为啥 sklearn 逻辑回归正则化权重和截距?

Posted

技术标签:

【中文标题】为啥 sklearn 逻辑回归正则化权重和截距?【英文标题】:Why does sklearn logistic regression regularize both the weights and the intercept?为什么 sklearn 逻辑回归正则化权重和截距? 【发布时间】:2018-04-14 12:58:48 【问题描述】:

逻辑回归中的正则化参数C (请参阅http://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LogisticRegression.html)用于允许对函数进行良好定义,并避免过度拟合或阶跃函数问题(请参阅https://datascience.stackexchange.com/questions/10805/does-scikit-learn-use-regularization-by-default/10806)。

然而,逻辑回归中的正则化应该只关注特征的权重,而不是截距(也在这里解释:http://aimotion.blogspot.com/2011/11/machine-learning-with-python-logistic.html)

但似乎 sklearn.linear_model.LogisticRegression 实际上也正则化了截距。原因如下:

1) 仔细考虑上面的链接 (https://datascience.stackexchange.com/questions/10805/does-scikit-learn-use-regularization-by-default/10806):sigmod 稍微向左移动,更靠近截距 0。

2) 我尝试用逻辑曲线和手动最大似然函数拟合数据点。将截距包含在 L2 范数中会得到与 sklearn 函数相同的结果。

请教两个问题:

1) 我是不是弄错了,这是一个错误,还是有充分的理由来规范拦截?

2) 有没有办法使用 sklearn 并指定正则化除截距以外的所有参数?

谢谢!

import numpy as np
from sklearn.linear_model import LogisticRegression

C = 1e1
model = LogisticRegression(C=C)

x = np.arange(100, 110)
x = x[:, np.newaxis]
y = np.array([0]*5 + [1]*5)

print x
print y

model.fit(x, y)
a = model.coef_[0][0]
b = model.intercept_[0]

b_modified = -b/a                   # without regularization, b_modified should be 104.5 (as for C=1e10)

print "a, b:", a, -b/a

# OUTPUT: 
# [[100]
#  [101]
#  [102]
#  [103]
#  [104]
#  [105]
#  [106]
#  [107]
#  [108]
#  [109]]
# [0 0 0 0 0 1 1 1 1 1]
# a, b: 0.0116744221756 100.478968664

【问题讨论】:

几年前我问过一个类似的问题。我知道你可以使用参数 intercept_scaling 来控制它,但我不确定合适的技术。 ***.com/questions/17711304/… 【参考方案1】:

scikit-learn 具有默认的正则化逻辑回归。

sklearn.linear_model.LogisticRegressionintercept_scaling 参数值的变化如果只更改C 参数对结果的影响类似。

intercept_scaling参数修改的情况下,正则化对逻辑回归中偏差的估计有影响。当这个参数的值偏高时,正则化对偏差的影响就会降低。每official documentation:

拦截变为intercept_scaling * synthetic_feature_weight。 笔记!合成特征权重受 l1/l2 正则化 与所有其他功能一样。减少正则化对 合成特征权重(因此在截距上) 必须增加intercept_scaling。

希望对您有所帮助!

【讨论】:

我添加了一个最小示例。你能用这个例子说明需要添加什么来不规范拦截吗?谢谢! 我认为如果你将截距缩放任意大,它的正则化可以忽略不计(但不是严格为零) 正如@cxrodgers 正确指出的那样——让我们试试model = LogisticRegression(intercept_scaling=99999)【参考方案2】:

感谢@Prem,这确实是解决方案:

C = 1e1  
intercept_scaling=1e3    # very high numbers make it unstable in practice
model = LogisticRegression(C=C, intercept_scaling=intercept_scaling)

【讨论】:

以上是关于为啥 sklearn 逻辑回归正则化权重和截距?的主要内容,如果未能解决你的问题,请参考以下文章

逻辑回归框架

在线性回归中使用现有系数和截距

03_有监督学习--简单线性回归模型(调用 sklearn 库代码实现)

具有非正则截距项的 Scikit-learn 岭回归

如何在sklearn逻辑回归中设置样本权重?

7.逻辑回归实践