Gestione dell'alta autocorrelazione in MCMC


10

Sto costruendo un modello bayesiano gerarchico piuttosto complesso per una meta-analisi usando R e JAGS. Semplificando un po ', i due livelli chiave del modello hanno dove è la esima osservazione del endpoint (in questo caso, rese colturali GM / non GM) nello studio , è l'effetto per lo studio , i s sono effetti per varie variabili a livello di studio (lo stato di sviluppo economico del paese in cui il sono stati fatti studi, specie di colture, metodo di studio, ecc.) indicizzati da una famiglia di funzioni eα j = h γ h ( j ) + ϵ j y i j i j α j j γ h ϵ

yioj=αj+εio
αj=Σhγh(j)+εj
yiojiojαjjγhεs sono termini di errore. Si noti che s non sono coefficienti su variabili fittizie. Esistono invece variabili distinte per diversi valori a livello di studio. Ad esempio, esiste per i paesi in via di sviluppo e per i paesi sviluppati. γ γ d e v e l o p i n g γ d e v e l o p e dγγγdevelopiongγdeveloped

Sono principalmente interessato a stimare i valori di s. Ciò significa che eliminare le variabili a livello di studio dal modello non è una buona opzione. γ

C'è un'elevata correlazione tra molte delle variabili a livello di studio e penso che questo stia producendo grandi autocorrelazioni nelle mie catene MCMC. Questo diagramma diagnostico illustra le traiettorie a catena (a sinistra) e la risultante autocorrelazione (a destra):
alta autocorrelazione nell'output MCMC

Come conseguenza dell'autocorrelazione, sto ottenendo dimensioni del campione effettive di 60-120 da 4 catene da 10.000 campioni ciascuna.

Ho due domande, una chiaramente obiettiva e l'altra più soggettiva.

  1. Oltre a diradare, aggiungere più catene ed eseguire il campionatore più a lungo, quali tecniche posso usare per gestire questo problema di autocorrelazione? Per "gestire" intendo "produrre stime ragionevolmente buone in un ragionevole lasso di tempo". In termini di potenza di calcolo, sto eseguendo questi modelli su un MacBook Pro.

  2. Quanto è grave questo grado di autocorrelazione? Le discussioni sia qui che sul blog di John Kruschke suggeriscono che, se eseguiamo il modello abbastanza a lungo, "probabilmente la complessa autocorrelazione è stata mediata" (Kruschke) e quindi non è un grosso problema.

Ecco il codice JAGS per il modello che ha prodotto la trama sopra, nel caso in cui qualcuno sia abbastanza interessato a sfogliare i dettagli:

model {
for (i in 1:n) {
    # Study finding = study effect + noise
    # tau = precision (1/variance)
    # nu = normality parameter (higher = more Gaussian)
    y[i] ~ dt(alpha[study[i]], tau[study[i]], nu)
}

nu <- nu_minus_one + 1
nu_minus_one ~ dexp(1/lambda)
lambda <- 30

# Hyperparameters above study effect
for (j in 1:n_study) {
    # Study effect = country-type effect + noise
    alpha_hat[j] <- gamma_countr[countr[j]] + 
                    gamma_studytype[studytype[j]] +
                    gamma_jour[jourtype[j]] +
                    gamma_industry[industrytype[j]]
    alpha[j] ~ dnorm(alpha_hat[j], tau_alpha)
    # Study-level variance
    tau[j] <- 1/sigmasq[j]
    sigmasq[j] ~ dunif(sigmasq_hat[j], sigmasq_hat[j] + pow(sigma_bound, 2))
    sigmasq_hat[j] <- eta_countr[countr[j]] + 
                        eta_studytype[studytype[j]] + 
                        eta_jour[jourtype[j]] +
                        eta_industry[industrytype[j]]
    sigma_hat[j] <- sqrt(sigmasq_hat[j])
}
tau_alpha <- 1/pow(sigma_alpha, 2)
sigma_alpha ~ dunif(0, sigma_alpha_bound)

# Priors for country-type effects
# Developing = 1, developed = 2
for (k in 1:2) {
    gamma_countr[k] ~ dnorm(gamma_prior_exp, tau_countr[k])
    tau_countr[k] <- 1/pow(sigma_countr[k], 2)
    sigma_countr[k] ~ dunif(0, gamma_sigma_bound)
    eta_countr[k] ~ dunif(0, eta_bound)
}

# Priors for study-type effects
# Farmer survey = 1, field trial = 2
for (k in 1:2) {
    gamma_studytype[k] ~ dnorm(gamma_prior_exp, tau_studytype[k])
    tau_studytype[k] <- 1/pow(sigma_studytype[k], 2)
    sigma_studytype[k] ~ dunif(0, gamma_sigma_bound)
    eta_studytype[k] ~ dunif(0, eta_bound)
}

# Priors for journal effects
# Note journal published = 1, journal published = 2
for (k in 1:2) {
    gamma_jour[k] ~ dnorm(gamma_prior_exp, tau_jourtype[k])
    tau_jourtype[k] <- 1/pow(sigma_jourtype[k], 2)
    sigma_jourtype[k] ~ dunif(0, gamma_sigma_bound)
    eta_jour[k] ~ dunif(0, eta_bound)
}

# Priors for industry funding effects
for (k in 1:2) {
    gamma_industry[k] ~ dnorm(gamma_prior_exp, tau_industrytype[k])
    tau_industrytype[k] <- 1/pow(sigma_industrytype[k], 2)
    sigma_industrytype[k] ~ dunif(0, gamma_sigma_bound)
    eta_industry[k] ~ dunif(0, eta_bound)
}
}

1
Per quello che vale, i complessi modelli multilivello sono praticamente il motivo dell'esistenza di Stan, esattamente per i motivi che identifichi.
Sycorax dice di reintegrare Monica il

Inizialmente ho provato a costruirlo a Stan, diversi mesi fa. Gli studi comportano un numero diverso di risultati, che (almeno al momento; non ho verificato per vedere se le cose sono cambiate) hanno richiesto l'aggiunta di un altro livello di complessità al codice e hanno significato che Stan non poteva trarre vantaggio dai calcoli della matrice che lo rendono così veloce.
Dan Hicks,

1
Non pensavo alla velocità tanto quanto all'efficienza con cui HMC esplora il posteriore. La mia comprensione è che poiché l'HMC può coprire molto più terreno, ogni iterazione ha un'autocorrelazione inferiore.
Sycorax dice di reintegrare Monica il

Oh, sì, questo è un punto interessante. Lo inserirò nella mia lista di cose da provare.
Dan Hicks,

Risposte:


6

Seguendo il suggerimento di user777, sembra che la risposta alla mia prima domanda sia "usa Stan". Dopo aver riscritto il modello in Stan, ecco le traiettorie (4 catene x 5000 iterazioni dopo il burn-in):
inserisci qui la descrizione dell'immagine E i grafici di autocorrelazione:
inserisci qui la descrizione dell'immagine

Molto meglio! Per completezza, ecco il codice Stan:

data {                          // Data: Exogenously given information
// Data on totals
int n;                      // Number of distinct finding i
int n_study;                // Number of distinct studies j

// Finding-level data
vector[n] y;                // Endpoint for finding i
int study_n[n_study];       // # findings for study j

// Study-level data
int countr[n_study];        // Country type for study j
int studytype[n_study];     // Study type for study j
int jourtype[n_study];      // Was study j published in a journal?
int industrytype[n_study];  // Was study j funded by industry?

// Top-level constants set in R call
real sigma_alpha_bound;     // Upper bound for noise in alphas
real gamma_prior_exp;       // Prior expected value of gamma
real gamma_sigma_bound;     // Upper bound for noise in gammas
real eta_bound;             // Upper bound for etas
}

transformed data {
// Constants set here
int countr_levels;          // # levels for countr
int study_levels;           // # levels for studytype
int jour_levels;            // # levels for jourtype
int industry_levels;        // # levels for industrytype
countr_levels <- 2;
study_levels <- 2;
jour_levels <- 2;
industry_levels <- 2;
}

parameters {                    // Parameters:  Unobserved variables to be estimated
vector[n_study] alpha;      // Study-level mean
real<lower = 0, upper = sigma_alpha_bound> sigma_alpha;     // Noise in alphas

vector<lower = 0, upper = 100>[n_study] sigma;          // Study-level standard deviation

// Gammas:  contextual effects on study-level means
// Country-type effect and noise in its estimate
vector[countr_levels] gamma_countr;     
vector<lower = 0, upper = gamma_sigma_bound>[countr_levels] sigma_countr;
// Study-type effect and noise in its estimate
vector[study_levels] gamma_study;
vector<lower = 0, upper = gamma_sigma_bound>[study_levels] sigma_study;
vector[jour_levels] gamma_jour;
vector<lower = 0, upper = gamma_sigma_bound>[jour_levels] sigma_jour;
vector[industry_levels] gamma_industry;
vector<lower = 0, upper = gamma_sigma_bound>[industry_levels] sigma_industry;


// Etas:  contextual effects on study-level standard deviation
vector<lower = 0, upper = eta_bound>[countr_levels] eta_countr;
vector<lower = 0, upper = eta_bound>[study_levels] eta_study;
vector<lower = 0, upper = eta_bound>[jour_levels] eta_jour;
vector<lower = 0, upper = eta_bound>[industry_levels] eta_industry;
}

transformed parameters {
vector[n_study] alpha_hat;                  // Fitted alpha, based only on gammas
vector<lower = 0>[n_study] sigma_hat;       // Fitted sd, based only on sigmasq_hat

for (j in 1:n_study) {
    alpha_hat[j] <- gamma_countr[countr[j]] + gamma_study[studytype[j]] + 
                    gamma_jour[jourtype[j]] + gamma_industry[industrytype[j]];
    sigma_hat[j] <- sqrt(eta_countr[countr[j]]^2 + eta_study[studytype[j]]^2 +
                        eta_jour[jourtype[j]] + eta_industry[industrytype[j]]);
}
}

model {
// Technique for working w/ ragged data from Stan manual, page 135
int pos;
pos <- 1;
for (j in 1:n_study) {
    segment(y, pos, study_n[j]) ~ normal(alpha[j], sigma[j]);
    pos <- pos + study_n[j];
}

// Study-level mean = fitted alpha + Gaussian noise
alpha ~ normal(alpha_hat, sigma_alpha);

// Study-level variance = gamma distribution w/ mean sigma_hat
sigma ~ gamma(.1 * sigma_hat, .1);

// Priors for gammas
gamma_countr ~ normal(gamma_prior_exp, sigma_countr);
gamma_study ~ normal(gamma_prior_exp, sigma_study);
gamma_jour ~ normal(gamma_prior_exp, sigma_study);
gamma_industry ~ normal(gamma_prior_exp, sigma_study);
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.