我正在研究的模型是一个多项logit选择模型 . 这是一个非常具体的数据集,因此其他现有的MNLogit库不适合我的数据 .

所以基本上,它是一个非常复杂的函数,它接受11个参数并返回对数似然值 . 然后我需要找到可以使用scipy.optimize.minimize最小化对数似然的最佳参数值 .

以下是我遇到的不同方法的问题:

'Nelder-Mead':效果很好,总能给我正确答案 . 但是,它非常慢 . 对于具有更复杂设置的另一功能,需要15个小时才能达到最佳点 . 同时,相同的功能在Matlab上使用fminunc只需1小时(默认情况下使用BFGS)

'BFGS':这是Matlab使用的方法 . 它适用于任何简单的功能 . 但是,对于我所拥有的功能,它始终无法收敛并返回“由于精度损失而无法实现所需的错误” . 我花了很多时间玩这些选项但仍未能奏效 .

'Powell':它快速收敛成功,但返回错误的答案 . 代码打印在下面(x0是正确答案,Nelder-Mead适用于任何初始值),您可以在此处获取数据:https://www.dropbox.com/s/aap2dhor5jyxy94/data.csv

谢谢!

import pandas as pd
import numpy as np
from scipy.optimize import minimize

# https://www.dropbox.com/s/aap2dhor5jyxy94/data.csv
df = pd.read_csv('data.csv', index_col=0)
dfhh = df.hh
B = df.ix[:,'b0':'b4'].values # NT*5
P = df.ix[:,'p1':'p4'].values # NT*4
F = df.ix[:,'f1':'f4'].values # NT*4
SDV = df.ix[:,'lagb1':'lagb4'].values

def Li(x):
    b1 = x[0] # coeff on prices
    b2 = x[1] # coeff on features
    a = x[2:7] # take first 4 values as alpha
    E = np.exp(a + b1*P + b2*F) # (1*4) + (NT*4) + (NT*4) build matrix (NT*J) for each exp()
    E = np.insert(E, 0, 1, axis=1) # (NT*5)
    denom = E.sum(1)
    return -np.log((B * E).sum(1) / denom).sum()


x0 = np.array([-32.31028223, 0.23965953, 0.84739154, 0.25418215,-3.38757007,-0.38036966])
np.random.seed(0)
x0 = x0 + np.random.rand(6)

 minL = minimize(Li, x0, method='Nelder-Mead',options={'xtol': 1e-8, 'disp': True})
# minL = minimize(Li, x0, method='BFGS')
# minL = minimize(Li, x0, method='Powell', options={'xtol': 1e-12, 'ftol': 1e-12})
print minL

更新时间:03/07/14更简单的代码版本现在Powell的耐受性非常小,但在这种情况下,Powell的速度比Nelder-Mead慢 . BFGS仍然无法正常工作 .