Stan中的混合模型 - 矢量化

时间:2017-02-03 15:59:21

标签: mixture-model stan rstan mixture

我现在正在学习斯坦,并希望实施一个简单的混合模型。

在参考手册(stan-reference-2.14.0)中已有解决方案:

data {
  int<lower=1> K; // number of mixture components
  int<lower=1> N; // number of data points
  real y[N]; // observations
}
parameters {
  simplex[K] theta; // mixing proportions
  real mu[K]; // locations of mixture components
  real<lower=0> sigma[K]; // scales of mixture components
}
model {
  real ps[K]; // temp for log component densities
  sigma ~ cauchy(0, 2.5);
  mu ~ normal(0, 10);
  for (n in 1:N) {
    for (k in 1:K) {
      ps[k] = log(theta[k])
      + normal_lpdf(y[n] | mu[k], sigma[k]);
    }
    target += log_sum_exp(ps);
  }
}

下一页描述了外循环的矢量化是不可能的。但是,我想知道内循环的平行化是否仍然存在。

所以我尝试了以下模型:

data {
  int<lower=1> K; // number of mixture components
  int<lower=1> N; // number of data points
  real y[N]; // observations
}

parameters {
  simplex[K] theta; // mixing proportions
  vector[K] mu; // locations of mixture components
  vector<lower=0>[K] sigma; // scales of mixture components
}

model {
  vector[K] ps;//[K]; // temp for log component densities
  vector[K] ppt;
  sigma ~ cauchy(0, 2.5);
  mu ~ normal(0, 10);
  for (n in 1:N) {
    ppt = log(theta);
    /*
    for (k in 1:K) {
      ps[k] = ppt[k] + //log(theta[k])
        normal_lpdf(y[n] | mu[k], sigma[k]);
    }
    */
    ps = ppt + normal_lpdf(y[n] | mu, sigma);
    target += log_sum_exp(ps);
  }
}

...而且这个模型做出了错误的估计(与原始模型相反)。

data("faithful")
erupdata <- list(
  K = 2,
  N = length(faithful$eruptions),
  y = faithful$eruptions
)

fiteruptions <- stan(file = 'mixturemodel.stan', data = erupdata, iter = 1000, chains = 1)

我想知道,我对模型规范的理解是错误的。我想了解语法提供的差异(以及vector[K]real[K]之间的区别),并且可能会对Stan有更深入的了解。

2 个答案:

答案 0 :(得分:2)

第二个程序定义了不同的密度。 normal_lpdf返回单个标量值,该值是数据/参数容器上的log pdfs之和。

手册中有关于矩阵/向量与数组的章节。

您希望提高ppt的定义以提高效率。

答案 1 :(得分:0)

我不是Stan用户,我不解释vector[K]real[K]之间的区别。但是根据某些资源(herehere),应将混合位置的先前分布定义为ordered[K],而不是vector[K],以避免无法识别的问题/可互换的先验。

为更深入地了解上述问题,强烈建议您使用 Identifying Bayesian Mixture Models 博客。 从此博客复制的工作模型:

data {
 int<lower = 0> N;
 vector[N] y;
}

parameters {
  ordered[2] mu;
  real<lower=0> sigma[2];
  real<lower=0, upper=1> theta;
}

model {
 sigma ~ normal(0, 2);
 mu ~ normal(0, 2);
 theta ~ beta(5, 5);
 for (n in 1:N)
   target += log_mix(theta,
                     normal_lpdf(y[n] | mu[1], sigma[1]),
                     normal_lpdf(y[n] | mu[2], sigma[2]));
}