下面的代码提供了一个完整的可重现示例。我的问题(主要)是关于我的功能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)