I am trying to fit a beta binomial mixture model with weights as a random variable (hyper parameter) with two parts.
The likelihood results is in between the two priors. However, in the posterior distributions do not move toward the likelihood.
What am I doing wrong in the stan code? From looking at examples online I understood that the b
parameter must be ordered, but this does not seem to help (and adds warnings since I can’t constrain the range [0,1] in an ordered vector).
I have also tried to use log_mix
, but the documentation of this function and examples are very limited.
data
input_data_post <- list(
N = 59,
y = c(rep(1,45), rep(0,14)),
K = 2,
alpha = c(25.8, 7.5),
beta = c(4.2, 7.5),
prior_only = 0 #if 1 then only prior will be used (no data)
)
stan code
data {
int<lower=1> K; // number of mixture components
int<lower=1> N; // number of data points
int<lower=0,upper=1> y[N]; // observations
real<lower = 0> alpha[K];
real<lower = 0> beta[K];
int<lower=0,upper=1> prior_only; // =1 to get data from prior predictive
}
parameters {
//simplex[K] w;
real<lower=0.59, upper=0.61> w0; // mixing proportions
positive_ordered[K] b; // locations of mixture components
}
transformed parameters {
simplex[K] w;
vector[K] log_w;
w[2] = w0;
w[1] = 1 - w0;
for(i in 1:K){
log_w[i] = log(w[i]);
}
}
model {
// contributions from each component
// these get overwritten for each observation
vector[K] lps;
// priors
w0 ~ uniform(0,1);
b[2] ~ beta(alpha[1], beta[1]);
b[1] ~ beta(alpha[2], beta[2]);
// individual likelihoods, as sum of component contributions
for (n in 1:N) {
for (k in 1:K) {
lps[k] = log_w[k] + bernoulli_lpmf(y[n] | b[k]);
}
// add the observation likelihood contribution if not prior-only
if (prior_only == 0) {
target += log_sum_exp(lps);
}
}
}