Управление высокой автокорреляцией в MCMC

10

Я строю довольно сложную иерархическую байесовскую модель для мета-анализа с использованием R и JAGS. Упрощенно, два ключевых уровня модели имеют α j = h γ h ( j ) + ϵ j, где y i j - i- е наблюдение за конечной точкой (в данном случае , GM против урожайности не-GM культур) в исследовании j , α j - эффект для исследования j

YяJзнак равноαJ+εя
αJзнак равноΣчасγчас(J)+εJ
YяJяJαJJ , γs являются эффектами для различного переменного исследования уровня (состояние экономического развития страны , в которой было сделано исследование, виды культур, методы исследования и т.д.) , индексированного семейством функций , а epsi ; s термины ошибки. Обратите внимание, что γ s не являются коэффициентами на фиктивных переменных. Вместо этого существуют разные γ- переменные для разных значений уровня обучения. Так , например, существует γ д е v е л о р я н г для развивающихся стран и γ д е v е л ö рчасεγγγdеvеLопяNгγdеvеLопеd для развитых стран.

Меня в первую очередь интересует оценка значений s. Это означает, что удаление переменных уровня обучения из модели не является хорошим вариантом. γ

Существует высокая корреляция между несколькими переменными уровня исследования, и я думаю, что это приводит к большим автокорреляциям в моих цепочках MCMC. Этот диагностический график иллюстрирует траектории цепочки (слева) и результирующую автокорреляцию (справа):
высокая автокорреляция на выходе MCMC

В результате автокорреляции я получаю эффективные размеры выборки 60-120 из 4 цепочек по 10 000 выборок в каждой.

У меня два вопроса, один явно объективный, а другой более субъективный.

  1. Какие методы я могу использовать для решения этой проблемы автокорреляции, кроме прореживания, добавления новых цепочек и более длительного запуска сэмплера? Под «управлять» я подразумеваю «производить достаточно хорошие оценки в разумные сроки». С точки зрения вычислительной мощности, я использую эти модели на MacBook Pro.

  2. Насколько серьезна эта степень автокорреляции? Обсуждения как здесь, так и в блоге Джона Крушке показывают, что, если мы просто запустим модель достаточно долго, «комковатая автокорреляция, вероятно, все усреднена» (Крушке), и, следовательно, это не имеет большого значения.

Вот код JAGS для модели, которая создала сюжет выше, на тот случай, если кому-то будет интересно узнать подробности:

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
Что бы это ни стоило, сложные многоуровневые модели являются в значительной степени причиной существования Stan, именно по тем причинам, которые вы определили.
Sycorax говорит восстановить Монику
Первоначально я пытался построить это в Стене, несколько месяцев назад. Исследования включают в себя различное количество выводов, которые (по крайней мере, в то время; я не проверял, изменились ли вещи) требовали добавления еще одного уровня сложности в код и означали, что Стэн не мог воспользоваться преимуществами матричных вычислений. это делает это так быстро.
Дэн Хикс
1
Я не столько думал о скорости, сколько об эффективности, с которой HMC исследует заднюю часть. Насколько я понимаю, поскольку HMC может охватывать гораздо больше областей, каждая итерация имеет меньшую автокорреляцию.
Сикоракс говорит восстановить Монику
О да, это интересный момент. Я внесу это в свой список вещей, чтобы попробовать.
Дэн Хикс

Ответы:

6

Следуя предложению user777, похоже, что ответ на мой первый вопрос «использовать Stan». После переписывания модели в Stan, вот траектории (4 цепочки x 5000 итераций после выгорания):
введите описание изображения здесь и графики автокорреляции:
введите описание изображения здесь

Намного лучше! Для полноты вот код Стэна:

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);
}
Дэн Хикс
источник