Будет ли JAGS оценивать все родительские узлы dcat или только нужный?

Скажем, у нас есть следующее утверждение:

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 неэффективно оценивает все родительские узлы, потому что моя модель была ускорена в 3 раза после того, как я избавился от dcat. Мне пришлось использовать несколько циклов for для разных результатов Y[i].

Теперь я понял, что dcat в JAGS на самом деле не требует этого sum(pi[]) = 1, и что dcat нормализует pi[] так, чтобы его сумма равнялась 1. Это означает, что он должен оценивать все узлы.

Это очень печально. Есть ли интеллектуальный эквивалент dcat, который будет оценивать только один необходимый родительский узел? А как насчет WinBUGS и Stan?


person Tomas    schedule 27.11.2014    source источник


Ответы (2)


В вашем примере недостаточно подробностей, чтобы я мог ответить. Я добавил несколько выражений в правой части:

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,])
}

Предположим, мы обновляем альфа узла, тогда сэмплер, отвечающий за обновление альфа, должен оценить funx(alpha) и funy(alpha), но не funz(beta) или funw(beta) (при условии, что бета не является детерминированной функцией альфа). Таким образом, в этом случае оцениваются 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, но в некоторых будущих версиях это можно будет сделать.

person Martyn Plummer    schedule 28.11.2014
comment
Дорогой Мартин! Спасибо за ответ. Нет-нет-нет, ни кеширования, ни обновления, я не это имел в виду. Моя идея была очень проста. dcat можно было бы доверять пользователю, достаточно умному, чтобы указать pi[], сумма которого будет равна 1. В этом случае обработка модели может быть намного быстрее: например, если Y[1] = 5, нужно будет оценивать только pi[1, 5], а все остальные 99 pi[1,] узлов будут не надо! Нынешняя dcat этого не сделает, модели с ней очень медленные. Теперь понятно, что я имею в виду? Пожалуйста, спросите меня, если нет. Так вот, мой вопрос, есть ли у вас такая смарт версия dcat в JAGS? - person Tomas; 28.11.2014
comment
Мне нужен полностью воспроизводимый пример, чтобы понять, какую оптимизацию вы хотите. - person Martyn Plummer; 01.12.2014

Я думаю, вы можете сделать то, о чем просите, просто используя dbern, то есть:

for(i in 1:N){
    pi[i,1] <- ...
    ...
    pi[i,100] <- ...

    Ones[i] ~ dbern(pi[i,Y[i])
}

Где Ones[] указывается в данных как вектор длины N, равный 1.

Тем не менее, все pi[] все равно будет вычислено — это должно быть так, потому что это узел в вашей модели, а JAGS (или WinBUGS/stan) не может сказать, какие узлы вам нужны, а какие нет. Вы можете избежать этого, имея одно значение pi[] для каждого i и смещая использование индекса Y[i] внутри правой части уравнения pi[i] - хотя, как говорит Мартин, ваш пример не t дать достаточно подробностей, чтобы определить, возможно ли это.

Мэтт

person Matt Denwood    schedule 30.11.2014