sklearn逻辑回归收敛到一个简单案例的意外系数

机器算法验证 回归 物流 scikit-学习 S形曲线
2022-03-01 02:19:46

案例如下:

假设

import numpy as np

X = np.array([1, 1, 1])
y = np.array([1, 0, 1])

然后我执行一个没有截距的逻辑回归来检查拟合系数:

from sklearn.linear_model import LogisticRegression

def fit_predict(X, y, fit_intercept=True):
  model = LogisticRegression(fit_intercept=fit_intercept)
  model.fit(X.reshape(-1, 1), y)
  print(f'model coefficients: {model.coef_}')

fit_predict(X, y, fit_intercept=False)

# output: [[0.2865409]]

我对这个输出感到很困惑。根据我的代数(直接解决优化约束),系数应该是logit(2/3)0.6931471805599452

这是因为我的数学错了,还是因为我不知道发生了其他事情?

代数如下,从以下等式开始:

iyixisigmoid(xi)xi=0

如果我们将值插入,则

2=3sigmoid(1)

我得出结论β=logit(2/3)

提前致谢。

2个回答

正如 Demetri 建议的那样,我们需要添加penalty='none'代码以提供预期的结果。

修改后的代码如下:

from sklearn.linear_model import LogisticRegression

def fit_predict(X, y, fit_intercept=True):
  model = LogisticRegression(fit_intercept=fit_intercept, penalty='none')
  model.fit(X.reshape(-1, 1), y)
  print(f'model coefficients: {model.coef_}')

我将对这个问题添加我自己的答案,以阐明为什么默认添加惩罚。我也在为后代发帖,因为你不是第一个被这个抓住的人,你也不会是最后一个。

早在 2019 年,Zachary Lipton 就发现 sklearn 也默认使用惩罚,这在推特和其他地方引发了一场非常激烈的争论。该讨论的长短在于 sklearn 首先将自己视为一个机器学习库,这在他们眼中意味着他们更喜欢其他东西而不是公正性和效果估计。他们的哲学(在我看来)最引人注目的例子是当 Andreas Mueller直截了当地问为什么有人想要一个不偏不倚的逻辑回归实现时推理根本不在他们的雷达上。

因此,LogisticRegression不是法律上的逻辑回归。默认情况下,它是一种惩罚变体(默认惩罚甚至没有任何意义)。还有一个尖锐的地方。如果您了解惩罚逻辑回归(la ridge 回归或 LASSO),您会惊讶地发现 sklearn 将惩罚参数参数化为正则化强度的倒数因此在 LASSO 或 Ridge 中设置将对应于in λ=2C=0.5LogisticRegression

让我通过使这一点完全明确来总结。

如果您打算估计某些协变量对二元结果的影响,并且您坚持使用 python Do Not Use Sklearn使用 Statsmodels

但是,如果您坚持使用 sklearn,请记住您需要penalty='none'在模型实例化步骤中进行设置。否则,您的估计将偏向于空值(按设计)。