Python - 条件logit模型的溢出问题

时间:2016-05-15 12:47:52

标签: python overflow mlogit

这是我关于堆栈溢出的第一篇文章,所以请放纵!

我正在尝试为多项(或条件)logit模型开发代码(如http://data.princeton.edu/wws509/notes/c6s3.html中所述) 这种类型的模型可以看作是经典二元逻辑回归的扩展。多项logit模型经常用于离散选择建模。

在下面的代码中,我描述了一个模型,解释了当所有参与者(N)面对相同的选择问题(T)时两个选项(J)之间的选择。我已经为R开发了类似的代码,它运行得非常好,但是很慢(因为“优化”例程)。由于溢出问题,使用PYTHON开发此类代码似乎更加困难。第一个操作(即numpsy.dot(X,beta))可能导致非常大/小的值,然后与numpsy.exp()变得“不兼容”。如https://lingpipe-blog.com/2012/02/16/howprevent-overflow-underflow-logistic-regression/所示,溢出问题往往发生在:abs(np.dot(X,beta))> 500.初始溢出问题具有重要的后果,因为它们将导致其余代码中的0,NaN和Inf值,从而产生其他问题(例如,np.log(0)或number / Inf)。我花了很多时间尝试用十进制模块,bigfloat模块等解决这个问题,但似乎没有用(Deal with overflow in exp using numpy)。

第二最佳选项似乎通过包括一些舍入操作(例如,num [num> 400] = 400)然后使用“Nelder-Mead”算法来最小化对数似然来修改似然函数。理想情况下,我会使用“BFGS”算法,但它与舍入操作不兼容。

关于我如何修复代码中的溢出问题的任何想法?

备注:非常大的np.dot(X,beta)值似乎不是R,MATLAB和STATA中的问题。

非常感谢您的帮助!

PYTHON CODE

N = len(set(data[:,0]))
T = 20
J = 2
Y = np.reshape(data[:,12],(N*T,J))
X = np.matrix(data[:,[33,10,5,6,7,8,9]])

def fn_mnl(beta):
    num = np.dot(X,beta)
    num[num >  400] =  400 # to avoid overflow  with np.exp()
    num[num < -400] = -400 # to avoid underflow with np.exp()
    num = np.exp(num)
    num = num.reshape(N*T,J)
    den = np.sum(num, axis=1)
    prbj = num/den
    prbi = prbj[Y==1]
    prbi[prbi <= 0] = 0.0000001 # to avoid issue with np.log()
    llik = np.sum(np.log(prbi))
    return(-llik)

sv = [0]*X.shape[1]
res = sc.minimize(fn_mnl, sv, method='Nelder-Mead')

R CODE

LOGIT = function(Beta, DATA, X, Y){
  num  = exp(as.matrix(DATA[,X]) %*% as.vector(Beta))
  mat1 = matrix(num, ncol=2, byrow=T)
  prbj = mat1/rowSums(mat1)
  prbi = prbj[Y==1]
  logl = sum(log(prbi))
  return(-logl)}

0 个答案:

没有答案