Python中的logit回归和奇异矩阵错误

Posted

技术标签:

【中文标题】Python中的logit回归和奇异矩阵错误【英文标题】:logit regression and singular Matrix error in Python 【发布时间】:2014-01-09 07:44:06 【问题描述】:

我正在尝试对德国信用数据运行 logit 回归 (www4.stat.ncsu.edu/~boos/var.select/german.credit.html)。为了测试代码,我只使用了数值变量,并尝试使用以下代码将其与结果进行回归。

import pandas as pd
import statsmodels.api as sm
import pylab as pl
import numpy as np

df = pd.read_csv("germandata.txt",delimiter=' ')
df.columns = ["chk_acc","duration","history","purpose","amount","savings_acc","employ_since","install_rate","pers_status","debtors","residence_since","property","age","other_plans","housing","existing_credit","job","no_people_liab","telephone","foreign_worker","admit"]

#pls note that I am only retaining numeric variables
cols_to_keep = ['admit','duration', 'amount', 'install_rate','residence_since','age','existing_credit','no_people_liab']

# rank of cols_to_keep is 8
print np.linalg.matrix_rank(df[cols_to_keep].values)
data = df[cols_to_keep]

data['intercept'] = 1.0

train_cols = data.columns[1:]

#to check the rank of train_cols, which in this case is 8
print np.linalg.matrix_rank(data[train_cols].values)

#fit logit model
logit = sm.Logit(data['admit'], data[train_cols])
result = logit.fit()

当我检查数据时,所有 8.0 列似乎都是独立的。尽管如此,我得到了奇异矩阵错误。你能帮忙吗?

谢谢

【问题讨论】:

【参考方案1】:

endog y 变量需要为零,一。在这个数据集中,它有 1 和 2 中的值。如果我们减去 1,就会产生结果。

>>> logit = sm.Logit(data['admit'] - 1, data[train_cols])
>>> result = logit.fit()
>>> print result.summary()
                           Logit Regression Results                           
==============================================================================
Dep. Variable:                  admit   No. Observations:                  999
Model:                          Logit   Df Residuals:                      991
Method:                           MLE   Df Model:                            7
Date:                Fri, 19 Sep 2014   Pseudo R-squ.:                 0.05146
Time:                        10:06:06   Log-Likelihood:                -579.09
converged:                       True   LL-Null:                       -610.51
                                        LLR p-value:                 4.103e-11
===================================================================================
                      coef    std err          z      P>|z|      [95.0% Conf. Int.]
-----------------------------------------------------------------------------------
duration            0.0261      0.008      3.392      0.001         0.011     0.041
amount           7.062e-05    3.4e-05      2.075      0.038      3.92e-06     0.000
install_rate        0.2039      0.073      2.812      0.005         0.062     0.346
residence_since     0.0411      0.067      0.614      0.539        -0.090     0.172
age                -0.0213      0.007     -2.997      0.003        -0.035    -0.007
existing_credit    -0.1560      0.130     -1.196      0.232        -0.412     0.100
no_people_liab      0.1264      0.201      0.628      0.530        -0.268     0.521
intercept          -1.5746      0.430     -3.661      0.000        -2.418    -0.732
===================================================================================

但是,在其他情况下,当我们评估它远离最优值时,例如在糟糕的起始值时,Hessian 可能不是正定的。在这些情况下,切换到不使用 Hessian 的优化器通常会成功。例如,scipy 的 'bfgs' 是一个很好的优化器,适用于许多情况

result = logit.fit(method='bfgs')

【讨论】:

此问题已得到修复以提供良好的错误消息。 github.com/statsmodels/statsmodels/pull/1978 很好的答案。要检查的另一件事:如果您的 exog 变量全为零(就像我的情况一样),它也会导致此错误。【参考方案2】:

我已经设法通过删除低方差列来解决这个问题:

from sklearn.feature_selection import VarianceThreshold

def variance_threshold_selector(data, threshold=0.5):
    # https://***.com/a/39813304/1956309
    selector = VarianceThreshold(threshold)
    selector.fit(data)
    return data[data.columns[selector.get_support(indices=True)]]

# min_variance = .9 * (1 - .9)  # You can play here with different values.
min_variance = 0.0001
low_variance = variance_threshold_selector(df, min_variance) 
print('columns removed:')
df.columns ^ low_variance.columns
df.shape
df.shape
X = low_variance
# (Logit(y_train, X), logit.fit()... etc)

提供更多背景信息:在此步骤之前,我对一些分类数据进行了一次热编码,其中一些列的 1 很少

【讨论】:

感谢 cmets。我认为这样做会偶然解决问题。当设计矩阵(或 one-hot 编码后的分类数据)的列的总和为 1(截距)时,就会出现奇异矩阵。

以上是关于Python中的logit回归和奇异矩阵错误的主要内容,如果未能解决你的问题,请参考以下文章

CGAffineTransformInvert:奇异矩阵错误

Quantum backsolve总结错误

python Ridge 回归(岭回归)的原理及应用

scipy 最小化 SLSQP - 'LSQ 子问题中的奇异矩阵 C'

使用 sklearn 和 GPFlow 的高斯回归

Python与矩阵论——特征值与特征向量