Esempio n. 1
0
def L_dL_singleuser(arg):
    """ calculate log likelihood and gradient wrt couplings of mIRT model
        for single user """
    couplings, state, options = arg
    abilities = state['abilities'].copy()
    correct = state['correct']
    exercises_ind = state['exercises_ind']

    # pad the abilities vector with a 1 to act as a bias
    abilities = np.append(abilities.copy(),
                          np.ones((1, abilities.shape[1])),
                          axis=0)
    # the abilities to exercise coupling parameters for this exercise
    exercise_couplings = couplings[exercises_ind, :]

    # calculate the probability of getting a question in this exercise correct
    Y = np.dot(exercise_couplings, abilities)
    Z = mirt_util.sigmoid(Y)  # predicted correctness value
    Zt = correct.reshape(Z.shape)  # true correctness value
    pdata = Zt * Z + (1 - Zt) * (1 - Z)  # = 2*Zt*Z - Z + const
    dLdY = ((2 * Zt - 1) * Z * (1 - Z)) / pdata
    dL = np.dot(dLdY, abilities.T)
    dL /= np.log(2.)

    L = np.sum(np.log(pdata))
    L /= np.log(2.)

    return -L, -dL, exercises_ind
Esempio n. 2
0
def L_dL_singleuser(arg):
    """ calculate log likelihood and gradient wrt couplings of mIRT model
        for single user """
    theta, state, options = arg

    abilities = state['abilities'].copy()
    correct = state['correct']
    exercises_ind = state['exercises_ind']

    dL = mirt_util.Parameters(theta.num_abilities, len(exercises_ind))

    # pad the abilities vector with a 1 to act as a bias
    abilities = np.append(abilities.copy(),
                          np.ones((1, abilities.shape[1])),
                          axis=0)
    # the abilities to exercise coupling parameters for this exercise
    W_correct = theta.W_correct[exercises_ind, :]

    # calculate the probability of getting a question in this exercise correct
    Y = np.dot(W_correct, abilities)
    Z = mirt_util.sigmoid(Y)  # predicted correctness value
    Zt = correct.reshape(Z.shape)  # true correctness value
    pdata = Zt * Z + (1. - Zt) * (1. - Z)  # = 2*Zt*Z - Z + const
    dLdY = ((2. * Zt - 1.) * Z * (1. - Z)) / pdata

    L = -np.sum(np.log(pdata))
    dL.W_correct = -np.dot(dLdY, abilities.T)

    if not options.correct_only:
        # calculate the probability of taking time response_time to answer
        log_time_taken = state['log_time_taken']
        # the abilities to time coupling parameters for this exercise
        W_time = theta.W_time[exercises_ind, :]
        sigma = theta.sigma_time[exercises_ind].reshape((-1, 1))
        Y = np.dot(W_time, abilities)
        err = (Y - log_time_taken.reshape((-1, 1)))
        L += np.sum(err ** 2 / sigma ** 2) / 2.
        dLdY = err / sigma ** 2

        dL.W_time = np.dot(dLdY, abilities.T)
        dL.sigma_time = (-err ** 2 / sigma ** 3).ravel()

        # normalization for the Gaussian
        L += np.sum(0.5 * np.log(sigma ** 2))
        dL.sigma_time += 1. / sigma.ravel()

    return L, dL, exercises_ind
Esempio n. 3
0
def L_dL_singleuser(arg):
    """ calculate log likelihood and gradient wrt couplings of mIRT model
        for single user """
    theta, state, options = arg

    abilities = state['abilities'].copy()
    correct = state['correct']
    exercises_ind = state['exercises_ind']

    dL = mirt_util.Parameters(theta.num_abilities, len(exercises_ind))

    # pad the abilities vector with a 1 to act as a bias
    abilities = np.append(abilities.copy(),
                          np.ones((1, abilities.shape[1])),
                          axis=0)
    # the abilities to exercise coupling parameters for this exercise
    W_correct = theta.W_correct[exercises_ind, :]

    # calculate the probability of getting a question in this exercise correct
    Y = np.dot(W_correct, abilities)
    Z = mirt_util.sigmoid(Y)  # predicted correctness value
    Zt = correct.reshape(Z.shape)  # true correctness value
    pdata = Zt * Z + (1. - Zt) * (1. - Z)  # = 2*Zt*Z - Z + const
    dLdY = ((2. * Zt - 1.) * Z * (1. - Z)) / pdata

    L = -np.sum(np.log(pdata))
    dL.W_correct = -np.dot(dLdY, abilities.T)

    if not options.correct_only:
        # calculate the probability of taking time response_time to answer
        log_time_taken = state['log_time_taken']
        # the abilities to time coupling parameters for this exercise
        W_time = theta.W_time[exercises_ind, :]
        sigma = theta.sigma_time[exercises_ind].reshape((-1, 1))
        Y = np.dot(W_time, abilities)
        err = (Y - log_time_taken.reshape((-1, 1)))
        L += np.sum(err ** 2 / sigma ** 2) / 2.
        dLdY = err / sigma ** 2

        dL.W_time = np.dot(dLdY, abilities.T)
        dL.sigma_time = (-err ** 2 / sigma ** 3).ravel()

        # normalization for the Gaussian
        L += np.sum(0.5 * np.log(sigma ** 2))
        dL.sigma_time += 1. / sigma.ravel()

    return L, dL, exercises_ind