我现在正在学习斯坦,并希望实施一个简单的混合模型。
在参考手册(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有更深入的了解。
答案 0 :(得分:2)
第二个程序定义了不同的密度。 normal_lpdf
返回单个标量值,该值是数据/参数容器上的log pdfs之和。
手册中有关于矩阵/向量与数组的章节。
您希望提高ppt
的定义以提高效率。
答案 1 :(得分:0)
我不是Stan用户,我不解释vector[K]
和real[K]
之间的区别。但是根据某些资源(here和here),应将混合位置的先前分布定义为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]));
}