Hi Stan Users,
I'd like to do some comparison of discrete models based on their model evidence p(M|y), and I'm wondering what the best way is to do this in stan. It seems to me that a good approach is to use Bayes factors, for which I need p(y|M) for each model. I'm imagining using stan to approximate the integral p(y|theta)*p(theta)*dTheta by sampling p(theta) in the Model block, computing the likelihood at each sample in the generated quantities block, and taking the average of these outside of stan. Code illustrating this idea for a simple hierarchical gaussian model is below the fold.
Alternatives on my mind include BIC, which I understand to constitute a minor statistical sin, and a technique called "thermodynamic integration", which I don't totally understand. I guess my questions are as much about statistics as they are about stan itself:
1) Does the approach below make sense as a way of getting estimates of p(y|M) for use in a Bayes Factor?
2) More generally: What are best practices in stan for comparing models based on model evidence, rather than on predictive performance?
Thanks!
Kevin
// Stan code for generating samples from p(theta), computing at each theta p(y|theta)
data {
int num_subjects;
int num_observations;
real y[num_subjects, num_observations];
real prior_mean;
real prior_var;
real prior_location;
real prior_scale;
}
parameters {
real pop_mean_mean;
real<lower=0> pop_mean_var;
real<lower=0> shared_var;
real subj_mean[num_subjects];
}
model {
pop_mean_mean ~ normal(prior_mean,prior_var);
pop_mean_var ~ cauchy(prior_location, prior_scale);
shared_var ~ cauchy(prior_location, prior_scale);
subj_mean ~ normal(pop_mean_mean, pop_mean_var);
}
generated quantities {
real log_lik;
log_lik <- 0;
for (subj_i in 1:num_subjects) {
for (obs_i in 1:num_observations){
log_lik <- log_lik + normal_log(y[subj_i,obs_i],subj_mean[subj_i],shared_var);
}
}
}
// Then back in matlab:
log_p_D_given_M = log(mean(exp(model_output.extract.log_lik)))