✏️ Esercizi#
Probabilità condizionata#
Seguendo il metodo descritto nel libro «Think Bayes» di , per affrontare gli esercizi sulla probabilità condizionata, utilizzeremo una definizione di probabilità semplice e intuitiva, basata sul conteggio degli elementi di un insieme. In particolare, considereremo la probabilità come la frazione di elementi che soddisfano un certo criterio rispetto al totale degli elementi dell’insieme.
Immaginiamo di avere un insieme finito di elementi e di volere calcolare la probabilità di un evento all’interno di questo insieme. Per farlo, contiamo quanti elementi soddisfano il criterio dell’evento e dividiamo questo numero per il totale degli elementi dell’insieme. Questo approccio semplifica notevolmente il calcolo delle probabilità e rende più chiaro come funzionano i concetti di base.
Questa definizione intuitiva di probabilità ci aiuterà ad affrontare gli esercizi e applicare i concetti finora descritti a situazioni concrete e reali.
Preparazione del Notebook#
import numpy as np
import pandas as pd
import random
Esercizi di ricapitolazione con Python#
Considereremo qui il dataset penguins
inteso come un insieme finito sul quale definire vari eventi. Iniziamo ad importare i dati ed escludiamo i dati mancanti.
df = pd.read_csv("../data/penguins.csv")
df.dropna(inplace=True)
df.info()
<class 'pandas.core.frame.DataFrame'>
Index: 333 entries, 0 to 343
Data columns (total 8 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 species 333 non-null object
1 island 333 non-null object
2 bill_length_mm 333 non-null float64
3 bill_depth_mm 333 non-null float64
4 flipper_length_mm 333 non-null float64
5 body_mass_g 333 non-null float64
6 sex 333 non-null object
7 year 333 non-null int64
dtypes: float64(4), int64(1), object(3)
memory usage: 23.4+ KB
Ora, poniamoci la domanda se ciascun pinguino viva o meno sull’isola Dream. Per fare ciò, useremo una funzione che ci restituirà un oggetto Pandas Series
contenente valori booleani. In particolare, ogni valore sarà True
se il pinguino associato vive sull’isola Dream, altrimenti sarà False
. In questo modo, avremo un elenco di valori che ci indicheranno per ciascun pinguino se vive o meno sull’isola Dream, utilizzando la potenza di Pandas per effettuare rapidamente questo tipo di calcoli.
on_dream = df["island"] == "Dream"
on_dream.head()
0 False
1 False
2 False
4 False
5 False
Name: island, dtype: bool
Essendo che il valore True
corrisponde a 1 e il valore False
corrisponde a 0, possiamo utilizzare la funzione .sum()
per contare il numero di pinguini che vivono sull’isola Dream. In altre parole, sommando tutti i valori True nell’oggetto Pandas Series
ottenuto prima, otterremo il numero totale di pinguini che vivono sull’isola Dream nel nostro campione di dati. Con questa operazione scopriamo che ci sono 123 pinguini che sono stati osservati sull’isola Dream.
on_dream.sum()
123
Per ottenere la proporzione di pinguini che vivono sull’isola Dream, dobbiamo calcolare la frequenza assoluta dei pinguini sull’isola Dream e dividere questo valore per il numero totale di pinguini del nostro campione di dati. Possiamo calcolare questo valore utilizzando il metodo .mean()
applicato all’oggetto Pandas Series
contenente i valori booleani True
e False
, ottenuto in precedenza. Questo metodo calcola la media aritmetica di tutti i valori nella serie, dove il valore True
viene considerato come 1 e il valore False
come 0. In questo modo, il risultato finale ci darà la proporzione di pinguini che vivono sull’isola Dream rispetto al totale dei pinguini del nostro campione di dati.
on_dream.mean()
0.36936936936936937
Circa il 36.9% di tutti i pinguini del nostro campione di dati vivono sull’isola Dream. Questo significa che, se scegliamo un pinguino a caso da questo insieme, la probabilità che viva sull’isola Dream è del 36.9%, ovvero 0.369.
Per automatizzare il calcolo della probabilità, possiamo inserire il codice precedente in una funzione. Questa funzione prenderà in input un oggetto Pandas Series
contenente valori booleani, rappresentanti la presenza o meno di un certo attributo, e calcolerà la probabilità come la media aritmetica di tutti i valori nella serie, dove il valore True
viene considerato come 1 e il valore False
come 0. In questo modo, la funzione calcolerà la proporzione di True
rispetto al totale dei valori nella serie e restituirà il valore corrispondente alla probabilità cercata.
def prob(A):
"""Computes the probability of a proposition, A."""
return A.mean()
Verifichiamo.
prob(on_dream)
0.36936936936936937
Troviamo ora la probabilità che un pinguino sia di genere femminile.
female = df["sex"] == "female"
prob(female)
0.4954954954954955
Intersezione di eventi (congiunzione)#
L’intersezione tra due insiemi corrisponde all’operazione logica della congiunzione. In altre parole, date due proposizioni \(p\) e \(q\), la loro congiunzione è vera solo se entrambe sono vere. Se abbiamo due oggetti Pandas Series
contenenti valori booleani, possiamo utilizzare l’operatore &
per trovare la loro congiunzione. Questo operatore restituisce un nuovo oggetto Series
in cui i valori sono True
solo se entrambi i corrispondenti valori nelle due serie sono True
.
Definiamo ora un nuovo evento, chiamato «small», che identifica i pinguini la cui massa corporea è inferiore al quantile di ordine 1/3. In altre parole, consideriamo la distribuzione dei pesi dei pinguini nel nostro campione di dati e identifichiamo i pinguini il cui peso è inferiore al valore corrispondente al quantile di ordine 1/3 della distribuzione. Questo evento è rappresentato da un oggetto Pandas Series
booleano, in cui i valori sono True
se il peso del pinguino è inferiore al quantile di ordine 1/3 e False
altrimenti.
small = df["body_mass_g"] < df["body_mass_g"].quantile(1 / 3)
prob(small)
0.30930930930930933
Calcoliamo ora la probabilità che un pinguino sia di sesso femminile e, allo stesso tempo, appartenga alla categoria «small». In altre parole, vogliamo calcolare la probabilità che si verifichino contemporaneamente due eventi: che un pinguino sia di sesso femminile e che appartenga alla categoria «small».
prob(female & small)
0.2552552552552553
Come ci possiamo aspettare la probabilità dell’intersezione è minore della probabilità di «small» dato che non tutti i pinguini più piccoli sono di genere femminile.
Probabilità condizionata#
Come abbiamo visto in precedenza, la probabilità condizionata è la probabilità calcolata su un sottoinsieme di eventi. Per selezionare un sottoinsieme di dati in un oggetto Pandas, utilizziamo la notazione delle parentesi quadre. Nell’istruzione seguente, selezioniamo solo i pinguini di sesso femminile tra quelli che appartengono alla categoria «small», ovvero quelli il cui peso corporeo è inferiore al quantile di ordine 1/3.
selected = female[small]
prob(selected)
0.8252427184466019
È importante notare la sintassi utilizzata in questo passaggio: quando inseriamo un oggetto Series booleano (in questo caso chiamato small
) tra le parentesi quadre che seguono un oggetto Series (in questo caso chiamato female
), stiamo selezionando solo le righe di female
per le quali small
ha il valore True
.
Definiamo ora una funzione che prende in input due oggetti Series
booleani, proposition
e given
, e restituisce la probabilità condizionata di proposition
rispetto a given
. In altre parole, la funzione calcola la probabilità che proposition
si verifichi, sapendo che given
si è verificato.
def conditional(proposition, given):
return prob(proposition[given])
Calcoliamo ora la probabilità condizionata che un pinguino sia di sesso femminile, dato che appartiene alla categoria «small», ovvero il sottoinsieme di pinguini il cui peso corporeo è inferiore al quantile di ordine 1/3.
conditional(female, given=small)
0.8252427184466019
Troviamo ora la probabilità di essere di genere femminile, se consideriamo solo i pinguini sull’isola Dream, \(P(\text{female} \mid \text{Dream})\).
conditional(female, given=on_dream)
0.4959349593495935
Lo stesso risultato si ottiene applicando la definizione di probabilità condizionata.
prob(female & on_dream) / prob(on_dream)
0.49593495934959353
Calcoliamo la probabilità di estrarre a caso un pinguino di sesso femminile che vive sull’isola Dream.
prob(female & on_dream)
0.1831831831831832
Possiamo ottenere lo stesso risultato del calcolo precedente, ovvero la probabilità di estrarre a caso un pinguino di sesso femminile che vive sull’isola Dream, usando la probabilità condizionata per calcolare l’intersezione tra i due eventi.
conditional(female, given=on_dream) * prob(on_dream)
0.18318318318318316