在 pymc 中标准化贝叶斯 IRT 模型

Normalizing Bayesian IRT Model in pymc

我能找到的关于如何在 Python 中使用 MCMC 估计此类 IRT 贝叶斯模型的最佳示例是 example。下面是我得到的代码的可重现版本 运行。我的理解是,为了识别模型,能力参数 theta 被限制为均值为 0、标准差为 1 的正态分布,我认为这是通过以下代码中的这一行完成的:

# theta (proficiency params) are sampled from a normal distribution
theta = Normal("theta", mu=0, tau=1, value=theta_initial, observed= generating)

但是,当我 运行 代码时,theta 的后验均值类似于 1.85e18,标准偏差更大,即不表示零和标准偏差 1。为什么我会收到此错误和我如何确保在每次迭代后将 theta 归一化为 0,sd 1?

#from pylab import * #Pylab will not install with pip so I just loaded numpy itself
from numpy import *
import numpy
from pymc import *
from pymc.Matplot import plot as mplot
import numpy as np

numquestions = 300 # number of test items being simulated
numpeople = 10 # number of participants
numthetas = 1 # number of latent proficiency variables

generating = 0
theta_initial = zeros((numthetas, numpeople))
correctness = np.random.randint(2, size= numquestions * numpeople) == 1 #Produces Error
#correctness = np.random.randint(2, size= numquestions * numpeople) == -1 #all False code runs fine
#correctness = np.random.randint(2, size= numquestions * numpeople) != -1 #all True code throws error message

correctness.shape = (numquestions, numpeople)


# theta (proficiency params) are sampled from a normal distribution
theta = Normal("theta", mu=0, tau=1, value=theta_initial, observed= generating)


# question-parameters (IRT params) are sampled from normal distributions (though others were tried)
a = Normal("a", mu=1, tau=1, value=[[0.0] * numthetas] * numquestions)
# a = Exponential("a", beta=0.01, value=[[0.0] * numthetas] * numquestions)
b = Normal("b", mu=0, tau=1, value=[0.0] * numquestions)

# take vectors theta/a/b, return a vector of probabilities of each person getting each question correct
@deterministic
def sigmoid(theta=theta, a=a, b=b): 
    bs = repeat(reshape(b, (len(b), 1)), numpeople, 1)
    return np.exp(1.0 / (1.0 + np.exp(bs - dot(a, theta))))

# take the probabilities coming out of the sigmoid, and flip weighted coins
correct = Bernoulli('correct', p=sigmoid, value=correctness, observed=not generating)

# create a pymc simulation object, including all the above variables
m = MCMC([a,b,theta,sigmoid,correct])

# run an interactive MCMC sampling session
m.isample(iter=20000, burn=15000)


mydict = m.stats()
print(mydict['theta']['mean']) #Get ability parameters for each student
print(mydict['theta']['mean'].mean()) #Should be zero, but returns something link 1.85e18, i.e. an absurdly large value.

我认为你的 sigmoid 函数中有一个额外的 n.exp。根据wikipediaS(t) = 1 / (1 + exp(-t))。我用这个替代版本替换了你的第 34 行:

return 1.0 / (1.0 + np.exp(bs - dot(a, theta)))

有了这个,我得到了 0.08 的 theta 平均值。