23 La predizione bayesiana
Oltre ad una sintesi della distribuzione a posteriori attraverso il computo di indici caratteristici e alla verifica di ipotesi, un altro compito dell’analisi bayesiana è la predizione di nuovi dati futuri. Dopo aver osservato i dati di un campione e dopo avere ricavato le distribuzioni a posteriori dei parametri, è infatti possibile ottenere delle indicazioni sulle proprietà di dati futuri. L’uso più immediato della stima della distribuzione dei possibili valori futuri della variabile di esito è la verifica del modello in esame. Infatti, il modo più diretto per testare un modello è quello di utilizzare il modello corrente per fare previsioni sui possibili dati futuri per poi confrontare i dati predetti con i dati che sono stati effettivamente osservati nel campione corrente. Questa pratica va sotto il nome di controllo predittivo a posteriori. In questo capitolo ci focalizzeremo sul problema della predizione bayesiana esaminando il caso più semplice, ovvero lo schema beta-binomiale. In seguito estenderemo questa discussione al caso generale.
23.1 La distribuzione predittiva a posteriori
Una volta costruita la distribuzione a posteriori del parametro o dei parametri sconosciuti, potremmo essere interessati a utilizzare il modello bayesiano allo scopo di prevedere la probabilità di risultati futuri basandoci sui dati già osservati. Questo tipo di analisi inferenziale va sotto il nome di analisi predittiva.
L’esempio che considereremo qui nei dettagli riguarda il caso beta-binomiale, nel quale la distribuzione a priori per il parametro ignoto
Siamo dunque interessati a predire i risultati che si potrebbero osservare in nuovi campioni di
In questo Capitolo ci porremo il problema di trovare la distribuzione predittiva a posteriori nel caso beta-binomiale. Useremo tre metodi diversi:
- la soluzione analitica,
- i risultati di una simulazione,
- il campionamento MCMC.
I tre metodi producono risultati equivalenti. In seguito useremo il metodo MCMC perché ci consente di trovare facilmente la risposta cercata, anche quando una soluzione analitica non è disponibile.
23.2 Soluzione analitica
Nel caso dell’esempio in discussione, la distribuzione di
Assumendo che le osservazioni future
La distribuzione predittiva a posteriori viene ottenuta dalla distribuzione congiunta di
Nel caso dello schema beta-binomiale, la funzione
In conclusione, per lo schema beta-binomiale, la distribuzione predittiva a posteriori corrisponde ad una distribuzione di probabilità discreta chiamata distribuzione beta-binomiale di parametri
Nell’esempio relativo allo studio di Zetsche et al. (2019), la verosimiglianza è binomiale, i dati sono costituiti da 23 successi su 30 prove e la distribuzione a priori su
In base all’Equazione 23.3 sappiamo che la distribuzione predittiva a posteriori è una distribuzione beta-binomiale di parametri extraDistr
. Per i parametri specificati sopra, un grafico della distribuzione predittiva a posteriori si ottiene nel modo seguente.
La distribuzione predittiva a posteriori illustrata nella figura precedente ci dice qual è la plausibilità relativa di osservare
Esaminando la distribuzione predittiva notiamo che, nei possibili campioni futuri di 30 osservazioni, il valore
È desiderabile costruire un intervallo che contiene le realizzazioni discint()
del pacchetto LearnBayes
. Per i dati dell’esempio otteniamo
Sulla base delle informazioni disponibili, possiamo dunque prevedere, con un livello di certezza soggettiva che eccede la soglia di 0.91, che in un futuro campione di 30 soggetti clinici depressi, il numero di pazienti con depressione grave sarà compreso tra 12 e 23.
In conclusione, per il caso beta-binomiale, possiamo dire che la predizione bayesiana di una nuova osservazione futura è la realizzazione di una distribuzione beta-binomiale di parametri
23.3 La distribuzione predittiva a posteriori mediante simulazione
In situazioni dove è difficile derivare l’esatta distribuzione predittiva a posteriori è possibile ottenere un campione casuale di valori della distribuzione predittiva posteriori mediante simulazione. Facciamo un esempio riferito al caso che stiamo discutendo. È possibile svolgere la simulazione richiesta in due fasi. Supponiamo di volere ottenere un campione casuale di
Vediamo come si fa in pratica con
I primi 10 valori così ottenuti sono riportati di seguito.
Codice
pred_p_sim[1:10]
#> [1] 0.5435206 0.5319551 0.6045577 0.6337146 0.7552324 0.5393935 0.6187069
#> [8] 0.6193819 0.6736216 0.6051480
Per ciascuno dei valori
Calcolo la proporzione di volte in cui sono stati osservai i valori
Codice
ppd <- table(pred_y_sim) / nrep
ppd
#> pred_y_sim
#> 3 4 5 6 7 8 9 10 11 12
#> 0.00002 0.00004 0.00011 0.00036 0.00096 0.00241 0.00533 0.01000 0.01753 0.02882
#> 13 14 15 16 17 18 19 20 21 22
#> 0.04290 0.06110 0.07812 0.09476 0.10763 0.11311 0.10821 0.09765 0.07982 0.06185
#> 23 24 25 26 27 28 29 30
#> 0.04156 0.02536 0.01299 0.00630 0.00224 0.00064 0.00016 0.00002
Calcolo l’intervallo di valori
Confronto i risultati della simulazione con i valori esatti della distribuzione predittiva a posteriori. Di seguito riporto i risultati esatti.
Un grafico con la distribuzione predittiva a posteriori esatta è fornito nella figura seguente.
Codice
tibble(Y=0:30, Probability = prob30) %>%
ProbBayes::prob_plot(Color = "black")
Una rappresentazione della distribuzione a posteriori ottenuta mediante simulazione è il seguente.
Si noti che i risultati della simulazione sono indistinguibili dalla soluzione esatta.
23.4 La distribuzione predittiva a posteriori mediante MCMC
Il metodo basato su simulazione che abbiamo discusso sopra si basa sulla stessa logica usata dai metodi MCMC per ottenere un’approssimazione della distribuzione predittiva a posteriori. Mediante i metodi MCMC, le stime delle possibili osservazioni future
- campionare
, ovvero scegliere un valore a caso del parametro dalla distribuzione a posteriori; - campionare
, ovvero scegliere un’osservazione a caso dalla funzione di verosimiglianza condizionata al valore del parametro definito nel passo precedente.
Se i due passaggi descritti sopra vengono ripetuti un numero sufficiente di volte, l’istogramma risultante approssimerà la distribuzione predittiva a posteriori che, in teoria potrebbe essere ottenuta per via analitica.
Esercizio 23.1 Utilizziamo il codice Stan per generare
Codice
modelString = "
data {
int<lower=0> N;
array[N] int<lower=0, upper=1> y;
}
parameters {
real<lower=0, upper=1> theta;
}
model {
theta ~ beta(2, 10);
y ~ bernoulli(theta);
}
generated quantities {
array[N] int y_rep;
for (n in 1 : N) {
y_rep[n] = bernoulli_rng(theta);
}
}
"
writeLines(modelString, con = "code/betabin23-30-2-10.stan")
Si noti che nel nel blocco generated quantities
sono state aggiunte le istruzioni necessarie per simulare y_rep[n] = bernoulli_rng(theta)
. Una tale istruzione ci dice di generare un valore casuale di una variabile Bernoulliana di parametro for
specifica che tale operazione va ripetuta 30 volte per ciascuna iterazione MCMC.
I dati dell’esempio sono forniti in formato list
.
Compiliamo il codice Stan.
Codice
file <- file.path("code", "betabin23-30-2-10.stan")
mod <- cmdstan_model(file)
Eseguiamo il campionamento MCMC.
Codice
fit <- mod$sample(
data = data_list,
iter_sampling = 4000L,
iter_warmup = 2000L,
seed = SEED,
chains = 4L,
refresh = 0
)
Per comodità, trasformiamo l’oggetto fit
in un oggetto di classe stanfit
.
Codice
stanfit <- rstan::read_stan_csv(fit$output_files())
Il contenuto dell’oggetto stanfit
può essere esaminato mediante la funzione extract()
.
Dall’oggetto list_of_draws
recuperiamo y_rep
.
Codice
y_bern <- list_of_draws$y_rep
dim(y_bern)
#> [1] 16000 30
head(y_bern)
#>
#> iterations [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13]
#> [1,] 1 1 1 1 0 1 1 1 1 1 1 1 1
#> [2,] 0 1 0 1 1 1 0 0 1 0 0 0 0
#> [3,] 0 1 0 1 1 1 0 0 1 1 1 0 1
#> [4,] 1 0 0 1 1 0 0 1 0 1 1 1 0
#> [5,] 0 0 0 1 1 0 1 1 0 1 0 0 1
#> [6,] 1 1 1 1 1 1 0 1 0 1 1 1 0
#>
#> iterations [,14] [,15] [,16] [,17] [,18] [,19] [,20] [,21] [,22] [,23] [,24]
#> [1,] 0 1 1 1 1 1 0 0 1 0 1
#> [2,] 1 0 0 1 0 1 1 1 0 0 0
#> [3,] 0 0 1 0 1 1 0 1 0 0 1
#> [4,] 0 1 0 1 0 1 0 0 1 0 1
#> [5,] 0 0 1 1 1 1 1 0 1 0 1
#> [6,] 1 1 0 1 0 1 1 0 0 1 0
#>
#> iterations [,25] [,26] [,27] [,28] [,29] [,30]
#> [1,] 1 1 1 1 1 1
#> [2,] 0 1 1 0 1 1
#> [3,] 1 1 1 1 1 0
#> [4,] 0 1 1 0 0 1
#> [5,] 0 0 0 0 1 0
#> [6,] 0 0 1 0 1 1
Dato che il codice Stan definisce un modello per i dati grezzi (ovvero, per ciascuna singola prova Bernoulliana del campione), ogni riga della matrice y_bern
ha 30 colonne, ciascuna delle quali corrisponde ad un campione (
Per ottenere una stima della distribuzione predittiva a posteriori y_bern
.
Codice
tibble(y_rep = rowSums(y_bern)) %>%
ggplot(aes(x = y_rep, after_stat(density))) +
geom_histogram(binwidth = 1)
Si noti che l’istogramma così ottenuto è equivalente a quello trovato nella simulazione precedente.
23.5 I metodi per la valutazione del modello
23.5.1 Posterior predictive checks
La distribuzione predittiva a posteriori viene utilizzata per eseguire i cosiddetti controlli predittivi a posteriori (Posterior Predictive Checks, PPC). Nella distribuzione predittiva a posteriori, viene generato un campione di dati possibili futuri utilizzando le proprietà del modello adattato. È ovvio che tali dati possibili futuri devono almento essere coerenti con i dati del campione presente. I PPC eseguono un confronto grafico tra
Oltre al confronto visivo tra le distribuzioni
Esercizio 23.2 Esaminiamo ora un set di dati che non seguono la distribuzione normale (Gelman et al., 2020). I dati corrispondono ad una serie di misurazioni prese da Simon Newcomb nel 1882 come parte di un esperimento per stimare la velocità della luce. A questi dati verrà (inappropriatamente) adattata una distribuzione normale. L’obiettivo dell’esempio è quello di mostrare come i PPC possono rivelare la mancanza di adattamento di un modello ai dati.
I PPC mostrano che il modo più semplice per verificare l’adattamento del modello è quello di visualizzare
Visualizziamo la distribuzione dei dati con un istogramma.
Codice
tibble(newcomb) %>%
ggplot(aes(x = newcomb, after_stat(density))) +
geom_histogram(binwidth = 1)
Creiamo un oggetto di tipo list
dove inserire i dati.
Utilizziamo il seguente codice Stan per il modello normale.
Codice
modelString <- "
data {
int<lower=0> N;
vector[N] y;
}
parameters {
real mu;
real<lower=0> sigma;
}
model {
mu ~ normal(25, 10);
sigma ~ cauchy(0, 10);
y ~ normal(mu, sigma);
}
generated quantities {
vector[N] y_rep;
for (n in 1 : N) {
y_rep[n] = normal_rng(mu, sigma);
}
}
"
writeLines(modelString, con = "code/newcomb.stan")
Adattiamo il modello ai dati.
Codice
file <- file.path("code", "newcomb.stan")
mod <- cmdstan_model(file)
fit <- mod$sample(
data = data_list,
iter_sampling = 4000L,
iter_warmup = 2000L,
seed = SEED,
chains = 4L,
refresh = 0
)
Otteniamo le stime dei parametri
Codice
fit$summary(c("mu", "sigma"))
#> # A tibble: 2 × 10
#> variable mean median sd mad q5 q95 rhat ess_bulk ess_tail
#> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 mu 26.2 26.2 1.33 1.30 24.0 28.4 1.00 13305. 11189.
#> 2 sigma 10.9 10.8 0.958 0.943 9.40 12.5 1.00 12614. 10352.
Trasformiamo l’oggetto fit
in un formato stanfit
.
Codice
stanfit <- rstan::read_stan_csv(fit$output_files())
Rappresentiamo graficamente la distribuzione a posteriori di
Codice
mu_draws <- as.matrix(stanfit, pars = "mu")
mcmc_areas(mu_draws, prob = 0.95) # color 95% interval
La media campionaria è pari a 26.21.
Codice
mean(newcomb)
#> [1] 26.21212
Anche se trova la media giusta, il modello non è comunque adeguato a prevedere le altre proprietà della stanfit
.
I valori y_rep
sono i dati della distribuzione predittiva a posteriori che sono stati simulati usando gli stessi valori
Codice
ppc_hist(data_list$y, y_rep[1:8, ], binwidth = 1)
Alla stessa conclusione si giunge tramite un confronto tra la funzione di densità empirica della
Codice
ppc_dens_overlay(data_list$y, y_rep[1:50, ])
Generiamo ora i PPC per la media e il minimo della distribuzione.
Codice
ppc_stat_2d(data_list$y, y_rep, stat = c("mean", "min"))
In conclusione, possiamo dire che mentre la media viene riprodotta accuratamente dal modello, ciò non è vero per il minimo della distribuzione. L’origine di questa mancanza di adattamento è il fatto che la distribuzione delle misurazioni della velocità della luce è asimmetrica negativa.
Dato che ci sono poche osservazioni nella coda negativa della distribuzione, solo per fare un esempio, utilizzeremo ora un secondo modello che ipotizza una distribuzione
Codice
modelString = "
data {
int<lower=0> N;
vector[N] y;
}
parameters {
real mu;
real<lower=0> sigma;
real<lower=0> nu;
}
model {
mu ~ normal(25, 10);
sigma ~ cauchy(0, 10);
nu ~ cauchy(0, 10);
y ~ student_t(nu, mu, sigma);
}
generated quantities {
vector[N] y_rep;
for (n in 1 : N) {
y_rep[n] = student_t_rng(nu, mu, sigma);
}
}
"
writeLines(modelString, con = "code/newcomb2.stan")
Adattiamo questo secondo modello ai dati.
Codice
file <- file.path("code", "newcomb2.stan")
mod <- cmdstan_model(file)
fit <- mod$sample(
data = data_list,
iter_sampling = 4000L,
iter_warmup = 2000L,
seed = SEED,
chains = 4L,
refresh = 0
)
#> Running MCMC with 4 sequential chains...
#>
#> Chain 1 finished in 0.2 seconds.
#> Chain 2 finished in 0.2 seconds.
#> Chain 3 finished in 0.2 seconds.
#> Chain 4 finished in 0.2 seconds.
#>
#> All 4 chains finished successfully.
#> Mean chain execution time: 0.2 seconds.
#> Total execution time: 1.1 seconds.
Per questo secondo modello il confronto tra la funzione di densità empirica della
Codice
stanfit <- rstan::read_stan_csv(fit$output_files())
y_rep <- as.matrix(stanfit, pars = "y_rep")
ppc_dens_overlay(data_list$y, y_rep[1:50, ]) + xlim(0, 50)
Inoltre, anche la statistica “minimo della distribuzione” viene ben predetta dal modello.
Codice
ppc_stat_2d(data_list$y, y_rep, stat = c("mean", "min"))
In conclusione, per le misurazioni della velocità della luce di Newcomb l’accuratezza predittiva del modello basato sulla distribuzione
23.6 Distribuzione predittiva a priori
Nella sezione precedente abbiamo visto come la distribuzione predittiva è stata usata per generare nuovi dati previsti futuri. Più precisamente, mediante l’Equazione 23.1 abbiamo descritto la nostra incertezza sulla distribuzione di future osservazioni di dati, data la distribuzione a posteriori di
Si noti che, nell’Equazione 23.1,
In un modello bayesiano dove
Una rappresentazione alternativa della distribuzione congiunta
Il primo termine in questo prodotto, la densità
La distribuzione predittiva a priori può essere ricavata facilmente se l’inferenza bayesiana viene svolta mediante i metodi MCMC. Per fare un esempio consideriamo nuovamente i dati di Zetsche et al. (2019), con 23 successi in 30 prove. Nella discussione precedente abbiamo svolto l’aggiornamento bayesiano imponendo su
Nel caso di una verosimiglianza binomiale e di una distribuzione a priori Beta, la distribuzione predittiva a priori può essere costruita mediante la funzione LearnBayes::pbetap()
.
Codice
La distribuzione predittiva a priori assegna livelli diversi di credibilità a ciascuno dei possibili risultati dell’esperimento casuale, ovvero il fatto di osservare 0, 1, , 30 successi in 30 prove Bernoulliane.
Nella distribuzione predittiva a priori riportata nel grafico precedente ho evidenziato il punto
Se viene invece utilizzata una distribuzione a priori debolmente informativa, o vero
Codice
In questo secondo caso al valore
Nella discussione dell’analisi dei dati di Zetsche et al. (2019), la
Commenti e considerazioni finali
Questo capitolo discute la predizione bayesiana e ne mostra un’applicazione nel caso dei controlli predittivi a posteriori. A questo proposito è necessario notare un punto importante: un buona corrispondenza tra