说我们有以下声明:
for (i in 1:N) {
pi[i,1] <- ....
pi[i,2] <- ....
pi[i,3] <- ....
...
pi[i,100] <- ...
Y[i] ~ dcat(p[i,])
}
让我们说Y[1] = 5
。 jags会评估所有pi[1,1:100]
个节点,还是唯一需要的节点,即pi[1,5]
?
根据我的经验,似乎JAGS无法有效地评估所有父节点,因为我的模型在我摆脱了dcat之后加速了3倍。对于Y[i]
的不同结果,我必须使用多个for循环。
现在我意识到JAGS中的dcat
实际上并不需要sum(pi[]) = 1
,而dcat
会将pi[]
标准化,以便它总和为1。表示必须评估所有节点。
这很难过。 是否有任何智能等效的dcat
仅评估所需的唯一一个父节点? WinBUGS和Stan怎么样?
答案 0 :(得分:0)
你的exampled没有足够的细节供我回答。我在右侧添加了一些表达式:
for (i in 1:N) {
pi[i,1] <- funx(alpha)
pi[i,2] <- funy(alpha)
pi[i,3] <- funz(beta)
...
pi[i,100] <- funw(beta)
Y[i] ~ dcat(p[i,])
}
假设我们正在更新节点alpha,那么负责更新alpha的采样器需要评估funx(alpha)
和funy(alpha)
而不是funz(beta)
或funw(beta)
(假设beta不是alpha的确定性函数。因此,在这种情况下,会pi[i,1]
和pi[i,1]
进行评估,但不会pi[i,3]
或pi[i,100]
。这些其他节点保留其当前值。
但是,对于可能性计算,我们必须取消引用所有节点p[i,1]
到p[i,100]
的当前值,以计算总和并标准化p。解除引用很便宜,但如果你做得足够多,那么它会变得昂贵。例如,如果你有
for (i in 1:N) {
for (j in 1:M) {
pi[i,j] ~ dexp(1)
}
Y[i] ~ dcat(p[i,])
}
然后你每次迭代都会N*M*M
解除引用操作,这很快就会加起来。
所以我猜你要求的是一个采样器,它为可能性计算缓存p[i,]
的总和,然后仅根据已更改的元素更新它,避免需要取消引用其他元素。这在JAGS中不可用,但在未来的某些版本中可能会有用。
答案 1 :(得分:0)
我认为你可以通过使用dbern来做你所要求的,即:
for(i in 1:N){
pi[i,1] <- ...
...
pi[i,100] <- ...
Ones[i] ~ dbern(pi[i,Y[i])
}
其中Ones []在数据中指定为1的N长度向量。
然而,仍然会计算所有的pi [] - 它必须是因为它是模型中的一个节点,并且JAGS(或WinBUGS / stan)无法告诉您关心哪个节点以及哪些节点和#39;吨。您可以通过为每个i设置一个pi []值并在pi [i]等式的右侧移动Y [i]索引来避免这种情况 - 尽管Martyn说你的例子不是&# 39;给出足够的细节以确定是否可行。
马特