0

下面的代码提供了一个完整的可重现示例。我的问题(主要)是关于我的功能thetaMax()。这是一个最小化心理测量过程的对数似然的函数。

我正在学习 Python,并通过将我的 R 函数转换为 python 来做到这一点。下面的代码按预期工作。但是,因为我正在学习 Python,但我的问题是关于风格和质量。

该函数thetaMax将运行在数十万人之上,并且在我的 R 代码中是高效的,并且在多个核心之间进行拆分。但是,在考虑并行处理之前,我的第一个目标是让 Python 代码尽可能快速高效。

我的功能可能有很多部分thetaMax可以改进,但我最关心的一个方面是:

for i in range(0,len(x2)):
     result[i] = (gpcm(theta, d = d[i], score = x2[i], a = 1, D = D))

我认为这样做作为一个循环可能很糟糕,并且可以通过某种形式的矢量化来改进。以下是实现此代码所需的完整内容,感谢任何愿意就如何改进代码提供建议的人。

import numpy as np
from scipy.stats import binom
from scipy.optimize import minimize

def prob3pl(theta, a, b, c, D = 1.7):
    result = c + (1 - c) / (1 + np.exp(-D * a * (theta - b)))
    return(result)


def gpcm(theta, d, score, a, D = 1.7):
    Da = D * a
    result = np.exp(np.sum(Da * (theta - d[0:score])))/np.sum(np.exp(np.cumsum(Da * (theta - d))))
    return(result)

d = np.array([[0, -1, .5, 1],[0,-.5,.2,1]])
a = np.array([1,1,1,1,1])
b = np.array([-1,.5,-.5,0,2])
c = np.array([0,0,0,0,0])
x = np.array([1,1,0,1,0,1,1])
indDichot = range(0,5,1)

def thetaMax(x, indDichot, a, b, c, D, d):
    x1 = x[indDichot]
    x2 = np.delete(x, indDichot)
    result = [0] * len(x2)
    def fn(theta):
        if(len(x1) > 0):
            p = prob3pl(theta, a, b, c, D = D)
            logDichPart = sum(np.log(binom.pmf(x1,1,p)))
        else:
            logPolyPart = 0
        if(len(x2) > 0):
            for i in range(0,len(x2)):
                result[i] = (gpcm(theta, d = d[i], score = x2[i], a = 1, D = D))
            logPolyPart = sum(np.log(result))
        else:
            logPolyPart = 0
        LL = -(logDichPart + logPolyPart)
        return(LL)
    out = minimize(fn, x0=0)
    return(out)


thetaMax(x,indDichot,a,b,c,D=1,d = d)
4

0 回答 0