import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import scipy.stats as stats
import scipy.special as sc
from scipy.integrate import quad
import math
import arviz as az
import warnings
"ignore", category=UserWarning) warnings.filterwarnings(
36 Distribuzioni di v.c. continue
Prerequisiti
Concetti e Competenze Chiave
Preparazione del Notebook
int = sum(map(ord, "cont_rv_distr"))
seed: = np.random.default_rng(seed=seed)
rng: np.random.Generator ="colorblind")
sns.set_theme(palette"arviz-darkgrid")
az.style.use(%config InlineBackend.figure_format = "retina"
Introduzione
Analogamente a quanto avviene per le variabili casuali discrete, anche per le variabili casuali continue possiamo rappresentare la variabilità all’interno di una popolazione attraverso un modello statistico, ma in questo caso utilizziamo le densità di probabilità – si veda il Capitolo 34. Mentre le distribuzioni di probabilità discrete si applicano a fenomeni con un numero finito o numerabile di esiti, le densità di probabilità sono fondamentali per descrivere variabili che possono assumere un continuum di valori.
La funzione di densità di probabilità \(f(x)\) associata a una variabile casuale continua \(X\) rappresenta la distribuzione della probabilità all’interno della popolazione. Questa funzione non fornisce la probabilità esatta di un singolo valore, ma piuttosto la probabilità di osservare valori di \(X\) all’interno di un intervallo specifico. Così come per le distribuzioni discrete, anche le densità di probabilità costituiscono un modello della popolazione, una rappresentazione matematica che ci consente di fare previsioni e di comprendere meglio i fenomeni aleatori continui.
Iniziamo con la distribuzione continua uniforme.
36.1 Distribuzione uniforme
La distribuzione uniforme è la più sempilce funzione di densità di probabilità. Consideriamo nuovamente l’esperimento con lo spinner che abbiamo introdotto nel Capitolo 34. Simuliamo 20 valori che potrebbero essere ottenuti facendo ruotare lo spinner e li rappresentiamo con un istogramma.
= rng.uniform(low=0, high=360, size=20)
y print(y)
[272.91158643 127.62934853 349.45128878 321.52360368 280.21805895
70.06993483 168.01956134 15.76935568 55.54421714 245.89762317
268.11437613 348.30350368 117.29712893 133.36549417 169.04009206
68.20968927 46.77174192 171.25377344 81.68736566 241.13303809]
plt.figure()= plt.hist(y, bins=36, density=True, alpha=0.5)
count, bins, ignored "Risultato dello spinner")
plt.xlabel("Frequenza relativa"); plt.ylabel(
Sebbene possiamo pensare che sia ugualmente probabile che si verifichi qualsiasi risultato tra 0 e 360, l’istogramma non sembra suggerire questo. Ma lo spinner è stato fatto ruotare solo 20 volte. Proviamo con 100,000 ripetizioni.
plt.figure()= plt.hist(rng.uniform(0, 360, 100000), bins=36, density=True, alpha=0.5)
count, bins, ignored "Risultato dello spinner")
plt.xlabel(= plt.ylabel("Frequenza relativa") _
In questo caso, anche se c’è una variazione nelle altezze delle barre (con \(\Delta\) = 10), la forma generale dell’istogramma sembra essere piuttosto piatta, ovvero uniforme, nell’intero intervallo dei valori possibili di \(X\), ovvero \(0 <= X <= 360\). Se potessimo ottenere un numero enorme di risultati dello spinner, il profilo dell’istogramma assumerebbe la forma della funzione di densità uniforme mostratra nella figura seguente.
plt.figure()= np.linspace(0, 360, 100)
x 0, 360), lw=2, label="uniform pdf")
plt.plot(x, stats.uniform.pdf(x, "x")
plt.xlabel("p(x)"); plt.ylabel(
Quando la variabile casuale \(X\) è continua, come nel caso del risultato della rotazione dello spinner, allora per rappresentare le probabilità usiamo una curva chiamata funzione di densità di probabilità. Poiché la scala dello spinner va da 0 a 360, sappiamo che tutti i risultati possibili devono cadere in questo intervallo, quindi la probabilità che \(X\) assuma un valore nell’intervallo [0, 360] è 1.0. Questa probabilità è rappresentata dall’area totale sotto la funzione di densità della figura precedente tra 0 e 360. Poiché l’area di questo rettangolo è data dall’altezza per la base e la base è uguale a 360, l’altezza di questa curva di densità deve essere 1/360 = 0.00278. L’ordinata della funzione di densità (qui 0.00278 nell’intervallo [0, 360] e 0 altrove) è chiamata densità.
Le probabilità corrispondono alle aree sottese alla curva di densità nell’intervallo di valori \(X\) specificato. Per esempio, nell’esperimento dello spinner possiamo chiederci quale sia la probabilità di ottenere un numero compreso tra 150 e 250, ovvero \(P(150 < X < 250)\). Per trovare la risposta dobbiamo calcolare l’area di un rettangolo. La base è 250 - 150 = 100. L’altezza è 0.00278. Dunque, la probabilità è
100*1/360
0.2777777777777778
Per svolgere questo calcolo i software utilizzano la funzione di ripartizione, \(P(X < x)\). Per trovare l’area in un intervallo è necessario sottrarre due aree. Nel caso presente abbiamo \(P(x < 250) - P(x < 150)\), ovvero:
250, 0, 360) - stats.uniform.cdf(150, 0, 360) stats.uniform.cdf(
0.27777777777777773
La probabilità cercata è rappresentata dal rettangolo indicato nella figura seguente.
plt.figure()= np.linspace(0, 360, 1000)
x = stats.uniform.pdf(x, 0, 360)
fx
plt.plot(x, fx)=(x >= 150) & (x <= 250), color="0.75"); plt.fill_between(x, fx, where
In maniera più formale possiamo dire che la distribuzione continua uniforme è una distribuzione di probabilità continua che assegna lo stesso grado di fiducia a tutti i possibili valori di una variabile definita in un certo intervallo \(S=[a,b]\subset {\mathbb {R}}\). La distribuzione continua uniforme viene indicata con \({\mathcal {U}}(a,b)={\mathcal {U}}([a,b])\). Come intervallo \([a,b]\) viene spesso preso l’intervallo unitario \(I=[0,1]\).
La densità di probabilità di una variabile casuale continua uniforme \({\mathcal {U}}(a,b)\) è
\[ f(x)={\frac {1}{b-a}} \quad \text{su}\; [a, b]. \]
Il suo valore attesto è
\[ \displaystyle E(X)={\frac {1}{2}}(b+a). \]
La sua varianza è
\[ V(X)={\frac {1}{12}}(b-a)^{2}. \]
In Python è possibile manipolare la distribuzione uniforme mediante la funzione uniform
del modulo scipy.stats
. Di default, la funzione scipy.stats.uniform()
è un’istanziazione di \({\mathcal{U}}(0,1)\). Se utilizziamo la funzione pdf()
(probability density function) otteniamo l’ordinata della funzione di densità \({\mathcal{U}}(0,1)\) in corrispondenza dei valori \(x\) passati in input. Per esempio, esaminiamo la funzione di densità \({\mathcal{U}}(0,1)\) in corrispondenza di 0.5, 0.8 e 1.2. Per i primi due valori ci aspettiamo di ottenere 1; in corrispondenza di 1.2 ci aspettiamo di ottenere 0, poiché questo valore è al di fuori dell’intervallo \([ 0, 1]\).
0.5, 0.8, 1.2]) stats.uniform.pdf([
array([1., 1., 0.])
Con la funzione cdf()
(cumulative density function) otteniamo la funzione di ripartizione. Per esempio, per \({\mathcal{U}}(0,1)\) in corrispondenza dei punti 0.5 e 0.8 otteniamo
0.5, 0.8]) stats.uniform.cdf([
array([0.5, 0.8])
Usando la funzione di ripartizione è possibile calcolare la probabilità che la variabile casuale continua assuma un valore nell’intervallo specificato. Per esempio, per \({\mathcal{U}}(0,1)\) troviamo \(P(0.5 < x < 0.8)\)
0.8) - stats.uniform.cdf(0.5) stats.uniform.cdf(
0.30000000000000004
I quantili di una funzione di densità (ovvero, il valore della variabile casuale \(X\) in corrispondenza del valore della funzione di ripartizione fornito in input) si ottengono con la funzione ppf()
(probability point function). Per esempio, troviamo i quantili di ordine 0.5 e 0.8 di una \({\mathcal {U}}(0,1)\).
0.5, 0.8]) stats.uniform.ppf([
array([0.5, 0.8])
Infine, è possibile simulare dei valori casuali della distribuzione \({\mathcal{U}}(0,1)\) usando la funzione stats.uniform()
. Se vogliamo 5 valori da una \({\mathcal{U}}(0,1)\), scriviamo:
0, 1, 5) rng.uniform(
array([0.51383373, 0.32883263, 0.16402071, 0.13786892, 0.15572435])
Verifico il valore atteso di 100,000 realizzazioni di \({\mathcal {U}}(0,1)\).
0, 1, 100000).mean() rng.uniform(
0.4993283752250098
Verifico la varianza di 100,000 realizzazioni di \({\mathcal {U}}(0,1)\).
0, 1, 100000).var() rng.uniform(
0.0832097723457758
1 / 12
0.08333333333333333
36.2 Distribuzione esponenziale
Un’altra distribuzione di densità molto semplice è la distribuzione esponenziale. La distribuzione esponenziale viene spesso utilizzata per modellare il tempo trascorso prima che un evento si verifichi (tempo di attesa).
La distribuzione esponenziale è l’unica distribuzione di probabilità continua che possiede la proprietà di assenza di memoria. Ad esempio, ipotizziamo che il tempo necessario affinché un bicchiere da vino si rompa dopo il primo utilizzo segua una distribuzione esponenziale. Supponiamo inoltre che ci sia un bicchiere da vino che non si è rotto dopo 3 anni dal primo utilizzo. L’assenza di memoria significa che la probabilità che questo bicchiere da vino non si rompa nel prossimo anno è la stessa della probabilità che un altro bicchiere da vino nuovo non si rompa nel primo anno di utilizzo.
Chiamiamo \(X\) il tempo di attesa. Sia \(\mu = \mathbb{E}(X)\) il tempo di attesa medio. La funzione di densità esponenziale è
\[ f(x) = \lambda {\rm e}^{-\lambda x}, \quad \text{con} \; \lambda = 1/\mu,\, \lambda > 0,\, x > 0, \tag{36.1}\]
ovvero
\[ f(x) = \frac{1}{\mu} {\rm e}^{-x/\mu}. \]
La media di una distribuzione esponenziale è
\[ E(X) = \frac{1}{\lambda}. \]
La varianza di una distribuzione esponenziale è
\[ V(X) = \mu = \frac{1}{\lambda^2}. \]
La deviazione standard è dunque uguale alla media:
\[ \sigma_X = \frac{1}{\lambda} = \mu. \]
Ad esempio, il tempo di attesa della pubblicazione del voto di un esame scritto segue una distribuzione esponenziale. Supponiamo che, in questo Corso di Laurea, il tempo di attesa medio per conoscere il risultato di un esame scritto sia di 4 giorni. La funzione esponenziale diventa
\[ f(x) = \frac{1}{4} \exp^{-x/4}. \]
Per disegnare un grafico della funzione esponenziale possiamo usare la funzione stats.expon()
. La densità è data da pdf(x, loc, scale)
, laddove il parametro loc
è 0 e scale
è la deviazione standard. Nel caso presente abbiamo:
= np.arange(0, 20, 0.01)
x = 4
mu = 1 / mu
lam = 1 / lam
stdev = stats.expon.pdf(x, loc=0, scale=stdev)
pdf
plt.figure()
plt.plot(x, pdf)"x")
plt.xlabel("f(x)"); plt.ylabel(
Chiediamoci, ad esempio, quale sia la probabilità di dovere aspettare non più di un giorno e mezzo per conoscere il voto dell’esame. La risposta a questa domanda è data dalla funzione di ripartizione in corrispondenza di 1.5, ovvero \(F(1.5) = P(X \leq 1.5)\).
= stats.expon.pdf(x, loc=0, scale=stdev)
fx
plt.figure()
plt.plot(x, fx)=(x >= 0) & (x <= 1.5), color="0.75"); plt.fill_between(x, fx, where
Possiamo trovare la risposta usando la funzione cdf()
:
1.5, loc=0, scale=stdev) stats.expon.cdf(
0.3127107212090278
Chiediamoci, ad esempio quale sia la probabilità di conoscere il voto in un tempo compreso tra 1 e 6 giorni. Dobbiamo trovare l’area sottesa alla funzione di densità nell’intervallo [1, 6]. Usando la fuzione di ripartizione, calcoliamo \(F(6) - F(1) = P(X <= 6) - P(X <= 1)\).
= stats.expon.pdf(x, loc=0, scale=stdev)
fx
plt.figure()
plt.plot(x, fx)=(x >= 1) & (x <= 6), color="0.75"); plt.fill_between(x, fx, where
6, loc=0, scale=stdev) - stats.expon.cdf(1, loc=0, scale=stdev) stats.expon.cdf(
0.5556706229229751
Troviamo la probabilità di dovere aspettare almeno 5 giorni e mezzo.
= stats.expon.pdf(x, loc=0, scale=stdev)
fx
plt.figure()
plt.plot(x, fx)=(x >= 5.5) & (x <= 21), color="0.75"); plt.fill_between(x, fx, where
La probabilità cercata è data dalla probabilità dell’evento complementare di quello fornito dalla funzione di ripartizione.
1 - stats.expon.cdf(5.5, loc=0, scale=stdev)
0.25283959580474646
5.5, loc=0, scale=stdev) stats.expon.sf(
0.25283959580474646
Se la media del tempo di attesa nel Corso di Laurea fosse di 4 giorni, allora circa una volta su 4 lo studente dovrà aspettare almeno 5.5 giorni per conoscere il voto dello scritto.
La figura seguente mostra un istogramma di 1000000 valori casuali estratti dalla distribuzione esponenziale di parametro \(\lambda = 1/4\). All’istogramma è sovrapposta la funzione di densità.
= rng.exponential(stdev, 100000)
samps
plt.figure()= plt.hist(samps, bins=100, density=True, alpha=0.5)
count, bins, ignored
plt.plot(x, fx)0, 20])
plt.xlim(["Frequenza relativa")
plt.ylabel("Tempo di attesa"); plt.xlabel(
36.3 Distribuzione Gaussiana
La più importante distribuzione di densità è la Gaussiana. Non c’è un’unica distribuzione gaussiana (o Normale): la distribuzione gaussiana è una famiglia di distribuzioni. Tali distribuzioni sono dette “gaussiane” in onore di Carl Friedrich Gauss (uno dei più grandi matematici della storia il quale, tra le altre cose, scoprì l’utilità di tale funzione di densità per descrivere gli errori di misurazione). Adolphe Quetelet, il padre delle scienze sociali quantitative, fu il primo ad applicare tale funzione di densità alle misurazioni dell’uomo. Karl Pearson usò per primo il termine “distribuzione normale” anche se ammise che questa espressione “ha lo svantaggio di indurre le persone a credere che le altre distribuzioni, in un senso o nell’altro, non siano normali.”
36.3.1 Limite delle distribuzioni binomiali
Iniziamo con un un breve excursus storico. Nel 1733, Abraham de Moivre notò che, aumentando il numero di prove di una distribuzione binomiale, la distribuzione risultante diventava quasi simmetrica e a forma campanulare. Per esempio, con 10 prove e una probabilità di successo di 0.9, la distribuzione è chiaramente asimmetrica.
= 10
n = 0.9
p = list(range(n + 1))
r_values = [stats.binom.pmf(r, n, p) for r in r_values]
dist
plt.figure(); plt.bar(r_values, dist)
Quando il numero di prove N viene aumentato di un fattore di 100 a N = 1000, mantenendo costante la probabilità di successo del 90%, si osserva che la distribuzione assume una forma campanulare quasi simmetrica. Questa osservazione porta a una scoperta di de Moivre: quando N diventa grande, la funzione gaussiana, nonostante rappresenti la densità di variabili casuali continue, offre una buona approssimazione alla funzione di massa di probabilità binomiale.
= 1000
n = 0.9
p = list(range(n + 1))
r_values = [stats.binom.pmf(r, n, p) for r in r_values]
dist
plt.figure()
plt.bar(r_values, dist)850, 950); plt.xlim(
La distribuzione Normale fu scoperta da Gauss nel 1809. Il Paragrafo successivo illustra come si possa giungere alla Normale mediante una simulazione.
36.4 La Normale prodotta con una simulazione
Il libro “Rethinking Statistics” di McElreath (2020) spiega come sia possibile ottenere la distribuzione normale attraverso una simulazione. Immaginiamo di avere duemila persone che si trovano allineate su una linea di partenza. Quando viene dato il segnale di partenza, ogni persona lancia una moneta e compie un passo avanti o indietro a seconda del risultato del lancio. La lunghezza di ogni passo può variare da 0 a 1 metro. Ogni persona lancia la moneta 16 volte e quindi compie 16 passi.
I risultati ottenuti da una serie di passeggiate casuali si traducono in varie distanze dall’origine, che è il punto da cui si parte, contrassegnato come zero, dopo un numero specificato di passi. Queste distanze sono rappresentate numericamente. Al termine di queste passeggiate, non è possibile determinare la posizione esatta di ogni individuo, ma è possibile descrivere accuratamente le caratteristiche della distribuzione delle 1000 distanze dall’origine.
Ad esempio, è possibile prevedere con precisione la frazione di individui che si sono mossi verso in avanti o indietro, o la proporzione di persone che si troveranno a una distanza specifica dal punto di partenza, come a 1.5 metri dall’origine. Queste previsioni sono fattibili perché la distribuzione delle distanze segue una distribuzione Normale.
Il codice presentato di seguito genera passeggiate casuali utilizzando un generatore di numeri casuali e ne traccia i percorsi risultanti. Il codice inizia inizializzando un oggetto generatore di numeri casuali con la funzione np.random.default_rng()
della libreria numpy
. Questo generatore sarà usato per produrre numeri casuali uniformemente distribuiti tra -1 e 1, simulando così il lancio di una moneta.
La variabile steps
specifica il numero di passi per ogni passeggiata casuale, mentre repetitions
indica il numero di passeggiate da generare. La variabile show_steps
è un elenco di numeri di passi in cui il codice traccerà linee verticali sul grafico.
Successivamente, il codice crea un array bidimensionale di NumPy chiamato x
con righe pari a steps + 1
e colonne pari a repetitions
. La prima colonna di questo array è riempita di zeri, e le colonne rimanenti sono riempite con la somma cumulativa dei passi, ottenuti da numeri casuali uniformemente distribuiti generati dal generatore di numeri casuali. Questo array verrà utilizzato per memorizzare le posizioni della passeggiata casuale ad ogni passo.
Il codice poi prepara una figura per tracciare tutte le passeggiate casuali. Il codice traccia anche la prima passeggiata casuale in nero.
# Parametri della simulazione
= 16 # Numero di passi per passeggiata
numero_passi = 1000 # Numero di passeggiate da generare
ripetizioni = [4, 8, 16] # Punti da evidenziare sul grafico
punti_da_evidenziare
# Inizializza l'array per registrare le passeggiate casuali
= np.zeros((numero_passi + 1, ripetizioni))
x
# Genera le passeggiate casuali
for i in range(ripetizioni):
= rng.uniform(-1, 1, numero_passi) # Genera passi casuali
passi 1:, i] = np.cumsum(passi) # Calcola la posizione cumulativa
x[
# Prepara il grafico
= plt.subplots()
fig, ax ="blue", alpha=0.05) # Disegna tutte le passeggiate
plt.plot(x, color0], color="black") # Evidenzia la prima passeggiata
plt.plot(x[:,
# Evidenzia i punti specifici
for punto in punti_da_evidenziare:
="--", color="black", alpha=0.5)
plt.axvline(punto, linestyle
# Imposta etichette e aspetti del grafico
"Numero di passi")
plt.xlabel("Distanza dall'origine")
plt.ylabel(
ax.set_xticks(punti_da_evidenziare)0, numero_passi + 0.1)
plt.xlim(
# Mostra il grafico
plt.show()
Il grafico riportato qui sotto visualizza la distribuzione dei passi a partire dalla linea mediana dopo 4, 8 e 16 lanci di moneta/passi. Quello che si nota è che, man mano che procediamo nel numero di passi, le densità iniziano a somigliare alla curva a campana associata alle distribuzioni Gaussiane.
# Crea una figura con 3 subplots in orizzontale, condividendo l'asse X
= plt.subplots(1, 3, figsize=(9, 3), sharex=True)
fig, axs
# Itera sui punti da evidenziare e sugli assi corrispondenti
for step, ax in zip(punti_da_evidenziare, axs):
# Estrae le posizioni al passo specificato per tutte le ripetizioni
= x[step, :]
posizioni_al_passo
=0.01, ax=ax)
az.plot_kde(posizioni_al_passo, bw
f"{step} passi")
ax.set_title("Densità")
ax.set_ylabel("Posizioni")
ax.set_xlabel(-6, 6)
ax.set_xlim(-6, -3, 0, 3, 6])
ax.set_xticks([
plt.tight_layout() plt.show()
La chiarezza dell’informazione presentata nei grafici precedenti può essere migliorata utilizzando un KDE plot.
# Genera la distribuzione uniforme e calcola la somma come prima
= rng.uniform(-1, 1, size=(16, 1000)).sum(0)
pos
# Calcola media e deviazione standard dei dati generati
= np.mean(pos), np.std(pos)
media, dev_std
# Spazio dei valori per la distribuzione normale
= np.linspace(np.min(pos), np.max(pos), 1000)
valori
# Calcola la distribuzione normale con la stessa media e deviazione standard
= stats.norm.pdf(valori, media, dev_std)
distribuzione_normale
# Disegna la stima della densità kernel dei dati
='Distribuzione KDE')
az.plot_kde(pos, label
# Sovrappone la distribuzione normale
='Distribuzione Normale', color = "C1", linestyle='--')
plt.plot(valori, distribuzione_normale, label
"Posizione")
plt.xlabel("Densità")
plt.ylabel(= plt.legend() _
Questa simulazione in luce un principio fondamentale della teoria delle probabilità: ogni processo che coinvolge la somma di una sequenza di valori casuali, tutti estratti dalla stessa distribuzione, inevitabilmente tende verso una distribuzione normale, comunemente conosciuta come curva gaussiana. Questa tendenza si verifica indipendentemente dalla configurazione iniziale della distribuzione di partenza, che può essere uniforme, come nell’esempio menzionato, o di qualsiasi altro tipo. La forma specifica della distribuzione iniziale influisce sulla velocità con cui si verifica questa convergenza verso il comportamento gaussiano, con variazioni significative nella velocità di convergenza: alcuni processi possono manifestare una convergenza lenta, mentre altri possono convergere estremamente rapidamente. Un esempio emblematico di questo fenomeno è rappresentato dal dispositivo conosciuto come Galton box, il quale offre una rappresentazione visiva e fisica di come la somma di valori casuali generi una distribuzione normale.
Un modo per razionalizzare la distribuzione Gaussiana è quello di pensare alle medie. Qualunque sia il valore medio della distribuzione di origine, ogni campione da essa può essere considerato una fluttuazione rispetto a quel valore medio. Tuttavia, quando sommiamo queste fluttuazioni insieme, esse si annullano a vicenda. E, facendo ciò, queste fluttuazioni convergono eventualmente alla media delle osservazioni collettive. Non importa quale sia la forma della distribuzione sottostante. A seconda della forma, le somme cumulative convergeranno inevitabilmente sulla media, alcune distribuzioni più lentamente di altre.
Dal punto di vista formale, possiamo definire una variabile casuale continua \(Y\) come avente una distribuzione normale se la sua densità di probabilità è distribuita secondo la seguente equazione
\[ f(y; \mu, \sigma) = {1 \over {\sigma\sqrt{2\pi} }} \exp \left\{-\frac{(y - \mu)^2}{2 \sigma^2} \right\}, \tag{36.2}\]
dove \(\mu \in \mathbb{R}\) e \(\sigma > 0\) sono i parametri della distribuzione.
La densità normale è unimodale e simmetrica con una caratteristica forma a campana e con il punto di massima densità in corrispondenza di \(\mu\).
Il significato dei parametri \(\mu\) e \(\sigma\) che appaiono nell’eq. {eq}eq-normal-formula
viene chiarito dalla dimostrazione che
\[ \mathbb{E}(Y) = \mu, \qquad \mathbb{V}(Y) = \sigma^2. \]
La rappresentazione grafica di quattro densità Normali con medie -1, -0.5, 0, 1 e con deviazioni standard 0.25, 0.5, 1 e 2 è fornita nella figura seguente.
= np.arange(-5, 6, 0.001)
x
= [-1.0, -0.5, 0.0, 1.0]
mus = [0.25, 0.5, 1, 2]
sigmas
plt.figure()
for mu, sigma in zip(mus, sigmas):
= stats.norm.pdf(x, mu, sigma)
pdf =r"$\mu$ = {}, $\sigma$ = {}".format(mu, sigma))
plt.plot(x, pdf, label"x")
plt.xlabel("f(x)")
plt.ylabel(=1); plt.legend(loc
36.4.1 Concentrazione
È istruttivo osservare il grado di concentrazione della distribuzione Normale attorno alla media:
\[ \begin{align} P(\mu - \sigma < Y < \mu + \sigma) &= P (-1 < Z < 1) \simeq 0.683, \notag\\ P(\mu - 2\sigma < Y < \mu + 2\sigma) &= P (-2 < Z < 2) \simeq 0.956, \notag\\ P(\mu - 3\sigma < Y < \mu + 3\sigma) &= P (-3 < Z < 3) \simeq 0.997. \notag \end{align} \]
Si noti come un dato la cui distanza dalla media è superiore a 3 volte la deviazione standard presenti un carattere di eccezionalità perché meno del 0.3% dei dati della distribuzione Normale presentano questa caratteristica.
Per indicare la distribuzione Normale si usa la notazione \(\mathcal{N}(\mu, \sigma)\).
36.4.2 Funzione di ripartizione
Il valore della funzione di ripartizione di \(Y\) nel punto \(y\) è l’area sottesa alla curva di densità \(f(y)\) nella semiretta \((-\infty, y]\). Non esiste alcuna funzione elementare per la funzione di ripartizione
\[ F(y) = \int_{-\infty}^y {1 \over {\sigma\sqrt{2\pi} }} \exp \left\{-\frac{(y - \mu)^2}{2\sigma^2} \right\} dy, \] (eq-gaussian-rip-formula)
pertanto le probabilità \(P(Y < y)\) vengono calcolate mediante integrazione numerica approssimata. I valori della funzione di ripartizione di una variabile casuale Normale sono dunque forniti da un software.
Esaminiamo le funzioni per la densità Normale. Il metodo rng.normal(loc, scale, size)
produce size
valori casuali estratti dalla distribuzione Normale specificata. Per esempio, un singolo valore casuale dalla \(\mathcal{N}(\mu = 100, \sigma = 15)\) è:
=100, scale=15, size=1) rng.normal(loc
array([77.8271813])
Estraiamo ora 10 valori a caso dalla \(\mathcal{N}(100, 15)\):
= rng.normal(loc=100, scale=15, size=10)
qi print(qi)
[107.37134121 74.33288092 70.05953321 100.16099998 67.01041676
102.19573565 114.68076458 58.88627549 69.38274746 112.14401099]
Per trovare la probabilità che un’osservazione estratta a caso dalla \(\mathcal{N}(100, 15)\) abbia un valore minore o uguale a, diciamo, 115, troviamo il valore della funzione di ripartizione (o funzione cumulativa di densità) nel punto 115.
115, 100, 15) stats.norm.cdf(
0.8413447460685429
Questa è l’area sottesa alla funzione di densità nell’intervallo \([-\infty, 115]\), come indicato nella figura seguente.
= 100
mu = 15
sigma = np.linspace(mu - 3 * sigma, mu + 3 * sigma, 10000)
x = stats.norm.pdf(x, mu, sigma)
fx
plt.figure()
plt.plot(x, fx)= plt.fill_between(x, fx, where=x <= 115, color="0.75") _
Solo per fare un esempio, qui di seguito fornisco il codice Python per calcolare l’integrale che stiamo discutendo per mezzo della funzione quad
della libreria SciPy:
def gaussian(x, mu, sig):
return (
1.0 / (np.sqrt(2.0 * np.pi) * sig) * np.exp(-np.power((x - mu) / sig, 2.0) / 2)
)
= 100
mu = 15
sigma = quad(gaussian, -1000, 115, args=(mu, sigma))
result, error print("Il risultato è", result, "con errore", error)
Il risultato è 0.8413447460685429 con errore 4.0191197364560644e-10
Il risultato replica quello prodotto da .norm.cdf()
.
Per trovare la proporzione di persone nella popolazione che hanno un QI maggiore di 2 deviazioni standard dalla media consideriamo l’evento complementare:
1 - stats.norm.cdf(130, 100, 15)
0.02275013194817921
plt.figure()
plt.plot(x, fx)=x >= 130, color="0.75"); plt.fill_between(x, fx, where
In maniera equivalente, possiamo usare la Survival Function:
130, 100, 15) stats.norm.sf(
0.022750131948179198
La funzione ppf
restituisce il quantile della Normale. Ad esempio:
1 - 0.022750131948179195, 100, 15) stats.norm.ppf(
130.0
36.4.3 Distribuzione Normale standard
La distribuzione Normale di parametri \(\mu = 0\) e \(\sigma = 1\) viene detta distribuzione Normale standard. La famiglia Normale è l’insieme avente come elementi tutte le distribuzioni Normali con parametri \(\mu\) e \(\sigma\) diversi. Tutte le distribuzioni Normali si ottengono dalla Normale standard mediante una trasformazione lineare: se \(Y \sim \mathcal{N}(\mu_Y, \sigma_Y)\) allora
\[ X = a + b Y \sim \mathcal{N}(\mu_X = a+b \mu_Y, \sigma_X = \left|b\right|\sigma_Y). \]
L’area sottesa alla curva di densità di \(\mathcal{N}(\mu, \sigma)\) nella semiretta \((-\infty, y]\) è uguale all’area sottesa alla densità Normale standard nella semiretta \((-\infty, z]\), in cui \(z = (y -\mu_Y )/\sigma_Y\) è il punteggio standard di \(Y\). Per la simmetria della distribuzione, l’area sottesa nella semiretta \([1, \infty)\) è uguale all’area sottesa nella semiretta \((-\infty, 1]\) e quest’ultima coincide con \(F(-1)\). Analogamente, l’area sottesa nell’intervallo \([y_a, y_b]\), con \(y_a < y_b\), è pari a \(F(z_b) - F(z_a)\), dove \(z_a\) e \(z_b\) sono i punteggi standard di \(y_a\) e \(y_b\).
Si ha anche il problema inverso rispetto a quello del calcolo delle aree: dato un numero \(0 \leq p \leq 1\), il problema è quello di determinare un numero \(z \in \mathbb{R}\) tale che \(P(Z < z) = p\). Il valore \(z\) cercato è detto quantile di ordine \(p\) della Normale standard e può essere trovato mediante un software.
Supponiamo che l’altezza degli individui adulti segua la distribuzione Normale di media \(\mu = 1.7\) m e deviazione standard \(\sigma = 0.1\) m. Vogliamo sapere la proporzione di individui adulti con un’altezza compresa tra \(1.7\) e \(1.8\) m.
Il problema ci chiede di trovare l’area sottesa alla distribuzione \(\mathcal{N}(\mu = 1.7, \sigma = 0.1)\) nell’intervallo \([1.7, 1.8]\):
1.8, 1.7, 0.1) - stats.norm.cdf(1.7, 1.7, 0.1) stats.norm.cdf(
0.34134474606854315
= 1.7
mu = 0.1
sigma = np.linspace(mu - 3 * sigma, mu + 3 * sigma, 10000)
x = stats.norm.pdf(x, mu, sigma)
fx
plt.figure()
plt.plot(x, fx)=(x >= 1.7) & (x <= 1.8), color="0.75"); plt.fill_between(x, fx, where
In maniera equivalente, possiamo standardizzare i valori che delimitano l’intervallo considerato e utilizzare la funzione di ripartizione della normale standardizzata. I limiti inferiore e superiore dell’intervallo sono
\[ z_{\text{inf}} = \frac{1.7 - 1.7}{0.1} = 0, \quad z_{\text{sup}} = \frac{1.8 - 1.7}{0.1} = 1.0, \]
quindi otteniamo
1.0, 0, 1) - stats.norm.cdf(0, 0, 1) stats.norm.cdf(
0.3413447460685429
Il modo più semplice per risolvere questo problema resta comunque quello di rendersi conto che la probabilità richiesta non è altro che la metà dell’area sottesa dalle distribuzioni Normali nell’intervallo \([\mu - \sigma, \mu + \sigma]\), ovvero \(0.683/2\).
Consideriamo ora la visualizzazione della PDF, la CDF e l’inverso della CDF della distribuzione normale.
# Definisco i parametri della distribuzione
= 100
mu = 15
sigma
# Creo un range di valori su cui calcolare le funzioni
= np.linspace(mu - 3*sigma, mu + 3*sigma, 1000)
x
# Calcolo la PDF, CDF, e l'inverso della CDF
= stats.norm.pdf(x, mu, sigma)
pdf = stats.norm.cdf(x, mu, sigma)
cdf = stats.norm.ppf(np.linspace(0.01, 0.99, 100), mu, sigma) # Evitiamo 0 e 1 per l'inverso
ppf
# Creo i grafici in una sola riga
= plt.subplots(1, 3, figsize=(15, 5))
fig, axs
# Grafico della PDF
0].plot(x, pdf, label='PDF')
axs[0].set_title('PDF')
axs[0].set_xlabel('Valori')
axs[0].set_ylabel('Probabilità')
axs[0].legend()
axs[
# Grafico della CDF
1].plot(x, cdf, label='CDF', color='orange')
axs[1].set_title('CDF')
axs[1].set_xlabel('Valori')
axs[1].set_ylabel('Cumulativa')
axs[1].legend()
axs[
# Grafico dell'inverso della CDF
2].plot(np.linspace(0.01, 0.99, 100), ppf, label='Inverse CDF', color='green')
axs[2].set_title('Inverse CDF')
axs[2].set_xlabel('Probabilità')
axs[2].set_ylabel('Valori')
axs[2].legend()
axs[
plt.tight_layout() plt.show()
Dovrebbe essere chiaro dalla figura che queste sono tre diverse modalità di osservare la stessa informazione.
36.5 Distribuzione Chi-quadrato
Dalla Normale deriva la distribuzione \(\chi^2\). La distribuzione \(\chi^2_{~k}\) con \(k\) gradi di libertà descrive la variabile casuale
\[ Z_1^2 + Z_2^2 + \dots + Z_k^2, \]
dove \(Z_1, Z_2, \dots, Z_k\) sono variabili casuali i.i.d. che seguono la distribuzione Normale standard \(\mathcal{N}(0, 1)\). La variabile casuale chi-quadrato dipende dal parametro intero positivo \(\nu = k\) che ne identifica il numero di gradi di libertà. La densità di probabilità di \(\chi^2_{~\nu}\) è
\[ f(x) = C_{\nu} x^{\nu/2-1} \exp (-x/2), \qquad \text{se } x > 0, \]
dove \(C_{\nu}\) è una costante positiva.
La figura seguente mostra alcune distribuzioni Chi-quadrato variando il parametro \(\nu\).
= np.arange(0, 40, 0.1)
x
= [2, 4, 8, 16]
nus
plt.figure()for nu in nus:
= stats.chi2.pdf(x, nu)
pdf =r"$\nu$ = {}".format(nu))
plt.plot(x, pdf, label"x")
plt.xlabel("f(x)")
plt.ylabel(=1); plt.legend(loc
36.5.1 Proprietà
- La distribuzione di densità \(\chi^2_{~\nu}\) è asimmetrica.
- Il valore atteso di una variabile \(\chi^2_{~\nu}\) è uguale a \(\nu\).
- La varianza di una variabile \(\chi^2_{~\nu}\) è uguale a \(2\nu\).
- Per \(k \rightarrow \infty\), la \(\chi^2_{~\nu} \rightarrow \mathcal{N}\).
- Se \(X\) e \(Y\) sono due variabili casuali chi-quadrato indipendenti con \(\nu_1\) e \(\nu_2\) gradi di libertà, ne segue che \(X + Y \sim \chi^2_m\), con \(m = \nu_1 + \nu_2\). Tale principio si estende a qualunque numero finito di variabili casuali chi-quadrato indipendenti.
Per fare un esempio, consideriamo la v.c. \(\chi^2_5\).
# Set the degrees of freedom
= 5
df
# Create a chi-square distribution object
= stats.chi2(df)
chi2_dist
# Generate x values for the plot
= np.linspace(0, 20, 200)
x
# Calculate the probability density function (PDF) of the chi-square distribution for x values
= chi2_dist.pdf(x)
pdf
# Plot the PDF
plt.figure()
plt.plot(x, pdf)'Chi-Square Distribution (df=5)')
plt.title('x')
plt.xlabel('PDF'); plt.ylabel(
Generiamo 1000000 valori da questa distribuzione.
= rng.chisquare(5, 1000000)
x 0:20] x[
array([3.66284512, 2.96353593, 4.93609572, 4.67151242, 4.10927523,
4.16530706, 3.36823832, 9.92342755, 7.02541475, 3.23262943,
2.73771833, 3.01973299, 4.83304038, 3.16952063, 5.98040985,
6.26951139, 8.73351727, 7.28411818, 7.75225854, 5.77346535])
Calcoliamo la media di questi valori.
np.mean(x)
5.0050584059950385
Calcolo la varianza.
=0) np.var(x, ddof
10.013703149640937
36.6 Distribuzione \(t\) di Student
Dalle distribuzioni Normale e Chi-quadrato deriva un’altra distribuzione molto nota, la \(t\) di Student. Se \(Z \sim \mathcal{N}\) e \(W \sim \chi^2_{~\nu}\) sono due variabili casuali indipendenti, allora il rapporto
\[ T = \frac{Z}{\Big( \frac{W}{\nu}\Big)^{\frac{1}{2}}} \tag{36.3}\]
definisce la distribuzione \(t\) di Student con \(\nu\) gradi di libertà. Si usa scrivere \(T \sim t_{\nu}\). L’andamento della distribuzione \(t\) di Student è simile a quello della distribuzione Normale, ma ha una dispersione maggiore (ha le code più pesanti di una Normale, ovvero ha una varianza maggiore di 1).
La seguente mostra alcune distribuzioni \(t\) di Student variando il parametro \(\nu\).
= np.arange(-5, 5, 0.1)
x
= [1, 2, 5, 30]
nus
plt.figure()for nu in nus:
= stats.t.pdf(x, nu)
pdf =r"$\nu$ = {}".format(nu))
plt.plot(x, pdf, label0, 1), label="N(μ = 0, σ = 1)")
plt.plot(x, stats.norm.pdf(x, "x")
plt.xlabel("f(x)")
plt.ylabel(=1); plt.legend(loc
36.6.1 Proprietà
La variabile casuale \(t\) di Student soddisfa le seguenti proprietà:
- Per \(\nu \rightarrow \infty\), \(t_{\nu}\) tende alla normale standard \(\mathcal{N}(0, 1)\).
- La densità della \(t_{\nu}\) è una funzione simmetrica con valore atteso nullo.
- Per \(\nu > 2\), la varianza della \(t_{\nu}\) vale \(\nu/(\nu - 2)\); pertanto è sempre maggiore di 1 e tende a 1 per \(\nu \rightarrow \infty\).
Per esempio, calcoliamo il valore della funzione di ripartizione di ordine 0.025 nel caso di una \(t_{30}\).
0.025, 30) stats.t.ppf(
-2.042272456301238
Aumentiamo i gradi di libertà: \(\nu\) = 1000.
0.025, 1000) stats.t.ppf(
-1.9623390808264078
Questo valore è quasi identico a quello della Normale stanardizzata.
0.025, 0, 1) stats.norm.ppf(
-1.9599639845400545
La ragione per cui il quantile della distribuzione \(t\) con \(\nu=30\) è maggiore (in valore assoluto) del quantile omotetico della distribuzione Normale Standard è che la distribuzione \(t\) ha una varianza maggiore rispetto alla distribuzione Normale Standard.
36.7 Funzione Beta di Eulero
La funzione Beta di Eulero è una funzione matematica, non una densità di probabilità. La menzioniamo qui perché viene utilizzata nella densità di probabilità Beta. La funzione Beta di Eulero, comunemente indicata con il simbolo \(B(\alpha, \beta)\), si può scrivere in molti modi diversi; per i nostri scopi la presentiamo così:
\[ B(\alpha, \beta) = \frac{\Gamma(\alpha)\Gamma(\beta)}{\Gamma(\alpha + \beta)}\,, \tag{36.4}\]
dove \(\Gamma(x)\) è la funzione Gamma, ovvero il fattoriale discendente, cioè
\[ (x-1)(x-2)\ldots (x-n+1)\notag\,. \]
Per esempio, posti \(\alpha = 3\) e \(\beta = 9\), la funzione Beta di Eulero assume il valore
= 3
alpha = 9
beta sc.beta(alpha, beta)
0.00202020202020202
Si noti che abbiamo usato la funzione beta
della libreria scipy.special
. Lo stesso risultato si ottiene svolgendo i calcoli in maniera esplicita:
2) * (8 * 7 * 6 * 5 * 4 * 3 * 2)) / (11 * 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2) ((
0.00202020202020202
-1)*math.factorial(beta-1)) / math.factorial(alpha+beta-1) (math.factorial(alpha
0.00202020202020202
oppure usando la funzione gamma
di scipy.special
:
* sc.gamma(beta) / sc.gamma(alpha + beta) sc.gamma(alpha)
0.00202020202020202
36.8 Distribuzione Beta
La distribuzione di probabilità Beta, denotata comunemente come \(Beta(\alpha, \beta)\), è utilizzata per modellare fenomeni che sono espressi in percentuali o proporzioni. Un aspetto cruciale di questa distribuzione è la sua definizione esclusiva nell’intervallo \((0, 1)\). In pratica, ciò significa che essa considera valori compresi strettamente tra 0 e 1, escludendo sia lo 0 che l’1 come estremi.
36.8.1 Definizione Formale
Consideriamo una variabile casuale \(\theta\), la quale può assumere qualunque valore nell’intervallo aperto \((0, 1)\). Se diciamo che \(\theta\) segue una distribuzione Beta con parametri \(\alpha\) e \(\beta\) (indicato come \(\theta \sim \text{Beta}(\alpha, \beta)\)), intendiamo che la sua funzione di densità è descritta dalla seguente formula:
\[ \text{Beta}(\theta \mid \alpha, \beta) = \frac{1}{B(\alpha, \beta)}\theta^{\alpha-1} (1-\theta)^{\beta-1} = \frac{\Gamma(\alpha+ \beta)}{\Gamma(\alpha)\Gamma(\beta)}\theta^{\alpha-1} (1-\theta)^{\beta-1} \quad \text{per } \theta \in (0, 1)\,, \]
dove \(B(\alpha, \beta)\) è la funzione beta di Eulero, definita come \(\frac{\Gamma(\alpha) \Gamma(\beta)}{\Gamma(\alpha + \beta)}\).
36.8.2 I Parametri \(\alpha\) e \(\beta\)
I parametri \(\alpha\) e \(\beta\) giocano un ruolo cruciale nella distribuzione Beta, influenzando direttamente la sua forma e il suo comportamento. È essenziale che entrambi questi parametri siano positivi.
36.8.3 Intuizione e Collegamento con la Distribuzione Binomiale
La distribuzione Beta può essere meglio compresa quando la si osserva in relazione con la distribuzione binomiale. Mentre la distribuzione binomiale modella il numero di successi in una serie di prove, la distribuzione Beta si focalizza sulla probabilità di successo in queste prove.
Nel contesto della distribuzione binomiale, la probabilità di successo è un parametro fisso; nella distribuzione Beta, questa probabilità diventa una variabile aleatoria.
36.8.4 Interpretazione dei Parametri \(\alpha\) e \(\beta\)
I parametri \(\alpha\) e \(\beta\) possono essere interpretati come rappresentanti il numero di successi e insuccessi, rispettivamente. Questa interpretazione è analoga ai termini \(n\) e \(n-x\) nella distribuzione binomiale.
La scelta di \(\alpha\) e \(\beta\) dipende dall’aspettativa iniziale della probabilità di successo: - Se si presume un’alta probabilità di successo (ad esempio, 90%), si potrebbe scegliere \(\alpha = 90\) e \(\beta = 10\). - Al contrario, per una bassa aspettativa di successo, si potrebbe impostare \(\alpha = 10\) e \(\beta = 90\).
Un aumento di \(\alpha\) (successi) sposta la distribuzione verso destra, mentre un aumento di \(\beta\) (insuccessi) la sposta verso sinistra. Inoltre, se sia \(\alpha\) sia \(\beta\) aumentano, la distribuzione diventa più stretta, indicando una maggiore certezza.
Questa interpretazione consente di utilizzare la distribuzione Beta per esprimere le nostre credenze a priori riguardo a una sequenza di prove di Bernoulli, dove il rapporto tra successi e tentativi totali è dato da:
\[ \frac{\text{Numero di successi}}{\text{Numero di successi} + \text{Numero di insuccessi}} = \frac{\alpha}{\alpha + \beta}\notag\,. \]
Al variare di \(\alpha\) e \(\beta\) si ottengono molte distribuzioni di forma diversa; un’illustrazione è fornita dalla seguente GIF animata.
La figura seguente mostra la distribuzione \(Beta(x \mid \alpha, \beta)\) per \(\alpha\) = 0.5, 5.0, 1.0, 2.0, 2.0 e \(\beta\) = 5, 1.0, 3.0, 2.0, 5.0.
= np.linspace(0, 1, 200)
x = [0.5, 5.0, 1.0, 2.0, 2.0]
alphas = [0.5, 1.0, 3.0, 2.0, 5.0]
betas
plt.figure()for a, b in zip(alphas, betas):
= stats.beta.pdf(x, a, b)
pdf =r"$\alpha$ = {}, $\beta$ = {}".format(a, b))
plt.plot(x, pdf, label"x", fontsize=12)
plt.xlabel("f(x)", fontsize=12)
plt.ylabel(0, 4.5)
plt.ylim(=9); plt.legend(loc
36.8.5 Costante di normalizzazione
La relazione \(\frac{1}{B(\alpha, \beta)} = \frac{\Gamma(\alpha + \beta)}{\Gamma(\alpha)\Gamma(\beta)}\) definisce il reciproco della funzione Beta di Eulero, \(B(\alpha, \beta)\), come una costante di normalizzazione. Qui, \(\Gamma(\cdot)\) denota la funzione Gamma di Eulero. Questa costante di normalizzazione garantisce che
\[ \int_0^1 \theta^{\alpha-1} (1-\theta)^{\beta-1} d\theta = 1\,, \]
per \(\alpha, \beta > 0\). Questa integrazione conferma che \(\theta^{\alpha-1} (1-\theta)^{\beta-1}\), quando moltiplicata per la costante di normalizzazione, forma una densità di probabilità che si estende sull’intervallo \([0,1]\), con l’area sottesa dalla curva (l’integrale) uguale a 1.
Ad esempio, con \(\alpha = 3\) e \(\beta = 9\) abbiamo
def integrand(p, a, b):
return p ** (a - 1) * (1 - p) ** (b - 1)
= 3
a = 9
b = quad(integrand, 0, 1, args=(a, b))
result, error print(result)
0.00202020202020202
ovvero
= (math.gamma(a) * math.gamma(b)) / math.gamma(a + b)
result print(result)
0.00202020202020202
ovvero, usando la funzione beta di Eulero di scipy.special
sc.beta(a, b)
0.00202020202020202
36.8.6 Proprietà
Il valore atteso, la moda e la varianza di una densità di probabilità Beta sono dati dalle seguenti equazioni:
\[ \mathbb{E}(\theta) = \frac{\alpha}{\alpha+\beta}\,, \] (eq-beta-mean)
\[ Mo(\theta) = \frac{\alpha-1}{\alpha+\beta-2}\,, \] (eq-beta-mode)
\[ \mathbb{V}(\theta) = \frac{\alpha \beta}{(\alpha+\beta)^2 (\alpha+\beta+1)}\,. \] (eq-beta-var)
Usando le formule precedenti, possiamo definire la funzione beta_mean_mode_variance()
in Python per calcolare la media, la moda e la varianza di una distribuzione di probabilità Beta:
def beta_mean_mode_variance(alpha, beta):
= alpha / (alpha + beta)
mean = (alpha - 1) / (alpha + beta - 2)
mode = alpha * beta / ((alpha + beta) ** 2 * (alpha + beta + 1))
variance return mean, mode, variance
Per esempio
= 7
alpha = 3
beta = beta_mean_mode_variance(alpha, beta)
mean, mode, variance print(f"Mean: {mean}, Mode: {mode}, Variance: {variance}")
Mean: 0.7, Mode: 0.75, Variance: 0.019090909090909092
36.8.7 Distribuzione a priori coniugata
La distribuzione Beta rappresenta una prior coniugata ottimale per una gamma di distribuzioni legate a eventi di successo e fallimento, quali le distribuzioni Bernoulli, Binomiale, Binomiale Negativa e Geometrica, nell’ambito dell’inferenza Bayesiana. Questa caratteristica di prior coniugata rende il calcolo della distribuzione a posteriori particolarmente efficiente, poiché permette di bypassare onerose computazioni numeriche tipicamente associate all’inferenza Bayesiana.
Prendiamo, ad esempio, il caso in cui la distribuzione Beta, espressa come Beta(α, β), venga adottata come prior nel contesto di una distribuzione Binomiale. Questa scelta metodologica ci assicura che la distribuzione a posteriori manterrà la forma funzionale della distribuzione Beta. Ciò significa che, una volta raccolti i dati, l’aggiornamento a posteriori può essere eseguito semplicemente aggiungendo il numero di successi osservati (x) e il numero di fallimenti (n-x) ai parametri α e β del prior, rispettivamente. In tal modo, si ottiene una distribuzione a posteriori Beta con parametri aggiornati (α+x, β+n-x), senza la necessità di compiere la moltiplicazione tra la funzione di verosimiglianza e il prior.
È importante prestare attenzione all’uso del termine “Beta” in questo contesto, poiché assume significati differenti a seconda del riferimento: - La distribuzione Beta, che descrive una distribuzione di probabilità continua. - La funzione Beta, una funzione matematica speciale. - Il parametro β, che insieme ad α, definisce i parametri specifici della distribuzione Beta.
36.9 Distribuzione di Cauchy
La distribuzione di Cauchy è un caso speciale della distribuzione di \(t\) di Student con 1 grado di libertà. È definita da una densità di probabilità che corrisponde alla seguente funzione, dipendente da due parametri \(\alpha\) e \(\beta\),
\[ f(x \mid \alpha, \beta) = \frac{1}{\pi \beta \left[1 + \left( \frac{x - \alpha}{\beta} \right)^2\right]}. \tag{36.5}\]
Il grafico mostra alcune distribuzioni di Cauchy con \(\alpha\) = 0., 0., 0., -2.0 e \(\beta\) = .5, 1., 2., 1.0.
= np.linspace(-5, 5, 500)
x = [0.0, 0.0, 0.0, -2.0]
alphas = [0.5, 1.0, 2.0, 1.0]
betas
plt.figure()for a, b in zip(alphas, betas):
= stats.cauchy.pdf(x, loc=a, scale=b)
pdf =r"$\alpha$ = {}, $\beta$ = {}".format(a, b))
plt.plot(x, pdf, label"x", fontsize=12)
plt.xlabel("f(x)", fontsize=12)
plt.ylabel(=1); plt.legend(loc
36.10 Distribuzione Gamma
La distribuzione Gamma è ampiamente utilizzata nella statistica bayesiana come distribuzione a priori per parametri che sono strettamente positivi, come tassi o varianze. È particolarmente utile nella modellazione di variabili che rappresentano tempi di attesa o qualsiasi altra quantità che può assumere solo valori positivi. La densità di probabilità Gamma gioca un ruolo fondamentale nella modellazione del tempo di attesa per l’occorrenza di un certo numero di eventi indipendenti e rari, rendendola adatta per processi di Poisson generalizzati.
La distribuzione Gamma può essere vista come una generalizzazione della distribuzione esponenziale. Più precisamente, la distribuzione esponenziale è un caso speciale della distribuzione Gamma. Se sommiamo \(n\) variabili casuali indipendenti, ciascuna delle quali segue una distribuzione esponenziale con parametro \(\lambda\), il risultato segue una distribuzione Gamma con parametri \(n\) (numero di variabili sommate) e \(\lambda\) (tasso esponenziale). Questo si formalizza come:
\[ \text{Gamma}(n, \lambda) = \sum_{i=1}^n \text{Esponenziale}(\lambda). \]
In particolare, la distribuzione Gamma con parametro di forma 1, ovvero \(\text{Gamma}(1, \lambda)\), corrisponde esattamente a una distribuzione esponenziale con parametro \(\lambda\), cioè:
\[ \text{Gamma}(1, \lambda) = \text{Esponenziale}(\lambda). \]
La distribuzione Gamma è anche legata alla distribuzione normale in alcuni contesti. Sebbene non vi sia una relazione diretta e semplice tra una distribuzione Gamma e una normale, un caso specifico è quando il parametro di forma \(n\) è molto grande (cioè \(n \to \infty\)). In questo caso, la distribuzione Gamma può essere approssimata da una distribuzione normale tramite il teorema del limite centrale. Più precisamente, quando \(n\) è grande, una Gamma di parametri \(n\) e \(\lambda\) converge approssimativamente a una normale con media \(n/\lambda\) e varianza \(n/\lambda^2\).
36.11 Parametrizzazione
La distribuzione Gamma è caratterizzata da due parametri principali: \(\alpha\) e \(\beta\), noti rispettivamente come parametro di forma e parametro di tasso (o, alternativamente, si può usare \(\theta = \frac{1}{\beta}\), il parametro di scala).
36.11.1 Parametro di forma (\(\alpha\))
Il parametro di forma, \(\alpha\), determina la forma generale della curva della distribuzione:
- Se \(\alpha = 1\), la distribuzione Gamma si riduce a una distribuzione esponenziale, con la funzione di densità \(f(x) = \beta e^{-\beta x}\).
- Se \(\alpha > 1\), la distribuzione presenta un picco (modalità) attorno a \((\alpha - 1) \cdot \theta\), indicando una distribuzione più concentrata attorno a un valore medio.
- Se \(\alpha < 1\), la distribuzione è inclinata verso destra, con una coda lunga che si estende verso valori più bassi, mostrando una maggiore probabilità di valori piccoli di \(x\).
Il parametro \(\alpha\) può essere interpretato come il numero di “eventi” che ci si aspetta si verifichino prima di raggiungere un certo tempo di attesa, in contesti di modelli di Poisson generalizzati. Ad esempio, se la distribuzione Gamma modella il tempo di attesa per l’arrivo di un certo numero di eventi, \(\alpha\) indica il numero di eventi attesi.
Man mano che \(\alpha\) aumenta, la distribuzione si sposta verso destra e diventa più simmetrica. Per valori alti di \(\alpha\), la distribuzione Gamma si avvicina a una distribuzione normale.
36.11.2 Parametro di scala (\(\theta\)) o tasso (\(\beta\))
Il parametro \(\theta\) (o, alternativamente, \(\beta\)) controlla la scala temporale o la larghezza della distribuzione:
- Il parametro di scala \(\theta\) è inversamente proporzionale al parametro di tasso \(\beta\). Un valore più grande di \(\theta\) (o un valore più piccolo di \(\beta\)) produce una curva più piatta, indicando una maggiore variabilità (dispersione) nel tempo di attesa.
- Un valore più piccolo di \(\theta\) (o più grande di \(\beta\)) rende la curva più appuntita, indicando una minore variabilità.
Nel contesto del tempo di attesa, \(\theta\) agisce come un fattore di scala: un valore grande di \(\theta\) indica un periodo di tempo più lungo tra gli eventi, mentre un valore piccolo di \(\theta\) indica un periodo di tempo più breve.
36.11.3 Formula della funzione di densità di probabilità
La funzione di densità di probabilità (PDF) della distribuzione Gamma è data da:
\[ f(x \mid \alpha, \theta) = \frac{x^{\alpha-1} e^{-\frac{x}{\theta}}}{\theta^\alpha \Gamma(\alpha)}, \]
dove:
- \(x\) è la variabile casuale continua, con \(x > 0\),
- \(\alpha\) è il parametro di forma,
- \(\theta\) è il parametro di scala (alternativamente si può usare \(\beta = \frac{1}{\theta}\), il parametro di tasso),
- \(\Gamma(\alpha)\) è la funzione Gamma di Eulero, che generalizza il fattoriale per numeri reali e complessi. Per numeri interi \(n\), si ha \(\Gamma(n) = (n-1)!\), ma per argomenti generali \(\alpha\), la funzione Gamma è definita come:
\[ \Gamma(\alpha) = \int_0^\infty x^{\alpha-1} e^{-x} dx. \]
36.11.4 Media e varianza della distribuzione Gamma
Le espressioni per la media e la varianza della distribuzione Gamma in funzione di \(\alpha\) e \(\theta\) (o \(\beta\)) sono:
- Media (\(\mu\)):
\[ \mu = \alpha \cdot \theta = \frac{\alpha}{\beta}. \]
- Varianza (\(\sigma^2\)): \[ \sigma^2 = \alpha \cdot \theta^2 = \frac{\alpha}{\beta^2}. \]
In sintesi, il parametro di forma \(\alpha\) controlla la forma generale della distribuzione, mentre il parametro di scala \(\theta\) (o tasso \(\beta\)) regola la dispersione o variabilità. Questa parametrizzazione è largamente utilizzata, in particolare nella statistica bayesiana, dove la distribuzione Gamma può servire da distribuzione a priori per parametri positivi, come varianze o tassi di processi stocastici.
Per esempio, qui è riportata la distribuzione Gamma di parametri \(\alpha\) = 3 e \(\beta\) = 5/3.
= 3
alpha = 5/3
beta
= alpha / beta
mean print(mean)
1.7999999999999998
# Standard deviation = sqrt(alpha / beta^2)
= np.sqrt(alpha / beta**2)
sigma print(sigma)
1.0392304845413263
# Generazione di dati dalla distribuzione Gamma
= rng.gamma(shape=alpha, scale=1/beta, size=100000)
data
# Plot dell'istogramma dei dati generati
=30, density=True, alpha=0.6, color='g')
plt.hist(data, bins
# Plot della PDF (Probability Density Function) della distribuzione Gamma
= np.linspace(0, 10, 1000)
x =alpha, scale=1/beta), 'r-', lw=2, label='PDF')
plt.plot(x, stats.gamma.pdf(x, a
'Valore')
plt.xlabel('Densità di probabilità')
plt.ylabel('Distribuzione Gamma con alpha=3 e beta=5/3')
plt.title(
plt.legend() plt.show()
36.12 Distribuzione Esponenziale
La distribuzione esponenziale è una distribuzione di probabilità continua che descrive la “durata di vita” di un fenomeno che non invecchia (ossia la distribuzione esponenziale è priva di memoria).
La distribuzione esponenziale (o di Laplace) può anche essere ricavata come la distribuzione di probabilità di una variabile aleatoria definita come somma dei quadrati di due variabili aleatorie normali standardizzate (ossia con valore atteso zero e varianza unitaria); dunque è riconducibile a un caso particolare di distribuzione del chi-quadro, essendo, quest’ultima, la distribuzione di probabilità della variabile aleatoria costruita come la somma dei quadrati di \(n\) variabili aleatorie indipendenti normali e standardizzate.
La distribuzione esponenziale con parametro \({\displaystyle \lambda >0}\), ha funzione di densità di probabilità:
\[ {\displaystyle f(x;\lambda )={\begin{cases}\lambda e^{-\lambda x}&x>0,\\0&x\leq 0.\end{cases}}}. \]
Una variabile aleatoria con distribuzione esponenziale di parametro \({\displaystyle \lambda }\) ha
- valore atteso \({\displaystyle E[X]=1/\lambda }\),
- varianza \({\displaystyle {\text{Var}}(X)=1/\lambda ^{2}}.\)
Per fare un esempio, consideriamo il punteggio totale della scala psicologica di Kessler (K6), una misura standardizzata utilizzata dal NHIS per lo screening del disagio psicologico. La K6 include sei item relativi alla sintomatologia depressiva e ansiosa e valuta il disagio psicologico aspecifico degli ultimi 30 giorni. Gli item sono valutati su una scala Likert a 5 punti, che va da “mai” (=0) a “sempre” (=4). I punteggi totali variano da 0 a 24. Secondo Tomitaka et al. (2019), il punteggio totale della K6 segue una distribuzione esponenziale, con punteggi di cut-off per disagio psicologico moderato e grave corrispondenti a punteggi di 5 e 13, rispettivamente. Dallo studio emerge che il punteggio medio del totale della K6 nella popolazione americana è di 2.5. La corrispondente distribuzione esponenziale è rappresentata di seguito.
= 2.5
mean = np.linspace(0.001, 22, 100)
x
plt.figure()= stats.expon.pdf(x, scale=mean)
pdf =r"$\lambda$ = {}".format(lam))
plt.plot(x, pdf, label"x")
plt.xlabel("f(x)")
plt.ylabel( plt.show()
36.13 Commenti e considerazioni finali
La statistica bayesiana impiega le distribuzioni di probabilità come motore inferenziale per la stima dei parametri e dell’incertezza. Immaginiamo che le distribuzioni di probabilità siano piccoli pezzi di “Lego” con cui possiamo costruire qualsiasi cosa desideriamo. Questo principio si applica analogamente ai modelli statistici bayesiani. Possiamo costruire modelli che vanno dai più semplici ai più complessi, utilizzando le distribuzioni di probabilità e le loro interrelazioni.
Python, oltre al modulo stats
, offre la capacità di generare campioni casuali da varie distribuzioni di probabilità attraverso il generatore di numeri casuali disponibile in NumPy. Dopo aver importato NumPy con il comando:
import numpy as np
è possibile inizializzare il generatore di numeri casuali (rng
) con un valore di seme (seed) specifico, garantendo così la riproducibilità degli esperimenti:
= 42
RANDOM_SEED = np.random.default_rng(RANDOM_SEED) rng
A questo punto, si possono generare campioni da diverse distribuzioni di probabilità. Ad esempio, per generare un campione dalla distribuzione normale (gaussiana), si può procedere nel seguente modo:
= 0, 1 # Valori per media e deviazione standard
media, deviazione_standard = rng.normal(media, deviazione_standard, size=100) campione_normale
In questo esempio, size=100
indica che vogliamo generare un campione di 100 valori dalla distribuzione. Analogamente, si possono generare campioni da altre distribuzioni di probabilità specificando i relativi parametri:
Distribuzione Uniforme: Per generare valori da una distribuzione uniforme, definita in un intervallo da a
a b
, si può usare:
= 0, 10 # Estremi dell'intervallo
a, b = rng.uniform(a, b, size=100) # Aggiunta del parametro 'size' campione_uniforme
Distribuzione t di Student: Per ottenere valori dalla distribuzione t di Student, con un dato numero di gradi di libertà:
= 10 # Gradi di libertà
gradi_libertà = rng.standard_t(gradi_libertà, size=100) # Aggiunta del parametro 'size' campione_t
Distribuzione Beta: Per la distribuzione Beta, specificando i parametri alpha
e beta
:
= 2, 5 # Parametri alpha e beta
alpha, beta = rng.beta(alpha, beta, size=100) # Aggiunta del parametro 'size' campione_beta
Distribuzione Gamma: Infine, per generare un campione dalla distribuzione Gamma, con i parametri di forma e scala:
= 2, 1 # Parametri di forma e scala
forma, scala = rng.gamma(forma, scala, size=100) # Aggiunta del parametro 'size' campione_gamma
In tutti i casi, l’aggiunta del parametro size
consente di specificare la dimensione del campione desiderato.
Per analizzare le proprietà statistiche di diverse distribuzioni di probabilità, oltre alla generazione di campioni casuali, si utilizzano le funzioni di densità di probabilità (PDF), le funzioni di ripartizione cumulativa (CDF) e le funzioni quantili. Queste operazioni possono essere effettuate efficacemente utilizzando la libreria SciPy in Python.
Per determinare la funzione densità di probabilità (PDF), la quale rappresenta la probabilità relativa di osservare un valore all’interno di un intervallo continuo, il procedimento è il seguente. Per la distribuzione normale, ad esempio:
import numpy as np
from scipy.stats import norm, uniform, t, beta, gamma
= 0, 1
media, deviazione_standard = np.linspace(media - 4*deviazione_standard, media + 4*deviazione_standard, 100)
x = norm.pdf(x, loc=media, scale=deviazione_standard) pdf_normale
Simili operazioni possono essere effettuate per altre distribuzioni, come mostrato di seguito:
Distribuzione Uniforme:
= 0, 10
a, b = np.linspace(a, b, 100)
x = uniform.pdf(x, loc=a, scale=b-a) pdf_uniforme
Distribuzione t di Student:
= 10
gradi_libertà = np.linspace(-5, 5, 100)
x = t.pdf(x, df=gradi_libertà) pdf_t
Distribuzione Beta:
= 2, 5
alpha, beta_param = np.linspace(0, 1, 100)
x = beta.pdf(x, alpha, beta_param) pdf_beta
Distribuzione Gamma:
= 2, 1
forma, scala = np.linspace(0, 10, 100)
x = gamma.pdf(x, a=forma, scale=scala) pdf_gamma
Per determinare i quantili, ovvero i valori corrispondenti a specifiche probabilità cumulate nella funzione di distribuzione, si utilizza la funzione ppf
(Percent Point Function). Ad esempio, per la distribuzione normale:
= 0.5
probabilità = norm.ppf(probabilità, loc=media, scale=deviazione_standard) quantile_normale
E per le altre distribuzioni:
Distribuzione Uniforme:
= uniform.ppf(probabilità, loc=a, scale=b-a) quantile_uniforme
Distribuzione t di Student:
= t.ppf(probabilità, df=gradi_libertà) quantile_t
Distribuzione Beta:
= beta.ppf(probabilità, alpha, beta_param) quantile_beta
Distribuzione Gamma:
= gamma.ppf(probabilità, a=forma, scale=scala) quantile_gamma
Infine, per calcolare la probabilità cumulativa associata a un dato quantile (ovvero la probabilità che una variabile casuale sia minore o uguale a quel quantile), si utilizza la funzione cdf
(Cumulative Distribution Function). Questo permette di determinare la probabilità che si verifichi un evento entro un certo intervallo di valori per la distribuzione considerata. Ad esempio, per la distribuzione normale:
= 0
quantile = norm.cdf(quantile, loc=media, scale=deviazione_standard) probabilità_normale
E analogamente per le altre distribuzioni:
Distribuzione Uniforme:
= uniform.cdf(quantile, loc=a, scale=b-a) probabilità_uniforme
Distribuzione t di Student:
= t.cdf(quantile, df=gradi_libertà) probabilità_t
Distribuzione Beta:
= beta.cdf(quantile, alpha, beta_param) probabilità_beta
Distribuzione Gamma:
= gamma.cdf(quantile, a=forma, scale=scala) probabilità_gamma
36.14 Esercizi
Esercizio 36.1 Per ciascuna delle distribuzioni di massa di probabilità discusse, utilizza Python per:
- creare un grafico della funzione, scegliendo opportunamente i parametri;
- estrarre un campione di 1000 valori casuali dalla distribuzione e visualizzarlo con un istogramma;
- calcolare la media e la deviazione standard dei campioni e confrontarle con i valori teorici attesi;
- stimare l’intervallo centrale del 94% utilizzando i campioni simulati;
- determinare i quantili della distribuzione per gli ordini 0.05, 0.25, 0.75 e 0.95;
- scegliendo un valore della distribuzione pari alla media più una deviazione standard, calcolare la probabilità che la variabile aleatoria assuma un valore minore o uguale a questo valore.
Informazioni sull’Ambiente di Sviluppo
%load_ext watermark
%watermark -n -u -v -iv -w -m
Last updated: Thu Mar 21 2024
Python implementation: CPython
Python version : 3.11.8
IPython version : 8.22.2
Compiler : Clang 16.0.6
OS : Darwin
Release : 23.4.0
Machine : arm64
Processor : arm
CPU cores : 8
Architecture: 64bit
scipy : 1.12.0
matplotlib: 3.8.3
seaborn : 0.13.2
pandas : 2.2.1
numpy : 1.26.4
arviz : 0.17.1
Watermark: 2.4.3