我有以下潜变量模型: Person j 有两个潜变量 X j1和 X j2。我们唯一能观察到的是它们的最大值,Y j = max(X j1 , X j2 )。潜变量是二元正态的;它们每个都有均值 mu、方差 sigma 2,并且它们的相关性是 rho。我想仅使用 Y j估计三个参数(mu、sigma 2、rho),数据来自 n 个患者,j = 1,...,n。
我试图在 JAGS 中拟合这个模型(所以我将先验放在参数上),但我无法编译代码。这是我用来调用 JAGS 的 R 代码。首先,在给定参数的一些真实值的情况下,我生成数据(潜在变量和观察变量):
# true parameter values
mu <- 3
sigma2 <- 2
rho <- 0.7
# generate data
n <- 100
Sigma <- sigma2 * matrix(c(1, rho, rho, 1), ncol=2)
X <- MASS::mvrnorm(n, c(mu,mu), Sigma) # n-by-2 matrix
Y <- apply(X, 1, max)
然后我定义了 JAGS 模型,并编写了一个小函数来运行 JAGS 采样器并返回样本:
# JAGS model code
model.text <- '
model {
for (i in 1:n) {
Y[i] <- max(X[i,1], X[i,2]) # Ack!
X[i,1:2] ~ dmnorm(X_mean, X_prec)
}
# mean vector and precision matrix for X[i,1:2]
X_mean <- c(mu, mu)
X_prec[1,1] <- 1 / (sigma2*(1-rho^2))
X_prec[2,1] <- -rho / (sigma2*(1-rho^2))
X_prec[1,2] <- X_prec[2,1]
X_prec[2,2] <- X_prec[1,1]
mu ~ dnorm(0, 1)
sigma2 <- 1 / tau
tau ~ dgamma(2, 1)
rho ~ dbeta(2, 2)
}
'
# run JAGS code. If latent=FALSE, remove the line defining Y[i] from the JAGS model
fit.jags <- function(latent=TRUE, data, n.adapt=1000, n.burnin, n.samp) {
require(rjags)
if (!latent)
model.text <- sub('\n *Y.*?\n', '\n', model.text)
textCon <- textConnection(model.text)
fit <- jags.model(textCon, data, n.adapt=n.adapt)
close(textCon)
update(fit, n.iter=n.burnin)
coda.samples(fit, variable.names=c("mu","sigma2","rho"), n.iter=n.samp)[[1]]
}
最后,我调用 JAGS,只提供观察到的数据:
samp1 <- fit.jags(latent=TRUE, data=list(n=n, Y=Y), n.burnin=1000, n.samp=2000)
遗憾的是,这会导致错误消息:“Y[1] 是一个逻辑节点,无法观察到”。JAGS 不喜欢我使用“<-”为 Y[i] 赋值(我用“Ack!”表示违规行)。我理解投诉,但我不知道如何重写模型代码来解决这个问题。
此外,为了证明其他一切(除了“Ack!”行)都很好,我再次运行模型,但这次我将 X 数据输入它,假装它确实被观察到了。这运行得很好,我得到了很好的参数估计:
samp2 <- fit.jags(latent=FALSE, data=list(n=n, X=X), n.burnin=1000, n.samp=2000)
colMeans(samp2)
如果你能找到一种方法在 STAN 而不是 JAGS 中对这个模型进行编程,那对我来说很好。