我正在尝试在著名的虹膜数据集上使用statsmodels的MNLogit函数。当我尝试拟合模型时,得到:“当前函数值:nan”。这是我正在使用的代码:

import statsmodels.api as st
iris = st.datasets.get_rdataset('iris','datasets')
y = iris.data.Species
x = iris.data.ix[:, 0:4]
x = st.add_constant(x, prepend = False)
mdl = st.MNLogit(y, x)
mdl_fit = mdl.fit()
print (mdl_fit.summary())

最佳答案

在虹膜示例中,我们可以完美地预测Setosa。这会导致Logit和MNLogit中(部分)完美分离的问题。

完美分离对于预测很有用,但是logit的参数变为无穷大。在这种情况下,我得到的是奇异矩阵错误,而不是使用statsmodels master相对较新版本的Nans(在Windows上)。

离散模型的默认优化器是Newton,当Hessian变为奇数时,该优化器将失败。其他不使用Hessian信息的优化器也可以完成优化。例如使用“bfgs”,我得到

>>> mdl_fit = mdl.fit(method='bfgs')
Warning: Maximum number of iterations has been exceeded.
         Current function value: 0.057112
         Iterations: 35
         Function evaluations: 37
         Gradient evaluations: 37
e:\josef\eclipsegworkspace\statsmodels-git\statsmodels-all-new2_py27\statsmodels\statsmodels\base\model.py:471: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
  "Check mle_retvals", ConvergenceWarning)

Setosa的预测概率本质上是(1,0,0),即它们是完美预测的
>>> fitted = mdl_fit.predict()
>>> fitted[y=='setosa'].min(0)
array([  9.99497636e-01,   2.07389867e-11,   1.71740822e-38])
>>> fitted[y=='setosa'].max(0)
array([  1.00000000e+00,   5.02363854e-04,   1.05778255e-20])

但是,由于完美分离,因此无法识别参数,这些值主要由优化器的停止准则确定,并且标准误差非常大。
>>> print(mdl_fit.summary())
                          MNLogit Regression Results
==============================================================================
Dep. Variable:                Species   No. Observations:                  150
Model:                        MNLogit   Df Residuals:                      140
Method:                           MLE   Df Model:                            8
Date:                Mon, 20 Jul 2015   Pseudo R-squ.:                  0.9480
Time:                        04:08:04   Log-Likelihood:                -8.5668
converged:                      False   LL-Null:                       -164.79
                                        LLR p-value:                 9.200e-63
=====================================================================================
Species=versicolor       coef    std err          z      P>|z|      [95.0% Conf. Int.]
--------------------------------------------------------------------------------------
Sepal.Length          -1.4959    444.817     -0.003      0.997      -873.321   870.330
Sepal.Width           -8.0560    282.766     -0.028      0.977      -562.267   546.155
Petal.Length          11.9301    374.116      0.032      0.975      -721.323   745.184
Petal.Width            1.7039    759.366      0.002      0.998     -1486.627  1490.035
const                  1.6444   1550.515      0.001      0.999     -3037.309  3040.597
--------------------------------------------------------------------------------------
Species=virginica       coef    std err          z      P>|z|      [95.0% Conf. Int.]
-------------------------------------------------------------------------------------
Sepal.Length         -8.0348    444.835     -0.018      0.986      -879.896   863.827
Sepal.Width         -15.8195    282.793     -0.056      0.955      -570.083   538.444
Petal.Length         22.1797    374.155      0.059      0.953      -711.152   755.511
Petal.Width          14.0603    759.384      0.019      0.985     -1474.304  1502.425
const                -6.5053   1550.533     -0.004      0.997     -3045.494  3032.483
=====================================================================================

关于statsmodels模型中的实现

Logit专门检查是否完美分离,并引发一个异常,可以选择将其减弱为警告。
对于诸如MNLogit之类的其他模型,还没有明确检查是否可以完美分离,主要是因为缺少良好的测试用例和易于识别的一般条件。 (像https://github.com/statsmodels/statsmodels/issues/516这样的几个问题仍然存在)

我的总体策略是:

当收敛失败时,请尝试使用不同的优化器和不同的起始值(start_params)。如果某些优化器成功,则可能是一个困难的优化问题,可能是目标函数的曲率,缩放比例的解释变量差或类似的问题。一个有用的检查是将诸如nmpowell之类的健壮优化器的参数估计值用作更严格的优化器(如newtonbfgs)的起始值。

如果在某些优化程序收敛后结果仍然不佳,则可能是数据固有的问题,例如Logit,Probit和其他几个模型中的完美分离或奇异或接近奇异的设计矩阵。在这种情况下,必须更改模型。可以通过互联网搜索找到关于完美分离的建议。

关于python - statsmodel中的MNLogit返回nan,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31507396/

10-13 02:28