Scikit-learn: 建议:添加对无惩罚逻辑回归的支持

创建于 2016-04-30  ·  34评论  ·  资料来源: scikit-learn/scikit-learn

LinearRegression提供unpenalized OLS,和SGDClassifier ,其支持loss="log" ,还支持penalty="none" 。 但是如果你想要简单的老式无惩罚逻辑回归,你必须通过将C中的LogisticRegression为一个大数来伪造它,或者使用Logitstatsmodels反而。

Documentation Easy

最有用的评论

你问我为什么要在没有正则化的情况下进行逻辑回归? 因为(1)有时样本与特征数量的比例足够大,正则化不会买任何东西,(2)有时最适合的系数是有意义的,而不是最大化预测准确性。

所有34条评论

你必须通过将 LogisticRegression 中的 C 设置为一个大数来伪造它

这种方法有什么问题?

我认为它比直接实现无惩罚逻辑回归不准确且慢。 我错了吗?

我注意到将C得太高,如下所示,将导致LogisticRegression.fit挂起。 但我不知道这是一个错误还是只是算法的固有属性及其在 64 位计算机上的实现。

import numpy as np
from sklearn.linear_model import LogisticRegression

x = np.matrix([0, 0, 0, 0,  1, 1, 1, 1]).T
y =           [1, 0, 0, 0,  1, 1, 1, 0]

m = LogisticRegression(C = 1e200)
m.fit(x, y)
print m.intercept_, m.coef_

我注意到将 C 设置得太高,如下所示,会导致 LogisticRegression.fit 挂起

是的,这是可以预料的,因为当 C 很大时问题变得不适定。 迭代求解器在处理不适定问题时速度很慢。

在您的示例中,算法需要很长时间才能达到所需的容差。 您需要增加tol或硬编码max_iter

@mblondel是否有“迭代求解器”的替代方案?
你不会得到完全非正则化的选项,对吧?

@Kodiologist你为什么要这个?

你问我为什么要在没有正则化的情况下进行逻辑回归? 因为(1)有时样本与特征数量的比例足够大,正则化不会买任何东西,(2)有时最适合的系数是有意义的,而不是最大化预测准确性。

是的,这是我的问题。

(1) 不正确。 它总会为您提供更快的求解器。

(2) 更多在统计分析领域,这并不是 scikit-learn 真正的重点。 我想我们可以添加这个,但我不知道我们会使用什么求解器。 作为一名非统计学家,我想知道通过一些正则化而改变的系数有什么好处。

关于(1)我不能说太多,因为计算不是我的强项。 对于(2),我是一名具有统计学背景的数据分析师。 我知道 scikit-learn 专注于传统的机器学习,但在我看来,它是目前最好的数据分析 Python 包,我认为它会受益于不_太多_限制自己。 (我还认为,在 Larry Wasserman 和 Andrew Gelman 之后,统计学和机器学习会从更多的混合中相互受益,但我猜这是它自己的蠕虫。)所有系数都会随着正则化而改变; 这就是正则化的作用。

我不反对在没有正则化的情况下添加求解器。 我们可以检查什么是好的,或者只是保释并使用 l-bfgs 并事先检查它是否病态?

是的,所有系数都随着正则化而变化。 老实说,我只是很好奇你以后想用它们做什么。

嘿,
这个话题的状态如何? 我对无惩罚的逻辑回归非常感兴趣。 这样 p 值将意味着从统计学上讲。 否则我将不得不继续使用 R 😢 来处理这些用例......
谢谢,
亚历克斯

还是国家模式?

您建议实施哪些求解器? 这与我们已经拥有的 C -> infty 求解器有何不同?

您建议实施哪些求解器? 这与我们已经拥有的 C -> infty 求解器有何不同?

您可以尝试查看 R 或 statsmodels 以获得想法。 我不熟悉他们的方法,但它们相当快并且根本不使用正则化。

如果您使用 QR 算法进行矩阵求逆,那么 statsmodels 也可以完成这项工作。 我的用例是关于模型可解释性的。 为了性能,我肯定会使用正则化。

我认为我们不需要添加任何新的求解器......逻辑回归不喜欢封闭形式的解决方案,这意味着 statsmodel 也必须使用某种迭代求解器(我的猜测是迭代重新加权最小二乘法,但是我没查过)。 设置C=np.inf (或等效的alpha=0 )原则上应该适用于我们当前的求解器。 我的建议是切换到 L-BFGS 或 Newton-CG 求解器,因为 liblinear 在这种设置下确实会很慢。 也许我们可以添加一个solver="auto"选项并在C=np.inf或等效的penalty="none"时自动切换到其中之一?

我们正在 #10001 fwiw 中将默认求解器更改为 lbfgs

对于那些真正想要非正则化逻辑回归的人(比如我自己)。 我一直不得不使用 statsmodels 并制作一个模仿 SKLearn API 的包装类。

有任何更新吗? 这是我愿意向人们推荐 scikit-learn 的一大障碍。 对于来自其他库的人来说,scikit-learn 默认进行正则化并且无法禁用它,这也一点也不明显

@shermstats建议如何改进文档? 我同意这可能不是很明显。
l-bfgs 是否允许C=np.inf

您可以指定C=np.inf ,但它会给您与C=large value相同的结果。 在我尝试的示例中,它比 statsmodel 更适合,并且 statsmodel 未能与大多数其他随机种子收敛:

from sklearn.datasets import make_classification
from sklearn.linear_model import LogisticRegression
import statsmodels.api as sm

X, y = make_classification(random_state=2)
lr = LogisticRegression(C=np.inf, solver='lbfgs').fit(X, y)


logit = sm.Logit(y, X)
res = logit.fit()
Optimization terminated successfully.
         Current function value: 0.167162
         Iterations 10
from sklearn.metrics import log_loss
log_loss(y, lr.predict_proba(X))
log_loss(y, res.predict(X))
0.16197793224715606
0.16716164149746823

所以我认为我们应该只记录你可以通过设置 C large 或 np.inf 来获得一个不受惩罚的模型。

我建议添加到文档字符串和用户指南
“默认情况下,LogisticRegression 模型会受到惩罚。您可以通过设置 C=np.inf 和solver='lbfgs' 来获得未受到惩罚的模型。”

它比 statsmodel 更适合,并且 statsmodel 未能与大多数其他随机种子收敛

R 的glm更成熟,可以进行更好的比较。

我建议添加到文档字符串和用户指南
“默认情况下,LogisticRegression 模型会受到惩罚。您可以通过设置 C=np.inf 和solver='lbfgs' 来获得未受到惩罚的模型。”

为什么不添加 allow penalty = "none" a la SGDClassifier

@Kodiologist我不反对添加penalty="none"但我不确定添加冗余选项有什么好处。
我认为我们欢迎与 glm 进行比较。 我对 glm 不是很熟悉,所以我可能不是进行比较的好人。 但是,我们正在优化对数损失,因此实际上应该没有区别。 也许他们实现了不同的求解器,所以有一个基准会很好。

我不反对添加penalty="none"但我不确定添加冗余选项有什么好处。

  1. 如何获得未受惩罚的模型变得更加清晰。
  2. 读者可以更清楚地了解使用无惩罚模型的代码试图做什么。
  3. 它允许 sklearn 将来在不破坏人们代码的情况下更改其非正则化模型的实现。

如果您觉得它增加了可发现性,那么我们可以添加它,并且 3 是一个有效的点(尽管我们实际上无法在不弃用的情况下真正改变它,请参阅求解器的当前更改)。
您要发送 PR 吗?

我没有它的圆形 tuits; 对不起。

@Kodiologist至少你教了我一个我不知道的习语;)

所以对贡献者开放:添加penalty='none'作为选项。 还可能检查哪些求解器支持此/对此有效(liblinear 可能不是)并限制为这些求解器。

我建议添加到文档字符串和用户指南
“默认情况下,LogisticRegression 模型会受到惩罚。您可以通过设置 C=np.inf 和solver='lbfgs' 来获得未受到惩罚的模型。”

这对我来说听起来很合理。 我还建议将第一句话加粗,因为对于来自其他机器学习或数据分析环境的人来说,这确实令人惊讶。

@shermstats所以@Kodiologist建议添加penalty="none"以使其更加明确,这只是C=np.inf的别名。 以这种方式使这更明确对我来说是有意义的。 你对此有什么想法吗?
那么这就是文档中的内容。 我同意大胆可能是个好主意。
我认为对于有 ML 背景的人来说这是(也许?)预期的,对于有统计背景的人来说,这似乎非常令人惊讶。

确切地! 我有统计背景,并与许多来自 R 甚至指向和点击界面的统计人员一起工作,这种行为让我们感到非常惊讶。 我认为现在penalty=None (不确定"none"None )是一个很好的解决方案。 将来,我们应该有一个单独的求解器,它会自动调用无惩罚逻辑回归,以防止出现@mblondel描述的问题。

抱歉,您指的是哪个问题? 我们默认切换到 l-bfgs,如果有人指定penalty='none' ,我们也可以在内部自动将求解器切换到 l-bfgs(通常 None 是我们用于弃用参数的特殊标记,但我们已经停止这样做。仍然“无”将与库的其余部分更一致)。
无论如何,我们都需要solver="auto" ,因此根据惩罚更改求解器应该不是问题。

这个问题是指迭代算法对于大 C 变得非常慢。我不是数值分析专家,但如果 l-bfgs 阻止它变慢,那么这听起来像是正确的解决方案。 penalty='none'听起来也是处理这个问题的正确方法。

@shermstats是的,对于 l-bfgs,这似乎不是问题。 不过,我还没有运行广泛的基准测试,也没有时间。 如果有人想运行基准测试,那将是一个很大的帮助。

如果要包含penalty='none',我建议在用户指南中添加与OLS 相同的关于共线X 的警告(特别是对于one-hot 编码特征)。

此页面是否有帮助?
0 / 5 - 0 等级