0

假设我们有以下语句:

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 倍。我必须使用多个 for 循环来处理不同的结果Y[i]

现在我意识到,dcat在 JAGS 中实际上不需要sum(pi[]) = 1,并且dcat它将归一化pi[]以使其总和为 1。这意味着它必须评估所有节点。

这是非常可悲的。是否有任何智能等价物dcat只会评估唯一需要的一个父节点?WinBUGS 和斯坦呢?

4

2 回答 2

0

你的例子没有足够的细节让我回答。我在右侧添加了一些表达式:

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)andfuny(alpha)而不是funz(beta)or funw(beta)(假设 beta 不是 alpha 的确定性函数)。所以在这种情况下pi[i,1]andpi[i,1]被评估但不是pi[i,3]or 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 中不可用,但在未来的某些版本中可能会朝着这个方向努力。

于 2014-11-28T18:13:00.050 回答
-1

我认为您只需使用 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)无法告诉您关心哪些节点,不关心哪些节点。您可以通过为每个 i 设置一个 pi[] 值并在 pi[i] 方程的右侧移动 Y[i] 索引的使用来避免这种情况 - 尽管正如 Martyn 所说,您的示例没有t 提供足够的细节来确定这是否可能。

马特

于 2014-11-30T15:59:18.817 回答