在这篇文章中,我们将首先看看Lasso和Ridge回归中一些常见的错误,然后我将描述我通常采取的步骤来优化超参数。代码是用Python编写的,我们主要依赖scikit-learn。本文章主要关注Lasso的例子,但其基本理论与Ridge非常相似。
起初,我并没有真正意识到需要另一个关于这个主题的指南——毕竟这是一个非常基本的概念。然而,当我最近想要确认一些事情时,我意识到,市面上的很多文章要么太学术化,要么太简单,要么就是完全错误。一个很常见的混淆来源是,在sklearn中总是有十多种不同的方法来计算同一件事情。
所以,废话少说,下面是我对这个话题的两点看法。
快速的理论背景回顾
Lasso和Ridge都是正则化方法,他们的目标是通过引入惩罚因子来正则化复杂的模型。它们在减少过拟合、处理多重共线性或自动特征工程方面非常出色。这听i来似乎有点神奇,但通过训练使模型更努力地拟合数据,我们得到一个更好的对底层结构的了解,从而对测试数据有了更好的泛化和更好的拟合。
LinearRegression
根据sklearn的公式,这是线性回归模型中最小的表达式,即所谓的普通最小二乘:
其中X矩阵为自变量,w为权重即系数,y为因变量。
Ridge
Ridge回归采用这个表达式,并在平方系数的最后添加一个惩罚因子:
这里α是正则化参数,这是我们要优化的。该模型惩罚较大的系数,并试图更平均地分配权重。用外行人的话来说,这就是Ridge模型所做的:
X1,我们看到你做得很好,如果不是因为惩罚的因素,我们会很重视你。但是X2只比你们差一点点,如果我们在你们俩之间均分权重,我们会得到更低的惩罚,从而得到更好的总分。
Lasso
Lasso做了类似的事情,但使用绝对值之和(l1范数)的权重作为惩罚。
注: sklearn提供公式中还有一个n_samples,这是观察的数量,并且应该改变X和y。我发现没有解释这是为什么,也许是为了比较不同模型。
Lasso将开始降低不那么重要的变量的系数,也有可能将系数降低到0。通俗的说:
X1,你对总分数的最小贡献会被注意到。但是,根据最新的罚分,我们将不得不将你从回归中移除。
Elastic Net
值得注意的是,您还可以将同一模型中的两个惩罚与Elastic Net结合起来。您需要在那里优化两个超参数。在本指南中,我们将不讨论此选项。
所需要的类库
以下是需要的所有库的列表:
importpandasaspdimportnumpyasnpimportmatplotlib.pyplotaspltimportseabornassnsfromsklearn.metricsimport\r2_score, get_scorerfromsklearn.linear_modelimport\Lasso, Ridge, LassoCV,LinearRegressionfromsklearn.preprocessingimport\StandardScaler, PolynomialFeaturesfromsklearn.model_selectionimport\KFold, RepeatedKFold, GridSearchCV, \cross_validate, train_test_split
三个秘诀
在本节中,我们将讨论一些常规技巧和常见错误,以避免涉及正则化回归。这些示例使用的是波士顿住房数据,您可以从Kaggle下载数据。
column_names=\ ['CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE',\'DIS', 'RAD', 'TAX', 'PTRATIO', 'B', 'LSTAT', 'MEDV'] data=pd.read_csv("../datasets/housing.csv", \header=None, delimiter=r"\s+", names=column_names) y=data['MEDV'] X=data.drop(['MEDV'], axis=1)
秘诀一:缩放自变量
如标题所示:需要缩放变量以进行正则回归。(我们知道,像缩放这样的线性变换不会对原始线性回归的预测产生影响。)很明显,如果您仔细查看一下公式,为什么必须对正则回归进行缩放:变量恰好在很小的范围内,其系数会很大,因此,由于惩罚会受到更大的惩罚。反之亦然,大规模变量将获得较小的系数,并且受惩罚的影响较小。Lasso and Ridge都是如此。
假设您执行以下操作。
(同样,该示例没有缩放比例,将不会产生正确的结果,请不要这样做。此外,请注意,除了缩放比例以外,还有其他问题,我们将在近期内再次讨论。)
# 错误,不要使用
cv=RepeatedKFold(n_splits=10, n_repeats=3, random_state=1) lasso_alphas=np.linspace(0, 0.2, 21)lasso=Lasso() grid=dict() grid['alpha'] =lasso_alphasgscv=GridSearchCV( \lasso, grid, scoring='neg_mean_absolute_error', \cv=cv, n_jobs=-1) results=gscv.fit(X, y)print('MAE: %.5f'%results.best_score_) print('Config: %s'%results.best_params_)
结果如下:
MAE: -3.37896Config: {'alpha': 0.01}
但是,如果事先缩放X变量,通常会获得更好的分数。要缩放,我们可以使用sklearn的StandardScaler。此方法使变量以0为中心,并使标准偏差等于1。
sc=StandardScaler()X_scaled=sc.fit_transform(X) X_scaled=pd.DataFrame(data=X_scaled, columns=X.columns)
如果在上面的代码块中用X_scaled替换X,我们将得到:
MAE: -3.35080Config: {'alpha': 0.08}
是的,没有太大的改进,但这是由于许多因素,我们将在后面看到。最重要的是,波士顿的住房数据是一个很好的,经过量身定制的线性回归的示例,因此我们不能做太多改进。
总结:在进行正则化之前,使用StandardScaler缩放自变量。无需调整因变量。
秘诀二:当Alpha等于零时…
如果在Lasso和Ridge中为alpha参数选择0,则基本上是在拟合线性回归,因为在公式的OLS部分没有任何惩罚。
由于计算复杂性,sklearn文档实际上不建议使用alpha = 0的参数运行这些模型。因为他可能引起算问题,但我还没有遇到过这种情况,因为它总是给出与LinearRegression模型相同的结果。
总结:选择alpha = 0毫无意义,这只是线性回归。
秘诀三:多次尝试
在上面的示例中,我们浏览了一系列Alpha,对它们进行了全部尝试,然后选择了得分最高的Alpha。但是,像往常一样,当您使用GridSearchCV时,建议进行多次尝试。找到最高Alpha的区域,然后进行更详细的检查。
以我的经验,尤其是在使用Lasso时,选择最低的非零参数是一个常见的错误,而实际上,最佳参数要小得多。请参阅下面的示例。
注意:当然,我们永远不会使用网格搜索方法找到实际的最佳数字,但是我们可以足够接近。
您还可以可视化结果。这是未缩放版本的样子:
对于每个Alpha,GridSearchCV都适合模型,我们选择了Alpha,其中验证数据得分(例如,RepeatedKFold中测试折叠的平均得分)最高。在此示例中,您可以看到0到0.01之间可能没有疯狂的峰值。当然,这仍然是错误的,因为我们没有缩放。
这是缩放版本的图:
再次看起来不错,在0.07和0.09之间可能没有任何奇怪的事情发生。
总结:可视化是你的朋友,请观察alpha曲线。确保您选择的Alpha位于漂亮的“弯曲”区域。
秘诀四:仔细考虑您的计分方法
您可能很想以其他方式进行计算以检查结果。如前所述,sklearn通常有很多不同的方法来计算同一件事。首先,有一个LassoCV方法将Lasso和GridSearchCV结合在一起。
您可以尝试执行以下操作以获得最佳Alpha(示例中不再使用未缩放的版本):
lasso=LassoCV(alphas=lasso_alphas, cv=cv, n_jobs=-1) lasso.fit(X_scaled, y) print('alpha: %.2f'%lasso.alpha_)
结果如下:
alpha: 0.03
等一下,难道不是上面的0.08的相同数据的Alpha吗?是的。差异的原因是什么?LassoCV使用R²得分,您无法更改它,而在更早的时候,我们在GridSearchCV对象中指定了MAE(正负MAE,但这只是为了使我们最大化并保持一致)。这是为什么说上个代码错误的原因:
scoring='neg_mean_absolute_error'
问题是,sklearn有数十种计分方法,您也可以选择max_error来衡量模型的性能。但是,该模型针对平方差进行了优化。但是我认为使用从平方差得出的任何东西都更加一致。,因为LassoCV使用R²,所以也许这是一个好的信号?
“在一个基础上进行优化,然后在另一个基础上进行性能比较”实际上在上面的图表中是很明显的。注意绿线的评分高了很多。那是因为这是训练的成绩。在正常情况下,施加惩罚因素后,它的性能不应更好。
通常,这就是您将看到的曲线的形状。训练数据得分立即下降,验证数据得分上升一段时间,然后下降:
总结:使用R²或另一个基于差异的平方模型作为回归的主要评分。