Statistica bayesiana: come imparare dai dati, un passo alla volta

Abbiamo avuto modo di esaminare, nel corso dei precedenti articoli, l’inferenza statistica da una prospettiva precisa e coerente: formulare un’ipotesi, raccogliere dati, calcolare un p-value, costruire un intervallo di confidenza. Abbiamo condotto test delle ipotesi, confrontato varianti con l’A/B testing, e visto con il Teorema del Limite Centrale perché tutto questo funziona anche quando i dati non sono normali.

Questo approccio — che si chiama frequentista — ha una logica chiara: il parametro che vogliamo stimare è un valore fisso (anche se sconosciuto), e noi lo “inseguiamo” con i dati. Ma esiste un altro modo di pensare l’incertezza, un modo che permette di aggiornare le nostre convinzioni man mano che arrivano nuovi dati. Si chiama approccio bayesiano, e in questo articolo ne costruiamo le fondamenta.

Partiamo da un esempio concreto. Immaginiamo di aver appena lanciato una campagna di advertising e di non conoscere il vero tasso di click. Abbiamo un’opinione iniziale, basata sull’esperienza (“di solito i tassi di click stanno tra lo 0% e il 20%”), e poi arrivano i dati. L’approccio bayesiano ci permette di combinare la nostra opinione iniziale con i dati osservati per ottenere una stima aggiornata — e di ripetere questo processo ogni volta che arrivano nuove informazioni.


Due modi di pensare l’incertezza: frequentisti e bayesiani

Prima di entrare nella meccanica, chiariamo la differenza concettuale tra i due approcci. Non si tratta di una guerra: sono due modi diversi di rispondere alle stesse domande.

Frequentista Bayesiano
Il parametro È un valore fisso (sconosciuto) È una variabile casuale con una distribuzione
La probabilità Frequenza relativa di un evento su ripetizioni infinite Grado di credenza (belief) su un evento
L’incertezza Espressa tramite intervalli di confidenza Espressa tramite credible intervals
I dati precedenti Non entrano nel modello Si incorporano tramite il prior
Interpretazione dell’IC/CI “Se ripetessi 100 volte, 95 intervalli conterrebbero il parametro” “C’è il 95% di probabilità che il parametro sia in questo intervallo”

L’approccio frequentista, quello che abbiamo usato finora, tratta il parametro come un numero fisso e ragiona sulla distribuzione dei dati. L’approccio bayesiano capovolge la prospettiva: tratta i dati come fissi (li abbiamo osservati, non cambiano) e ragiona sulla distribuzione del parametro, cioè su quanto crediamo plausibili i vari valori che il parametro potrebbe assumere.

Il vantaggio pratico del bayesiano è che può incorporare conoscenza pregressa. Se sappiamo qualcosa sul parametro prima di raccogliere i dati (per esperienza, per studi precedenti, per buon senso), possiamo usare quella conoscenza. E poi aggiornarla.


Il Teorema di Bayes

Il cuore dell’approccio bayesiano è una formula che risale al 1763, al reverendo Thomas Bayes. Partiamo dalla probabilità condizionata: la probabilità di A dato B.

Sappiamo dalla teoria della probabilità che:

\(
P(A|B) = \frac{P(A \cap B)}{P(B)} \\
\)

e simmetricamente:

\(
P(B|A) = \frac{P(A \cap B)}{P(A)} \\
\)

Da queste due relazioni, ricavando \(P(A \cap B)\) dalla seconda e sostituendo nella prima, otteniamo il Teorema di Bayes:

\(
P(A|B) = \frac{P(B|A) \cdot P(A)}{P(B)} \\
\)

Fin qui è algebra. La magia avviene quando applichiamo questa formula al nostro problema: stimare un parametro \(\theta\) (ad esempio, il tasso di click) a partire dai dati osservati. Il teorema diventa:

\(
P(\theta | \text{dati}) = \frac{P(\text{dati} | \theta) \cdot P(\theta)}{P(\text{dati})} \\
\)

Ogni pezzo di questa formula ha un nome e un ruolo preciso:

  • Prior \(P(\theta)\): ciò che crediamo sul parametro prima di vedere i dati. È la nostra conoscenza pregressa, il nostro punto di partenza.
  • Likelihood \(P(\text{dati} | \theta)\): quanto i dati osservati sono compatibili con ciascun valore possibile di \(\theta\). È la stessa funzione di verosimiglianza che compare anche nell’approccio frequentista.
  • Posterior \(P(\theta | \text{dati})\): ciò che crediamo sul parametro dopo aver visto i dati. È il risultato finale, la nostra conoscenza aggiornata.
  • Evidence \(P(\text{dati})\): la probabilità marginale dei dati. In pratica, è una costante di normalizzazione che fa sì che il posterior sia una distribuzione di probabilità valida.

Poiché l’evidence è costante (non dipende da \(\theta\)), possiamo scrivere la relazione fondamentale:

\(
P(\theta | \text{dati}) \propto P(\text{dati} | \theta) \cdot P(\theta) \\
\)

In parole: il posterior è proporzionale al likelihood moltiplicato per il prior. Più dati raccogliamo, più il likelihood “domina” e il posterior si concentra attorno ai valori supportati dai dati. Ma con pochi dati, il prior conta — e conta molto.


Esempio numerico: il tasso di click di una campagna ads

Passiamo alla pratica. Abbiamo lanciato una campagna pubblicitaria: l’annuncio è stato mostrato 100 volte e ha ricevuto 13 click. Qual è il vero tasso di click?

Il prior: non sappiamo quasi nulla, ma per esperienza riteniamo che i tassi di click stiano tipicamente tra lo 0% e il 20%. Modelliamo questa incertezza con una distribuzione uniforme su [0, 0.20].

L’approccio: usiamo una simulazione. Generiamo molti valori plausibili dal prior, simuliamo i dati che ciascun valore produrrebbe, e teniamo solo quelli compatibili con ciò che abbiamo effettivamente osservato (13 click su 100). Ciò che rimane è il posterior.

set.seed(42)

n_samples <- 100000
n_ads_shown <- 100
n_clicks_observed <- 13

# 1. Generiamo campioni dal prior: uniforme tra 0 e 0.20
proportion_clicks <- runif(n_samples, min = 0.0, max = 0.20)

# 2. Per ogni valore di proporzione, simuliamo quanti click otterremmo
n_visitors <- rbinom(n_samples, size = n_ads_shown, prob = proportion_clicks)

# 3. Costruiamo il data frame con prior e dati simulati
prior <- data.frame(proportion_clicks, n_visitors)

# 4. Conditioning: teniamo solo i campioni compatibili con 13 click
posterior <- prior[prior$n_visitors == n_clicks_observed, ]

cat("Campioni nel prior:", nrow(prior), "\n")
cat("Campioni nel posterior:", nrow(posterior), "\n")
cat("Media del posterior:", round(mean(posterior$proportion_clicks) * 100, 1), "%\n")
cat("Mediana del posterior:", round(median(posterior$proportion_clicks) * 100, 1), "%\n")

Risultato: dei 100.000 campioni iniziali, circa 4.700 sopravvivono al conditioning (il numero esatto varia per via della simulazione). La media e la mediana del posterior sono circa il 13.4%: un valore molto vicino ai 13 click su 100 che abbiamo osservato.

Visualizziamo la trasformazione dal prior al posterior:

par(mfrow = c(1, 2))

# Prior
hist(prior$proportion_clicks, breaks = 30, probability = TRUE,
     main = "Prior\n(uniforme 0-20%)",
     col = "lightyellow", xlab = "Tasso di click",
     ylab = "Densità", xlim = c(0, 0.25))

# Posterior
hist(posterior$proportion_clicks, breaks = 30, probability = TRUE,
     main = "Posterior\n(dopo 13/100 click)",
     col = "lightblue", xlab = "Tasso di click",
     ylab = "Densità", xlim = c(0, 0.25))

La differenza è evidente. Il prior è una distribuzione piatta (uniforme): tutti i valori tra 0% e 20% sono considerati ugualmente plausibili. Il posterior, invece, si concentra attorno al 13%, con una forma a campana. I dati hanno "informato" la nostra incertezza.

Il credible interval al 95%:

ci_95 <- quantile(posterior$proportion_clicks, probs = c(0.025, 0.975))
cat("Credible interval al 95%:", round(ci_95[1] * 100, 1), "% -",
    round(ci_95[2] * 100, 1), "%\n")

Il credible interval al 95% è circa 7.7% - 19.1%. Questo significa esattamente ciò che sembra: c'è il 95% di probabilità che il vero tasso di click sia compreso tra il 7.7% e il 19.1%.

Confronto con l'IC frequentista:

prop_test <- prop.test(13, 100, correct = FALSE)
cat("IC frequentista al 95%:", round(prop_test$conf.int[1] * 100, 1), "% -",
    round(prop_test$conf.int[2] * 100, 1), "%\n")

L'IC frequentista al 95% è circa 7.8% - 21.0%. I numeri sono simili, ma l'interpretazione è diversa: l'IC frequentista ci dice che "se ripetessimo il campionamento 100 volte, 95 intervalli conterrebbero il vero parametro". Il credible interval bayesiano ci dice direttamente la probabilità che il parametro sia nell'intervallo. Quest'ultima è l'interpretazione che la maggior parte delle persone crede di dare all'intervallo di confidenza — ma che, nell'approccio frequentista, è tecnicamente scorretta.


L'aggiornamento sequenziale: il posterior di oggi è il prior di domani

Ecco il punto in cui l'approccio bayesiano rivela la sua eleganza. Supponiamo che la campagna continui: dopo altri giorni, abbiamo 150 nuove impression e 20 nuovi click. Come aggiorniamo la nostra stima?

Il principio è semplice: il posterior che abbiamo appena calcolato diventa il nuovo prior. Non dobbiamo ricominciare da zero; partiamo da dove eravamo rimasti.

# Il posterior precedente diventa il nuovo prior
prior_aggiornato <- posterior

# Nuovi dati: 150 impression, 20 click
n_ads_nuovi <- 150
n_clicks_nuovi <- 20

# Simuliamo i dati con le proporzioni del prior aggiornato
n_samples_aggiornato <- nrow(prior_aggiornato)
prior_aggiornato$n_visitors <- rbinom(n_samples_aggiornato,
                                       size = n_ads_nuovi,
                                       prob = prior_aggiornato$proportion_clicks)

# Conditioning: teniamo solo i campioni compatibili con 20 click
posterior_aggiornato <- prior_aggiornato[prior_aggiornato$n_visitors == n_clicks_nuovi, ]

cat("Campioni nel posterior aggiornato:", nrow(posterior_aggiornato), "\n")
cat("Media:", round(mean(posterior_aggiornato$proportion_clicks) * 100, 1), "%\n")

# Nuovo credible interval
ci_aggiornato <- quantile(posterior_aggiornato$proportion_clicks, probs = c(0.025, 0.975))
cat("Credible interval al 95%:", round(ci_aggiornato[1] * 100, 1), "% -",
    round(ci_aggiornato[2] * 100, 1), "%\n")

In totale ora abbiamo osservato 33 click su 250 impression (13.2%). La media del posterior aggiornato è circa il 13.5%, e il credible interval al 95% si è ristretto a circa 9.6% - 17.9% (rispetto al 7.7% - 19.1% precedente). La distribuzione si è "stretta": abbiamo più dati, quindi siamo più sicuri.

Visualizziamo l'evoluzione:

par(mfrow = c(1, 3))

# Prior originale
hist(runif(10000, 0, 0.20), breaks = 30, probability = TRUE,
     main = "1. Prior originale\n(uniforme 0-20%)",
     col = "lightyellow", xlab = "Tasso di click",
     ylab = "Densità", xlim = c(0, 0.25))

# Posterior dopo primi dati (13/100)
hist(posterior$proportion_clicks, breaks = 30, probability = TRUE,
     main = "2. Dopo 13/100 click",
     col = "lightblue", xlab = "Tasso di click",
     ylab = "Densità", xlim = c(0, 0.25))

# Posterior dopo secondi dati (33/250 totali)
hist(posterior_aggiornato$proportion_clicks, breaks = 30, probability = TRUE,
     main = "3. Dopo 33/250 click",
     col = "lightgreen", xlab = "Tasso di click",
     ylab = "Densità", xlim = c(0, 0.25))

Il messaggio visivo è immediato: la distribuzione si sposta e si stringe. Da un'incertezza totale (tutto tra 0% e 20%), passando per una stima ragionevole (centrata sul 13%), arriviamo a una stima più precisa attorno al 13.2%. Più dati raccogliamo, più il posterior si concentra attorno al valore vero.

Questo è l'aggiornamento bayesiano: un processo iterativo in cui l'informazione si accumula. Non buttiamo via niente di ciò che sapevamo prima; lo integriamo con le nuove evidenze.


Prior informativi e non informativi

Negli esempi precedenti abbiamo usato un prior uniforme: "tutti i valori tra 0% e 20% sono ugualmente plausibili". Questo si chiama prior non informativo (o debolmente informativo): non esprime una preferenza forte per nessun valore.

Ma nella pratica spesso sappiamo qualcosa. Se abbiamo già gestito molte campagne pubblicitarie, sappiamo che i tassi di click stanno tipicamente tra il 5% e il 15%, con una concentrazione attorno al 10%. Possiamo esprimere questa conoscenza con un prior informativo, ad esempio una distribuzione centrata su 0.10 con dispersione ridotta.

Confrontiamo i due approcci sugli stessi dati (13 click su 100 impression):

set.seed(42)

n_samples <- 100000
n_ads_shown <- 100
n_clicks_observed <- 13

# --- Prior non informativo: uniforme (0, 0.20) ---
prior_flat <- runif(n_samples, min = 0.0, max = 0.20)
sim_flat <- rbinom(n_samples, size = n_ads_shown, prob = prior_flat)
posterior_flat <- prior_flat[sim_flat == n_clicks_observed]

# --- Prior informativo: centrato su 10%, concentrato tra 5% e 15% ---
# Usiamo una distribuzione beta(20, 180) che ha media ~10% e varianza ridotta
prior_info <- rbeta(n_samples, shape1 = 20, shape2 = 180)
sim_info <- rbinom(n_samples, size = n_ads_shown, prob = prior_info)
posterior_info <- prior_info[sim_info == n_clicks_observed]

# Confronto
cat("=== Prior non informativo (uniforme) ===\n")
cat("Media posterior:", round(mean(posterior_flat) * 100, 1), "%\n")
cat("Credible interval 95%:", round(quantile(posterior_flat, 0.025) * 100, 1), "% -",
    round(quantile(posterior_flat, 0.975) * 100, 1), "%\n\n")

cat("=== Prior informativo (centrato su 10%) ===\n")
cat("Media posterior:", round(mean(posterior_info) * 100, 1), "%\n")
cat("Credible interval 95%:", round(quantile(posterior_info, 0.025) * 100, 1), "% -",
    round(quantile(posterior_info, 0.975) * 100, 1), "%\n")

Il posterior con prior informativo è leggermente "tirato" verso il 10% (la nostra esperienza pregressa), mentre quello con prior uniforme segue più fedelmente i dati. Con 13 click su 100, la differenza è modesta; ma con 5 click su 20, sarebbe molto più marcata.

Visualizziamo:

par(mfrow = c(1, 2))

hist(posterior_flat, breaks = 30, probability = TRUE,
     main = "Posterior con prior\nnon informativo",
     col = "lightyellow", xlab = "Tasso di click",
     ylab = "Densità", xlim = c(0, 0.25))

hist(posterior_info, breaks = 30, probability = TRUE,
     main = "Posterior con prior\ninformativo (10%)",
     col = "lightcoral", xlab = "Tasso di click",
     ylab = "Densità", xlim = c(0, 0.25))

Questa è una proprietà fondamentale dell'inferenza bayesiana: con pochi dati, il prior conta molto; con molti dati, il prior viene "sommerso" dai dati. Se avessimo 10.000 impression e 1.300 click, i due posterior sarebbero praticamente identici, indipendentemente dal prior scelto. I dati, alla lunga, vincono sempre.


Credible interval vs confidence interval

Questo è il punto in cui le strade si separano in modo chiaro. Nell'articolo sugli intervalli di confidenza abbiamo visto un punto fondamentale: l'intervallo di confidenza al 95% non significa che c'è il 95% di probabilità che il parametro sia nell'intervallo. È una proprietà della procedura, non del singolo intervallo.

Il credible interval bayesiano al 95%, invece, significa esattamente quello che sembra: c'è il 95% di probabilità che il parametro si trovi in quell'intervallo. È un'affermazione diretta su ciò che non conosciamo, non un'affermazione sulla procedura.

Rivediamo i numeri del nostro esempio (13 click su 100 impression):

Frequentista (IC) Bayesiano (credible interval)
Intervallo ~7.8% - 21.0% ~7.7% - 19.1%
Interpretazione "Se ripetessimo l'esperimento 100 volte, 95 intervalli conterrebbero il vero parametro" "C'è il 95% di probabilità che il vero parametro sia in questo intervallo"
Il parametro È un valore fisso; l'intervallo è casuale La nostra credenza sul parametro è descritta da una distribuzione
Dipende dal prior? No

I numeri sono simili — e questo non è un caso. Con campioni grandi e prior non informativi, i due approcci convergono. Ma l'interpretazione è profondamente diversa, e il credible interval è molto più intuitivo: "c'è il 95% di probabilità che il tasso di click sia tra il 7.7% e il 19.1%" è una frase che chiunque può comprendere e usare per prendere decisioni.


Quando usare l'approccio bayesiano

Non c'è un vincitore assoluto. La scelta dipende dal contesto:

L'approccio bayesiano funziona particolarmente bene quando:

  • Abbiamo pochi dati ma una conoscenza pregressa ragionevole. Il prior ci permette di ottenere stime sensate anche con campioni piccoli.
  • Ci serve un aggiornamento continuo: i dati arrivano nel tempo e vogliamo aggiornare la nostra stima progressivamente, senza ricominciare ogni volta da zero.
  • Vogliamo comunicare l'incertezza in modo diretto. Il credible interval è molto più intuitivo dell'intervallo di confidenza: dire "c'è il 90% di probabilità che il tasso di conversione sia tra il 3% e il 7%" è chiaro anche per chi non ha formazione statistica.

L'approccio frequentista resta preferibile quando:

  • Servono risultati standardizzati e ripetibili. I test frequentisti non dipendono da scelte soggettive (come il prior), e questo li rende più facili da confrontare e replicare.
  • Lavoriamo in contesti dove le convenzioni sono stabilite (pubblicazioni scientifiche, report regolamentari).
  • Abbiamo grandi campioni: con molti dati, i due approcci danno risultati praticamente identici, e il frequentista è spesso più semplice da implementare.

Nella pratica, molti professionisti usano entrambi gli approcci a seconda del contesto. L'A/B testing, ad esempio, può essere condotto in modo frequentista (come abbiamo visto nell'articolo dedicato) o in modo bayesiano — e alcune piattaforme di testing usano proprio l'approccio bayesiano per poter aggiornare i risultati in tempo reale.


Verso la distribuzione Beta

Abbiamo visto come l'aggiornamento bayesiano funzioni con la simulazione: generare campioni, simulare dati, filtrare. È un metodo potente e intuitivo, ma ha un limite pratico: ad ogni passaggio perdiamo campioni. Dopo due aggiornamenti, dei 100.000 campioni iniziali ne rimangono pochi.

La buona notizia è che, per il caso delle proporzioni (tassi di click, tassi di conversione, percentuali di successo), esiste una soluzione analitica elegante. La distribuzione Beta, che abbiamo già incontrato, è la distribuzione naturale per descrivere la nostra incertezza su una proporzione. E quando il prior è una distribuzione Beta e i dati sono binomiali (successo/insuccesso), il posterior è ancora una distribuzione Beta — con parametri aggiornati.

Questo significa che l'intero aggiornamento bayesiano si riduce a una semplice operazione sui parametri, senza bisogno di simulazioni. Ma questa è una storia per il prossimo articolo.


Prova tu

Un e-commerce ha un tasso di conversione storico intorno al 3%. Dopo un redesign della pagina prodotto, su 200 visite si osservano 10 conversioni (5%).

  1. Costruisci un modello bayesiano con prior uniforme tra 0% e 10% (incertezza iniziale: il tasso potrebbe essere qualsiasi valore in quel range).
  2. Usa la simulazione (come nell'esempio dell'articolo) per ottenere il posterior.
  3. Calcola il credible interval al 95%.
  4. Calcola la probabilità che il vero tasso di conversione sia superiore al 3%.

Suggerimento: il codice è quasi identico a quello dell'esempio sulla campagna ads. Cambia il prior (runif(n, 0, 0.10)), il numero di visite (200) e il numero di conversioni osservate (10). Per la domanda 4, conta quanti campioni del posterior sono superiori a 0.03 e dividi per il totale.


Per approfondire

Se vuoi esplorare la statistica bayesiana con un approccio accessibile e sorprendentemente divertente, Bayesian Statistics the Fun Way di Will Kurt è una lettura che consiglio. Kurt riesce a spiegare prior, posterior e aggiornamento bayesiano con esempi concreti che non richiedono una laurea in matematica — e usa R per la parte computazionale, esattamente come facciamo qui. È il libro ideale per chi vuole capire la logica bayesiana prima di affrontare la teoria formale.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *