在逻辑回归中,正则化强度的倒数是什么意思?它应该如何影响我的代码?

60

我正在使用scikit learn中的sklearn.linear_model.LogisticRegression来运行逻辑回归。

C : float, optional (default=1.0) Inverse of regularization strength;
    must be a positive float. Like in support vector machines, smaller
    values specify stronger regularization.

在简单的术语中,这里的C是什么意思?正则化强度是什么?


你问过谷歌吗?我问了。这个链接是第一个结果:http://compbio.soe.ucsc.edu/html_format_papers/hughkrogh96/node6.html - Rich Scriven
9
我已经看过了,并且发现它很复杂,希望有人能够友好地用简单的英语解释一下给我听!感谢提供链接 :) - user3427495
3
没问题。虽然它看起来更像复杂的数学而不是简单的英语。 :) - Rich Scriven
19
我问了谷歌,这是第一个出现的链接 ;) - AJP
3
我在 Quora 上询问了,这是第一个答案中的链接 ;) - Ankit Agrawal
2个回答

105

正则化是为了减少过拟合而对参数值的增加施加惩罚。当你训练一个模型,比如逻辑回归模型时,你会选择一组参数,使得这个模型最好地拟合数据。这意味着将模型预测的结果与你实际输入的因变量之间的误差最小化。

但是当有大量参数(即独立变量)但数据不够多时,模型往往会调整参数值来适应数据中的不规则性,这样模型就会完美地拟合你的数据。然而,由于这些特异性在未来的数据中并不出现,所以你的模型表现不佳。

为了解决这个问题,除了最小化误差外,还需要最小化一个函数,该函数对参数的大值进行惩罚。通常使用的函数是λΣθj2,其中λ是某个常数,乘以参数平方值的总和θj2。λ越大,参数就越不容易因为数据微小扰动而增加。在你的情况下,你需要指定C=1/λ,而不是λ。


2
非常好的回答!非常感谢 :) - user3427495
据我所知,惩罚是应用于减小参数的幅度。 - Arton Dorneles
@ArtonDorneles 是的,增加参数的大小会有惩罚。相反地,减小参数的大小往往会有好处。 - TooTone
1
我刚读到L1和L2正则化,这个链接很有用:LINK。现在我知道你在这里提到的术语是L2正则化。 - ashley
1
是的,这个术语是L2正则化,为了让大家了解,L2只是意味着$\lambda \sum \theta_{j}^{2}$,而L1只是意味着$\lambda \sum \abs{\theta_{j}}$。就是这么简单,但影响很大,因为L1倾向于稀疏性(模型中的特征参数更少),因为$x^2$比$x < 1$更快地成为惩罚的无关紧要的加法。 - Mike Williamson
显示剩余3条评论

0
在一句话中,正则化使模型在训练数据上表现更差,以便在保留数据上表现更好。
逻辑回归是一个优化问题,其中最小化以下目标函数。

func1

在使用solver='lbfgs'时,损失函数看起来至少如下所示。

loss func

正则化将系数的范数添加到该函数中。以下实现了L2惩罚。

func2

从方程中可以看出,正则化项的作用是惩罚大的系数(最小化问题是为了找到使目标函数最小化的系数)。由于每个系数的大小取决于其对应变量的尺度,因此需要对数据进行缩放,以便正则化项平等地惩罚每个变量。正则化强度由C确定,随着C的增加,正则化项变小(对于极大的C值,几乎没有正则化)。
如果初始模型过拟合(即,它在训练数据上拟合得太好),那么添加一个强正则化项(使用较小的C值)会使模型在训练数据上表现更差,但引入这种“噪声”会提高模型在未见过的(或测试)数据上的性能。

下面展示了具有1000个样本和200个特征的示例。从在不同的C值上准确率的图表中可以看出,如果C很大(几乎没有正则化),模型在训练数据和测试数据上的表现存在很大差距。然而,当C减小时,模型在训练数据上表现较差,但在测试数据上表现更好(测试准确率增加)。然而,当C变得太小(或正则化变得过强)时,模型再次开始表现较差,因为现在正则化项完全主导目标函数。

C vs accuracy


用于生成图表的代码:
import pandas as pd
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression

# make sample data
X, y = make_classification(1000, 200, n_informative=195, random_state=2023)
# split into train-test datasets
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=2023)

# normalize the data
sc = StandardScaler()
X_train = sc.fit_transform(X_train)
X_test = sc.transform(X_test)

# train Logistic Regression models for different values of C
# and collect train and test accuracies
scores = {}
for C in (10**k for k in range(-6, 6)):
    lr = LogisticRegression(C=C)
    lr.fit(X_train, y_train)
    scores[C] = {'train accuracy': lr.score(X_train, y_train), 
                 'test accuracy': lr.score(X_test, y_test)}

# plot the accuracy scores for different values of C
pd.DataFrame.from_dict(scores, 'index').plot(logx=True, xlabel='C', ylabel='accuracy');

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接