在JAGS中运行逻辑模型 - 您可以进行矢量化而不是循环遍历各个案例吗?

时间:2015-09-06 02:43:49

标签: bayesian jags

我对JAGS很新,所以这可能是一个愚蠢的问题。我正在尝试在JAGS中运行一个模型来预测一维随机游走过程在越过边界B之前越过边界A的概率。这个模型可以通过以下逻辑模型进行分析求解:

Pr(A,B)= 1 /(1 + exp(-2 *(d / sigma)* theta))

其中“d”是平均漂移率(正值表示向边界A漂移),“sigma”是该漂移率的标准偏差,“theta”是起点和边界之间的距离(假设为两个边界相等)。

我的数据集由50位参与者组成,每位参与者提供1800次观察。我的模型假设d是由观察到的环境变量(我称之为'x')的特定组合决定的,以及与x相关的加权系数(我称之为'beta')。因此,有三个参数:beta,sigma和theta。我想为每个参与者估算一组参数。我的目的是最终运行一个分层模型,其中组级参数影响各个级别的参数。但是,为简单起见,我在这里只考虑一个模型,其中我估计一个参与者的一组参数(因此模型不是分层的)。

rjags中的模型如下:

model{
for ( i in 1:Ntotal ) {   
 d[i] <- x[i] * beta
 probA[i] <- 1/(1+exp(-2 * (d[i]/sigma) * theta )   )
 y[i] ~ dbern(probA[i])    
 }

 beta ~ dunif(-10,10)
 sigma ~ dunif(0,10)
 theta ~ dunif(0,10)
}

此模型运行正常,但需要很长时间才能运行。我不确定JAGS是如何执行代码的,但是如果这个代码是在R中运行的话,那将是相当低效的,因为它必须循环遍历案例,为每个案例单独运行模型。因此,随着样本量的增加,运行分析所需的时间将迅速增加。我有一个相当大的样本,所以这是一个问题。

有没有办法对这段代码进行矢量化,以便它可以一次计算所有数据点的可能性?例如,如果我将其作为简单的最大似然模型运行。我将对模型进行矢量化并计算给定参与者提供的所有1800个案例的特定参数值的数据概率(因此不需要for循环)。然后,我将记录这些可能性,并将它们全部加在一起,为参与者给出的所有观察结果提供单一的可能性。这种方法可以节省大量时间。有没有办法在JAGS中做到这一点?

修改

感谢您的回复,并指出我展示的模型中的参数可能未被识别。我应该指出模型是一个简化版本。完整模型如下:

model{
  for ( i in 1:Ntotal ) {
    aExpectancy[i] <- 1/(1+exp(-gamma*(aTimeRemaining[i] - aDiscrepancy[i]*aExpectedLag[i]) ) )
    bExpectancy[i] <- 1/(1+exp(-gamma*(bTimeRemaining[i] - bDiscrepancy[i]*bExpectedLag[i]) ) )
    aUtility[i] <- aValence[i]*aExpectancy[i]/(1 + discount * (aTimeRemaining[i]))
    bUtility[i] <- bValence[i]*bExpectancy[i]/(1 + discount * (bTimeRemaining[i]))
    aMotivationalValueMean[i] <- aUtility[i]*aQualityMean[i]
    bMotivationalValueMean[i] <- bUtility[i]*bQualityMean[i]
    aMotivationalValueVariance[i] <- (aUtility[i]*aQualitySD[i])^2 + (bUtility[i]*bQualitySD[i])^2
    bMotivationalValueVariance[i] <- (aUtility[i]*aQualitySD[i])^2 + (bUtility[i]*bQualitySD[i])^2
    mvDiffVariance[i] <- aMotivationalValueVariance[i] + bMotivationalValueVariance[i]
    meanDrift[i] <- (aMotivationalValueMean[i] - bMotivationalValueMean[i])
    probA[i] <- 1/(1+exp(-2*(meanDrift[i]/sqrt(mvDiffVariance[i])) *theta ) )
    y[i] ~ dbern(probA[i])
  }

在此模型中,估算的参数为thetadiscountgamma,并且可以恢复这些参数。当我在单个参与者(Ntotal = 1800)的观察上运行模型时,模型运行大约需要5分钟,这完全没问题。然而,当我在整个样本上运行模型时(45个参与者×每个1800个案例= 78,900个观察点),我已经让它运行了24小时,并且不到50%。这看起来很奇怪,因为我预计它只需要45倍的时间,所以最多需要4或5个小时。我错过了什么吗?

2 个答案:

答案 0 :(得分:2)

你不能像在R中那样进行矢量化,但是如果你能用相同的概率表达式对观测进行分组(即常见的d [i]),那么你可以使用二项式而不是伯努利分布。会有很大的帮助。如果每个观察都有一个独特的d [i]那么你就会被困住,我很害怕。

另一种选择是看看Stan,这对于像你这样的大型数据集来说通常会更快。

马特

答案 1 :(得分:0)

感谢您的回复。是的,您明确指出我所展示的模型中的参数可能未被识别。

我应该指出模型是一个简化版本。完整模型如下:

model{
  for ( i in 1:Ntotal ) {  

    aExpectancy[i] <- 1/(1+exp(-gamma*(aTimeRemaining[i] - aDiscrepancy[i]*aExpectedLag[i]) ) )
    bExpectancy[i] <- 1/(1+exp(-gamma*(bTimeRemaining[i] - bDiscrepancy[i]*bExpectedLag[i]) ) )

    aUtility[i] <- aValence[i]*aExpectancy[i]/(1 + discount * (aTimeRemaining[i]))
    bUtility[i] <- bValence[i]*bExpectancy[i]/(1 + discount * (bTimeRemaining[i]))

    aMotivationalValueMean[i] <- aUtility[i]*aQualityMean[i]
    bMotivationalValueMean[i] <- bUtility[i]*bQualityMean[i]
    aMotivationalValueVariance[i] <- (aUtility[i]*aQualitySD[i])^2 + (bUtility[i]*bQualitySD[i])^2
    bMotivationalValueVariance[i] <- (aUtility[i]*aQualitySD[i])^2 + (bUtility[i]*bQualitySD[i])^2

    mvDiffVariance[i] <- aMotivationalValueVariance[i] + bMotivationalValueVariance[i]
    meanDrift[i] <- (aMotivationalValueMean[i] - bMotivationalValueMean[i])
    probA[i] <- 1/(1+exp(-2*(meanDrift[i]/sqrt(mvDiffVariance[i])) *theta )   )
    y[i] ~ dbern(probA[i])    

  }

  theta ~ dunif(0,10)  
  discount ~ dunif(0,10)
  gamma ~ dunif(0,1)
}

在此模型中,估算的参数为thetadiscountgamma,并且可以恢复这些参数。

当我在单个参与者(Ntotal = 1800)的观察上运行模型时,模型运行大约需要5分钟,这完全没问题。

然而,当我在整个样本上运行模型时( 45个参与者X 1800个案例= 78,900个观察),我已经让它运行了24个小时,它不到50%通过。

这看起来很奇怪,因为我预计它只需要45倍的时间,所以最多需要4到5个小时。我错过了什么吗?