推断受 STAN 中的总和约束的两个变量的后验

infer posterior of two variables constrained by their sum in STAN

动机:回答下面的问题:2个男人的身高相加是4米,每个男人最可能的身高是多少?

我正在尝试使用 STAN 对此进行建模(对于这个用例来说可能有点矫枉过正,但目标是拥有一个我可以扩展的通用框架),我假设人们的身高是正常的(1.8 , 0.2).

我想出了以下 .stan 代码,但是当我查看结果时,似乎没有考虑总和的约束。我做错了什么?

experiment.stan

data {
}
parameters {
  real y1;
  real y2;
}
transformed parameters {
  real S;
  S = y1+y2;
  S = 4;
}
model {  
  y1 ~ normal(1.8,0.2);
  y2 ~ normal(1.8,0.2);
}

experiment.R

#load libraries
library(rstan)
library(coda)

#the model
heights<-stan(file="experiment.stan",
             pars = c("y1", "y2", "S"))

#plotting the posterior distribution for the parameters
post_beta<-As.mcmc.list(heights,pars=c("y1", "y2", "S"))
plot(post_beta)

一种选择是使用 Unit Simplex,它类似于元素总和等于 1 的向量。然后,您可以通过将 generated quantities 中的所有内容乘以 4 来重新缩放部分(一直向下滚动以查看相关策略):

stan_program <- "
parameters {
  simplex[2] height;
}
model {  
  height ~ normal(.45, .05);
}
generated quantities {
  vector[2] height_scale;
  height_scale = height * 4;
}
"

library(rstan)
library(coda)

mod <- stan(model_code=stan_program) 
post_beta <- As.mcmc.list(mod, pars=c("height_scale"))
plot(post_beta)  

编辑:类似的方法是

parameters {
  simplex[2] height_constrained;
}
transformed parameters {
  vector[2] height;
  height = height_constrained * 4;
}
model {  
  height_constrained ~ normal(.45, .05);
}

在参数之间创建约束的一个简单解决方案是将一个参数表示为另一个参数的变换。此解决方案使事情变得非常简单和灵活:

experiment.stan

data {
 }
parameters {
  real y1;
}
transformed parameters {
  real y2;
  y2 = 4-y1;
}
model {  
  y1 ~ normal(1.8,0.2);
  y2 ~ normal(1.8,0.2);
}