LinearRegression
提供unpenalized OLS,和SGDClassifier
,其支持loss="log"
,还支持penalty="none"
。 但是如果你想要简单的老式无惩罚逻辑回归,你必须通过将C
中的LogisticRegression
为一个大数来伪造它,或者使用Logit
的statsmodels
反而。
你必须通过将 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"
但我不确定添加冗余选项有什么好处。
如果您觉得它增加了可发现性,那么我们可以添加它,并且 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 编码特征)。
最有用的评论
你问我为什么要在没有正则化的情况下进行逻辑回归? 因为(1)有时样本与特征数量的比例足够大,正则化不会买任何东西,(2)有时最适合的系数是有意义的,而不是最大化预测准确性。