Я хотел бы оценить модель модели ответа на вопрос (IRT) в Python. В частности, возьмите канонический пример IRT для студентов, сдающих экзамен. Для каждого ученика мы наблюдаем, правильно ли ответили на вопросы, которые они ответили на экзамене. Это дает нам наблюдаемую матрицу результатов X, из которой по каждому вопросу мы хотели бы оценить (1) параметр трудности α и (2) параметр дискриминации β, чтобы мы могли также оценить каждую скрытую способность Y студентов как функцию того, получил правильный ответ или нет по каждому тестовому вопросу, т.е. α + βX. Лучший пример, который я мог найти, как оценить этот тип байесовской модели IRT с использованием MCMC в Python, - это example. То, что я не понимаю из этого примера, - это то, где матрица X, независимо от того, получил ли ученик правильный ответ на тестовый вопрос, входит в модель. Вот немного измененный вариант этого кода, предназначенный для оценки скрытой способности каждого студента:Байесовская модель IRT в Python с использованием pymc
#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
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.zeros_like(1.0/(1.0 + exp(bs - dot(a, theta)))) #np.zeros_like fixes error
# 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
Когда я запускаю сценарий, я получаю сообщение об ошибке:
pymc.Node.ZeroProbability: Stochastic correct's value is outside its support,
or it forbids its parents' current values.`
, который восходит к линии :
correct = Bernoulli('correct', p=sigmoid, value=correctness, observed=not generating)
Я проверил оригинальный сценарий (который переключает между генерацией результатов от скрытых значений и вычисления латентных значений из результатов) и correctness
в который, как я думал, является матрицей X результатов испытаний, описанных выше, заполнен значениями False
. Когда я устанавливаю correctness
, чтобы быть заполненным значениями False
, тогда скрипт завершается. Тем не менее, это, казалось бы, говорит, что каждый студент получил каждый вопрос неправильно, что не имело бы большого смысла. Я подумал, что это может быть правильный ответ на вопрос, поэтому я установил все значения в correctness
в True
, но это привело к той же ошибке. Что я делаю неправильно, и как я могу оценить скрытую способность с использованием модели IRT из матрицы X того, получил ли ученик правильный ответ на тестовый вопрос, используя pymc?
Спасибо! Я копировал код из другого файла (копии исходного кода), который не воспроизводится. Я, должно быть, сделал «import numpy as np» в терминале и никогда не перезапускал файл, а просто передал его интерпретатору. Я согласен, что импорт всего с '*', как правило, является плохим. В основном артефакт примера, над которым я работал. – Michael