I am trying to fit a mixture model of two negative binomial distributions. I would like to estimate the parameters of those distributions. Also, for every single observation, I want to know from which of the two possible distributions that observation comes.
As far as I can tell the sampling works fine. However I am not able to estimate the \mu parameters of the models correctly (irrespective of the amount of data provided). For comparison I also tried \texttt{optimizing()}, with similar results. \texttt{optimizing()} gave me results like (34, 5), Stan gave (27, 7) instead of (20, 5). Do you have any ideas how to fix this? Thank you.
library(rstan)
options(mc.cores = parallel::detectCores() - 2)
rstan_options(auto_write = TRUE)
generatemixedcounts <- function(n = 6, N = 50, phi = 1, mu1 = 20, mu2 = 5){
## select some of the entries of the matrix
m <- matrix(NA, nrow = N, ncol = n)
m[] <- rnbinom(n = n*N, mu = mu1, size = phi)
select <- sample(c(T,F), size = n * N, replace = T, prob = c(0.25, 0.75))
tmp <- rnorm(n = sum(select), mean = 0, sd = 1)
## assign rnbinom with different mu
m[select] <- rnbinom(n = sum(select), mu = mu2, size = phi)
return(m)
}
toy <- generatemixedcounts(N = 60, mu1 = 20, mu2 = 5)
standata <- list(y = toy, N = nrow(toy), n = ncol(toy))
write("
data {
int<lower=0> N;
int<lower=0> n;
int<lower=0> y[N,n];
}
parameters {
matrix <lower=0, upper=1>[N,n] pi;
ordered[2] mu;
real<lower=0> phi;
}
model {
vector[2] contributions;
for (j in 1:n){
for (i in 1:N) {
contributions[1] = log(pi[i,j]) + neg_binomial_2_lpmf(y[i,j] | mu[2], phi);
contributions[2] = log( (1 - pi[i,j]) ) + neg_binomial_2_lpmf(y[i,j] | mu[1], phi);
target += log_sum_exp(contributions);
}
}
}
", file = "./mixturenegbin.stan")
## MAP Estimation
model <- stan_model(file = "./mixturenegbin.stan")
optimizing(model,
data = standata,
iter = 1000, seed = 1)
## Bayesian Estimation
stanfit <- rstan::stan(file = "./mixturenegbin.stan",
data = standata,
iter = 1000, warmup = 500, thin = 1, seed = 1)
stanfit
library(shinystan)
launch_shinystan(stanfit)