Lasso和Ridge回归中的超参数调整技巧
在这篇⽂章中,我们将⾸先看看Lasso和Ridge回归中⼀些常见的错误,然后我将描述我通常采取的步骤来优化超参数。代码是⽤Python编写的,我们主要依赖。本⽂章主要关注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结合起来。 您需要在那⾥优化两个超参数。 在本指南中,我们将不讨论此选项。
所需要的类库
以下是需要的所有库的列表:
三个秘诀
在本节中,我们将讨论⼀些常规技巧和常见错误,以避免涉及正则化回归。 这些⽰例使⽤的是波⼠顿
住房数据,您可以从Kaggle下载数据。
秘诀⼀:缩放⾃变量
如标题所⽰:需要缩放变量以进⾏正则回归。 (我们知道,像缩放这样的线性变换不会对原始线性回归的预测产⽣影响。)很明显,如果您仔细查看⼀下公式,为什么必须对正则回归进⾏缩放: 变量恰好在很⼩的范围内,其系数会很⼤,因此,由于惩罚会受到更⼤的惩罚。反之亦然,⼤规模变量将获得较⼩的系数,并且受惩罚的影响较⼩。Lasso and Ridge都是如此。
假设您执⾏以下操作。
(同样,该⽰例没有缩放⽐例,将不会产⽣正确的结果,请不要这样做。此外,请注意,除了缩放⽐例以外,还有其他问题,我们将在近期内再次讨论。)
结果如下:
但是,如果事先缩放X变量,通常会获得更好的分数。 要缩放,我们可以使⽤sklearn的StandardScaler。 此⽅法使变量以0为中⼼,并使标准偏差等于1。import pandas as pd import numpy as np import matplotlib.pyplot as plt import aborn as sns ics import \ r2_score, get_scorer from sklearn.linear_model import \ Lasso, Ridge, LassoCV,LinearRegression
from sklearn.preprocessing import \ StandardScaler, PolynomialFeatures del_lection import \ KFold, RepeatedKFold, GridSearchCV, \ cross_validate, train_test_split
1
2
34
5
6
7
8
9
10
11
12
13column_names = \ ['CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE',\ 'DIS', 'RAD', 'TAX', 'PTRATIO', 'B', 'LSTAT', 'MEDV']data = pd.read_csv("../datats/housing.csv", \ header=None, delimiter=r"\s+", names=column_names)y = data['MEDV']X = data.drop(['MEDV'], axis = 1)
1
关于坚持的名言警句
2新加坡旅游景点
3
孕妇能不能吃红枣45
6
7# 错误,不要使⽤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_alphas gscv = 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_)
1
2
3
4
5
6
7
8
9
10MAE: -3.37896Config: {'alpha': 0.01}
1
2sc = StandardScaler()X_scaled = sc.fit_transform(X)X_scaled = pd.DataFrame(data = X_scaled, columns = X.columns)
1
2
如果在上⾯的代码块中⽤X_scaled替换X,我们将得到:
是的,没有太⼤的改进,但这是由于许多因素,我们将在后⾯看到。 最重要的是,波⼠顿的住房数据是⼀个很好的,经过量⾝定制的线性回归的⽰例,因此我们不能做太多改进。
总结:在进⾏正则化之前,使⽤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之间可能没有疯狂的峰值。 当然,这仍然是错误的,因为我们没有缩放。MAE: -3.35080Config: {'alpha': 0.08}
1
2
这是缩放版本的图:
再次看起来不错,在0.07和0.09之间可能没有任何奇怪的事情发⽣。
总结:可视化是你的朋友,请观察alpha曲线。 确保您选择的Alpha位于漂亮的“弯曲”区域。
秘诀四:仔细考虑您的计分⽅法ps怎么填充颜色
您可能很想以其他⽅式进⾏计算以检查结果。 如前所述,sklearn通常有很多不同的⽅法来计算同⼀件事。 ⾸先,有⼀个LassoCV⽅法将Lasso和GridSearchCV结合在⼀起。
您可以尝试执⾏以下操作以获得最佳Alpha(⽰例中不再使⽤未缩放的版本):
结果如下:
等⼀下,难道不是上⾯的0.08的相同数据的Alpha吗? 是的。 差异的原因是什么? LassoCV使⽤R ²得分,您⽆法更改它,⽽在更早的时候,我们在GridSearchCV对象中指定了MAE(正负MAE,但这只是为了使我们最⼤化并保持⼀致)。 这是为什么说上个代码错误的原因:
问题是,sklearn有数⼗种计分⽅法,您也可以选择max_error来衡量模型的性能。 但是,该模型针对平⽅差进⾏了优化。但是我认为使⽤从平⽅差得出的任何东西都更加⼀致。,因为LassoCV使⽤R ²,所以也许这是⼀个好的信号?
“在⼀个基础上进⾏优化,然后在另⼀个基础上进⾏性能⽐较”实际上在上⾯的图表中是很明显的。 注
意绿线的评分⾼了很多。 那是因为这是训练的成绩。 在正常情况下,施加惩罚因素后,它的性能不应更好。lasso = LassoCV(alphas=lasso_alphas, cv=cv, n_jobs=-1)lasso.fit(X_scaled, y)print('alpha: %.2f' % lasso.alpha_)
12
3alpha: 0.03
1scoring='neg_mean_absolute_error'
1
通常,这就是您将看到的曲线的形状。 训练数据得分⽴即下降,验证数据得分上升⼀段时间,然后下降:
总结:使⽤R ²或另⼀个基于差异的平⽅模型作为回归的主要评分。
本⽂的⽅法
qc质量管理
在这⼀节中,我将介绍我⽤来准备数据和拟合正则化回归的⽅法。
在得到X和y之前,我不会详细说明数据。我使⽤来⾃美国县级国家健康排名数据收集的⼀个版本来⽣成下⾯的结果,但对于这个⽰例来说,这真的⽆关紧要。
因此,假设您有⼀个漂亮⽽⼲净的X和y,下⼀步是使⽤⽅便的train_test_split留出⼀个测试数据集。如果想让结果重现,可以为my_random_state选择任何数字。
下⼀步是包含多项式特性。我们将结果保存在多边形对象中,这很重要,我们将在以后使⽤它。
这将产⽣变量的所有⼆阶多项式组合。需要注意的是,我们将include_bias设置为Fal。这是因为我们不需要截距列,回归模型本⾝将包含⼀个截距列。
这是我们转换和重命名X的⽅法。它假设您将X保存在⼀个pandas DataFrame中,并且需要进⾏⼀些调整以保持列名可⽤。如果你不想要名字,你只需要第⼀⾏。X_train , X_test, y_train, y_test = train_test_split( X, y, test_size=1000, random_state=my_random_state)
1
2poly = PolynomialFeatures( degree = 2, include_bias = Fal, interaction_only = Fal)
1
2