我正在尝试在Python中重新实现以下代码: http://www.wordfish.org/uploads/1/2/9/8/12985397/wordfish_1.3.r
但是,我在移植优化(最大化)功能时很挣扎。 我编写了一个代码段,并制作了两个简单的示例,它们应该产生相同的结果:
R:
omega = c(0)
y = c(18, 24, 23, 27, 24, 5, 7, 5, 4, 7, 64, 59, 66, 51, 50, 11, 17, 9, 13, 16)
b = c(-0.5047485, -0.6346391, -0.375262, -0.4550382, -0.4839501, 0.3181721, 0.4557756, 0.5618271, 0.3847818, 0.485241, -0.4500023, -0.4224367, -0.461969, -0.5605062, -0.4635604, 0.4995454, 0.5027968, 0.5656253, 0.5506545, 0.5368292 )
psi = c(2.653242, 2.687847, 2.564949, 2.61007, 2.694627, 2.533697, 2.60269, 2.564949, 2.60269, 2.631889, 3.65584, 3.632309, 3.591818, 3.572346, 3.605498, 3.580737, 3.54674, 3.569533, 3.624341, 3.538057)
llik_alpha_1 <- function(y,p,b,psi) {
omega <- p[1]
lambda<-exp(psi+b*omega)
-sum(-lambda+log(lambda)*y)
}
resa <- optim(p=omega,
fn=llik_alpha_1,
y=y,
b=b,
psi=psi,
method=c("BFGS")
)
resa
llik_alpha_1(y,omega,b,psi)
R的结果:
$par
-1.15535372895012
$value
-1249.36539272541
$counts
function
11
gradient
4
$convergence
0
$message
NULL
-1162.28778073828
Python:
omega = np.array([0])
y = np.array([18, 24, 23, 27, 24, 5, 7, 5, 4, 7, 64, 59, 66, 51, 50, 11, 17, 9, 13, 16])
b = np.array([-0.5047485, -0.6346391, -0.375262, -0.4550382, -0.4839501, 0.3181721, 0.4557756, 0.5618271, 0.3847818, 0.485241, -0.4500023, -0.4224367, -0.461969, -0.5605062, -0.4635604, 0.4995454, 0.5027968, 0.5656253, 0.5506545, 0.5368292])
psi = np.array([2.653242, 2.687847, 2.564949, 2.61007, 2.694627, 2.533697, 2.60269, 2.564949, 2.60269, 2.631889, 3.65584, 3.632309, 3.591818, 3.572346, 3.605498, 3.580737, 3.54674, 3.569533, 3.624341, 3.538057])
def llik_alpha_1(y,p,b,psi):
omega = p
lambda_1 = np.exp(psi+b*omega)
return -np.sum(-lambda_1+np.log(lambda_1)*y)
resa = minimize(fun=llik_alpha_1,
args=(omega, b, psi),
x0 = y,
method='BFGS'
)
print(resa)
llik_alpha_1(y, omega, b, psi)
Python的结果:
fun: -1269762128.486976
hess_inv: array([[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]])
jac: array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0.])
message: 'Optimization terminated successfully.'
nfev: 330
nit: 1
njev: 15
status: 0
success: True
x: array([17066136.98700089, 17288740.69846503, 16498164.49306662,
16788487.73050529, 17332318.02822256, 16297239.29934215,
16740964.51518402, 16498244.64020571, 16740961.51518402,
16928818.13940904, 23515038.90828061, 23363691.01979838,
23103313.65978324, 22978062.91029989, 23191237.49641104,
23032003.83680133, 22813239.86376185, 22959863.68956758,
23312412.21319156, 22757393.14161763])
-1162.2877807382822
如您所见,两个优化函数的结果均返回-1162.28778073828,但优化器的结果完全不同。
有人可以解释我错在哪里吗?我猜想Python中的优化与R中的优化有所不同,但我不是专家...
谢谢您,并致以诚挚的问候!
迈克尔
编辑//解决方案: 如果有人感兴趣,我发现了我的错误 以下Python代码返回相同的结果:
omega = np.array([0])
y = np.array([18, 24, 23, 27, 24, 5, 7, 5, 4, 7, 64, 59, 66, 51, 50, 11, 17, 9, 13, 16])
b = np.array([-0.5047485, -0.6346391, -0.375262, -0.4550382, -0.4839501, 0.3181721, 0.4557756, 0.5618271, 0.3847818, 0.485241, -0.4500023, -0.4224367, -0.461969, -0.5605062, -0.4635604, 0.4995454, 0.5027968, 0.5656253, 0.5506545, 0.5368292])
psi = np.array([2.653242, 2.687847, 2.564949, 2.61007, 2.694627, 2.533697, 2.60269, 2.564949, 2.60269, 2.631889, 3.65584, 3.632309, 3.591818, 3.572346, 3.605498, 3.580737, 3.54674, 3.569533, 3.624341, 3.538057])
def llik_alpha_1(p,y,b,psi):
lambda_1 = np.exp(psi+b*p)
return -np.sum(-lambda_1+np.log(lambda_1)*y)
resa = minimize(fun=llik_alpha_1,
args=(y, b, psi),
x0 = omega,
method='BFGS'
)
print(resa)
llik_alpha_1(omega, y, b, psi)
问题是,我混合了变量(ω和y)。 x0是要优化的参数,在我的情况下是omega而不是y。