Lasso 和 Ridge回归中的超参数调整技巧(上)

简介: Lasso 和 Ridge回归中的超参数调整技巧

640.png

640.png

在这篇文章中,我们将首先看看Lasso和Ridge回归中一些常见的错误,然后我将描述我通常采取的步骤来优化超参数。代码是用Python编写的,我们主要依赖scikit-learn。本文章主要关注Lasso的例子,但其基本理论与Ridge非常相似。

起初,我并没有真正意识到需要另一个关于这个主题的指南——毕竟这是一个非常基本的概念。然而,当我最近想要确认一些事情时,我意识到,市面上的很多文章要么太学术化,要么太简单,要么就是完全错误。一个很常见的混淆来源是,在sklearn中总是有十多种不同的方法来计算同一件事情。

所以,废话少说,下面是我对这个话题的两点看法。

快速的理论背景回顾

Lasso和Ridge都是正则化方法,他们的目标是通过引入惩罚因子来正则化复杂的模型。它们在减少过拟合、处理多重共线性或自动特征工程方面非常出色。这听i来似乎有点神奇,但通过训练使模型更努力地拟合数据,我们得到一个更好的对底层结构的了解,从而对测试数据有了更好的泛化和更好的拟合。

LinearRegression

根据sklearn的公式,这是线性回归模型中最小的表达式,即所谓的普通最小二乘:

640.png

其中X矩阵为自变量,w为权重即系数,y为因变量。

Ridge

Ridge回归采用这个表达式,并在平方系数的最后添加一个惩罚因子:

640.png

这里α是正则化参数,这是我们要优化的。该模型惩罚较大的系数,并试图更平均地分配权重。用外行人的话来说,这就是Ridge模型所做的:

X1,我们看到你做得很好,如果不是因为惩罚的因素,我们会很重视你。但是X2只比你们差一点点,如果我们在你们俩之间均分权重,我们会得到更低的惩罚,从而得到更好的总分。

Lasso

Lasso做了类似的事情,但使用绝对值之和(l1范数)的权重作为惩罚。

注: sklearn提供公式中还有一个n_samples,这是观察的数量,并且应该改变X和y。我发现没有解释这是为什么,也许是为了比较不同模型。

640.png

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时,选择最低的非零参数是一个常见的错误,而实际上,最佳参数要小得多。请参阅下面的示例。

注意:当然,我们永远不会使用网格搜索方法找到实际的最佳数字,但是我们可以足够接近。

您还可以可视化结果。这是未缩放版本的样子:

640.png

对于每个Alpha,GridSearchCV都适合模型,我们选择了Alpha,其中验证数据得分(例如,RepeatedKFold中测试折叠的平均得分)最高。在此示例中,您可以看到0到0.01之间可能没有疯狂的峰值。当然,这仍然是错误的,因为我们没有缩放。

这是缩放版本的图:

640.png

再次看起来不错,在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²,所以也许这是一个好的信号?

“在一个基础上进行优化,然后在另一个基础上进行性能比较”实际上在上面的图表中是很明显的。注意绿线的评分高了很多。那是因为这是训练的成绩。在正常情况下,施加惩罚因素后,它的性能不应更好。

通常,这就是您将看到的曲线的形状。训练数据得分立即下降,验证数据得分上升一段时间,然后下降:

640.png

总结:使用R²或另一个基于差异的平方模型作为回归的主要评分。

目录
相关文章
|
Rust 安全 编译器
Rust中的生命周期与借用检查器:内存安全的守护神
本文深入探讨了Rust编程语言中生命周期与借用检查器的概念及其工作原理。Rust通过这些机制,在编译时确保了内存安全,避免了数据竞争和悬挂指针等常见问题。我们将详细解释生命周期如何管理数据的存活期,以及借用检查器如何确保数据的独占或共享访问,从而在不牺牲性能的前提下,为开发者提供了强大的内存安全保障。
|
数据采集 运维 数据挖掘
一文速学-Pandas异常值检测及处理操作各类方法详解+代码展示
一文速学-Pandas异常值检测及处理操作各类方法详解+代码展示
1725 0
一文速学-Pandas异常值检测及处理操作各类方法详解+代码展示
|
机器学习/深度学习 数据采集 算法
解码癌症预测的密码:可解释性机器学习算法SHAP揭示XGBoost模型的预测机制
解码癌症预测的密码:可解释性机器学习算法SHAP揭示XGBoost模型的预测机制
1024 0
|
自然语言处理 数据可视化 数据挖掘
基于词云图+Kmeans聚类+LDA主题分析+社会网络语义分析对大唐不夜城用户评论进行分析(下)
基于词云图+Kmeans聚类+LDA主题分析+社会网络语义分析对大唐不夜城用户评论进行分析
563 0
|
算法 前端开发 Java
信创环境下达梦数据库唯一索引异常无法拦截DuplicateKeyException
迁移到达梦数据库后,发现我们的全局异常拦截中的唯一索引异常 无法被正常拦截,给前端直接抛出了数据库原始的错误信息,对用户极其不友好。如果不对唯一索引异常拦截,则默认 与 的异常信息如下:在 中通过 注解,实现对异常响应的统一封装。可参考:全栈开发之后端脚手架:SpringBoot集成MybatisPlus代码生成,分页,雪花算法,统一响应,异常拦截,Swagger3接口文档以下是对数据库唯一索引异常的拦截,统一返回:编号不可重复。 问题分析 对主流的数据库的异常进行了封装与翻译,对于 都可以进行拦截,但是到了国产数据库,比如这里是达梦8,那么其异常信息 `Spring` 就不认识
2222 0
|
存储 机器学习/深度学习 数据可视化
数据集中存在大量的重复值,会对后续的数据分析和处理产生什么影响?
数据集中存在大量重复值可能会对后续的数据分析和处理产生多方面的负面影响
731 56
|
大数据 UED 开发者
实战演练:利用Python的Trie树优化搜索算法,性能飙升不是梦!
在数据密集型应用中,高效搜索算法至关重要。Trie树(前缀树/字典树)通过优化字符串处理和搜索效率成为理想选择。本文通过Python实战演示Trie树构建与应用,显著提升搜索性能。Trie树利用公共前缀减少查询时间,支持快速插入、删除和搜索。以下为简单示例代码,展示如何构建及使用Trie树进行搜索与前缀匹配,适用于自动补全、拼写检查等场景,助力提升应用性能与用户体验。
272 2
|
存储 编解码 算法
栅格数据矢量化(附有完整代码)
栅格数据矢量化(附有完整代码)
|
机器学习/深度学习 数据采集 人工智能
【机器学习】集成学习(Bagging)——随机森林(RandomForest)(理论+图解+公式推导)
【机器学习】集成学习(Bagging)——随机森林(RandomForest)(理论+图解+公式推导)
1616 0
【机器学习】集成学习(Bagging)——随机森林(RandomForest)(理论+图解+公式推导)
|
机器学习/深度学习 算法 Python
【Python 机器学习专栏】随机森林算法的性能与调优
【4月更文挑战第30天】随机森林是一种集成学习方法,通过构建多棵决策树并投票或平均预测结果,具有高准确性、抗过拟合、处理高维数据的能力。关键性能因素包括树的数量、深度、特征选择和样本大小。调优方法包括调整树的数量、深度,选择关键特征和参数优化。Python 示例展示了使用 GridSearchCV 进行调优。随机森林广泛应用于分类、回归和特征选择问题,是机器学习中的重要工具。
898 1