La bibliografia afferma che se q è una distribuzione simmetrica il rapporto q (x | y) / q (y | x) diventa 1 e l'algoritmo si chiama Metropolis. È corretto?
Sì, questo è corretto. L'algoritmo Metropolis è un caso speciale dell'algoritmo MH.
Che dire di "Random Walk" Metropolis (-Hastings)? In che cosa differisce dalle altre due?
In una passeggiata casuale, la distribuzione della proposta viene ricentrata dopo ogni passaggio sull'ultimo valore generato dalla catena. Generalmente, in una passeggiata casuale la distribuzione della proposta è gaussiana, nel qual caso questa passeggiata casuale soddisfa il requisito di simmetria e l'algoritmo è metropoli. Suppongo che tu possa eseguire una camminata casuale "pseudo" con una distribuzione asimmetrica che causerebbe una deriva eccessiva delle proposte nella direzione opposta rispetto all'inclinazione (una distribuzione inclinata a sinistra favorirebbe le proposte verso destra). Non sono sicuro del motivo per cui lo faresti, ma potresti e sarebbe un algoritmo di hastings della metropoli (cioè richiedere il termine rapporto aggiuntivo).
In che cosa differisce dalle altre due?
In un algoritmo di camminata non casuale, le distribuzioni della proposta sono fisse. Nella variante di camminata casuale, il centro della distribuzione della proposta cambia ad ogni iterazione.
Che cosa succede se la distribuzione della proposta è una distribuzione di Poisson?
Quindi è necessario utilizzare MH anziché solo metropoli. Presumibilmente questo sarebbe campionare una distribuzione discreta, altrimenti non vorrai usare una funzione discreta per generare le tue proposte.
In ogni caso, se la distribuzione di campionamento viene troncata o se si ha una conoscenza preliminare del suo disallineamento, probabilmente si desidera utilizzare una distribuzione di campionamento asimmetrica e quindi è necessario utilizzare gli hasting metropolitani.
Qualcuno potrebbe darmi un semplice esempio di codice (C, python, R, pseudo-codice o qualunque cosa tu preferisca)?
Ecco la metropoli:
Metropolis <- function(F_sample # distribution we want to sample
, F_prop # proposal distribution
, I=1e5 # iterations
){
y = rep(NA,T)
y[1] = 0 # starting location for random walk
accepted = c(1)
for(t in 2:I) {
#y.prop <- rnorm(1, y[t-1], sqrt(sigma2) ) # random walk proposal
y.prop <- F_prop(y[t-1]) # implementation assumes a random walk.
# discard this input for a fixed proposal distribution
# We work with the log-likelihoods for numeric stability.
logR = sum(log(F_sample(y.prop))) -
sum(log(F_sample(y[t-1])))
R = exp(logR)
u <- runif(1) ## uniform variable to determine acceptance
if(u < R){ ## accept the new value
y[t] = y.prop
accepted = c(accepted,1)
}
else{
y[t] = y[t-1] ## reject the new value
accepted = c(accepted,0)
}
}
return(list(y, accepted))
}
Proviamo a usarlo per campionare una distribuzione bimodale. Innanzitutto, vediamo cosa succede se utilizziamo una camminata casuale per il nostro propsal:
set.seed(100)
test = function(x){dnorm(x,-5,1)+dnorm(x,7,3)}
# random walk
response1 <- Metropolis(F_sample = test
,F_prop = function(x){rnorm(1, x, sqrt(0.5) )}
,I=1e5
)
y_trace1 = response1[[1]]; accpt_1 = response1[[2]]
mean(accpt_1) # acceptance rate without considering burn-in
# 0.85585 not bad
# looks about how we'd expect
plot(density(y_trace1))
abline(v=-5);abline(v=7) # Highlight the approximate modes of the true distribution
Ora proviamo il campionamento utilizzando una distribuzione di proposta fissa e vediamo cosa succede:
response2 <- Metropolis(F_sample = test
,F_prop = function(x){rnorm(1, -5, sqrt(0.5) )}
,I=1e5
)
y_trace2 = response2[[1]]; accpt_2 = response2[[2]]
mean(accpt_2) # .871, not bad
All'inizio sembra ok, ma se diamo un'occhiata alla densità posteriore ...
plot(density(y_trace2))
vedremo che è completamente bloccato al massimo locale. Ciò non è del tutto sorprendente poiché abbiamo effettivamente concentrato la nostra distribuzione delle proposte lì. La stessa cosa accade se centriamo questo sull'altra modalità:
response2b <- Metropolis(F_sample = test
,F_prop = function(x){rnorm(1, 7, sqrt(10) )}
,I=1e5
)
plot(density(response2b[[1]]))
Possiamo provare a far cadere la nostra proposta tra le due modalità, ma dovremo impostare la varianza davvero alta per avere la possibilità di esplorarne una
response3 <- Metropolis(F_sample = test
,F_prop = function(x){rnorm(1, -2, sqrt(10) )}
,I=1e5
)
y_trace3 = response3[[1]]; accpt_3 = response3[[2]]
mean(accpt_3) # .3958!
Nota come la scelta del centro della nostra distribuzione di proposta ha un impatto significativo sul tasso di accettazione del nostro campionatore.
plot(density(y_trace3))
plot(y_trace3) # we really need to set the variance pretty high to catch
# the mode at +7. We're still just barely exploring it
Rimaniamo ancora bloccati nel più vicino dei due modi. Proviamo a lasciarlo cadere direttamente tra le due modalità.
response4 <- Metropolis(F_sample = test
,F_prop = function(x){rnorm(1, 1, sqrt(10) )}
,I=1e5
)
y_trace4 = response4[[1]]; accpt_4 = response4[[2]]
plot(density(y_trace1))
lines(density(y_trace4), col='red')
Infine, ci stiamo avvicinando a ciò che stavamo cercando. Teoricamente, se lasciamo che il campionatore funzioni abbastanza a lungo, possiamo ottenere un campione rappresentativo da una qualsiasi di queste distribuzioni di proposta, ma la camminata casuale ha prodotto un campione utilizzabile molto rapidamente e abbiamo dovuto sfruttare la nostra conoscenza di come si supponeva il posteriore cercare di mettere a punto le distribuzioni di campionamento fisse per produrre un risultato utilizzabile (che, a dire la verità, non abbiamo ancora del tutto y_trace4
).
Proverò ad aggiornare con un esempio di episodi di metropoli in seguito. Dovresti essere in grado di vedere abbastanza facilmente come modificare il codice sopra per produrre un algoritmo di hastings metropoli (suggerimento: devi solo aggiungere il rapporto supplementare nel logR
calcolo).