线性回归 正则项(惩罚项)原理、正则项的分类与Python代码的实现

简介: 线性回归 正则项(惩罚项)原理、正则项的分类与Python代码的实现

1 正则项的含义

在线性回归中,正则项是一种用于控制模型复杂度的技术,它通过将系数的大小加入到损失函数中,以限制模型的复杂度。在线性回归中,通常使用L1正则项或L2正则项。正则项的形式可以表示为:


L1正则项(Lasso):


image.png

L2正则项(Ridge):


image.png


其中,p pp是系数的数量,w i w_iw

i

是第i ii个系数,λ \lambdaλ是正则化参数,用于控制正则化的强度。


L1正则项将系数的绝对值之和作为正则化项,可以促使模型中的某些系数变为0,从而实现特征选择的效果。这意味着,L1正则项可以在模型中选择最重要的特征,从而提高模型的泛化能力。


L2正则项将系数的平方和作为正则化项,可以防止模型中的系数过大,从而减少模型的过拟合。L2正则项在许多机器学习任务中都被广泛使用。


以L2正则项为例,加入正则项前,损失函数为:


image.pngimage.png

image.png

加入正则项后,损失函数变为:

image.png

其中,h w ( x ( i ) ) h_w(x^{(i)})h w (x (i) )是预测值,y ( i ) y^{(i)}y (i) 是实际值,w j w_jw j 是第j jj个特征的权重,λ \lambdaλ是正则化参数,用于控制正则化的强度。


这就意味着,在模型拟合中,将会寻找模型在训练集的表现与模型复杂度之中的平衡点。在实践中,通常使用交叉验证来选择最佳的正则化参数λ \lambdaλ,以获得最好的性能和泛化能力。正则项是一种非常有效的技术,可以帮助解决过拟合问题,并提高模型的泛化能力。


2 L1与L2正则项的区别

除了前面提到的L1与L2在算法上的区别之外,还有一个重要的区别在于L1正则项的解不是唯一的,而L2正则项的解是唯一的。这是由于L1正则项的正则化图形是一个菱形,其边界在坐标轴上,而L2正则项的正则化图形是一个圆形,其边界是一个平滑的曲线。这个区别使得L1正则项的解在特定情况下可能不是唯一的。具体见下图:


721687ab1ab9c8987dd36cf41cf8a740.png




同时,这一图片也解释了为什么L1正则可以在模型中选择最重要的特征,因其交点更容易出现在坐标轴上,而坐标轴上的点意味着某个θ \thetaθ变为了0。


通常情况下很难说L1和L2正则哪个更好,因此出现了Elastic Net正则化技术,即把L1正则和L2正则结合起来。


Elastic Net的正则化项可以表示为:


image.png

image.png

其中,λ 1 \lambda_1λ 1 和λ 2 \lambda_2λ 2 分别是L1正则项和L2正则项的正则化参数p pp是系数的数量,w i w_iw i 是第i ii个系数。


Elastic Net的主要优点是可以克服L1和L2正则项各自的缺点,并同时利用它们的优点。通过调整L1和L2正则项的权重,可以控制特征选择和平滑效果之间的权衡,从而实现更好的性能和泛化能力。


3 正则的python实现

3.1 Lasso 正则

使用from sklearn.linear_model import Lasso即可导入Lasso回归的包,之后的建模顺序如下:


导入所需的库和数据(这里和上篇博客一样,也是用波士顿房价)

from sklearn.linear_model import Lasso
from sklearn.datasets import load_boston
boston = load_boston()
X = boston.data
y = boston.target


创建Lasso模型对象

lasso = Lasso(alpha=1.0)
1

拟合模型

lasso.fit(X, y)

1

访问模型的系数

print(lasso.coef_)
1

预测

y_pred = lasso.predict(X)
1

模型性能评价

from sklearn.metrics import r2_score
print(r2_score(y, y_pred))


这段函数的输出为:



d5bdf12428fc751693d95c4632029fef.png



可以看到,部分θ \thetaθ的值为0,加入Lasso正则化成功的起到了特征筛选的作用。


3.2 Ridge正则

在python中使用from sklearn.linear_model import Ridge即可使用Ridge回归,之后的模型训练与使用与Lasso完全相同,非常的简单,这里就不重复讲解。

同样使用波士顿数据集,Ridge正则的代码结果为:


b7041ce48cf3d49ecc2828c38d22ca22.png



可以看到,这次的θ \thetaθ不再有零值了,但是不重要的特征所对应的θ \thetaθ变得非常小。起到了前面所说的防止模型中的系数过大,从而减少模型的过拟合作用。


3.3 Elastic Net正则

在python中使用from sklearn.linear_model import ElasticNet即可使用Elastic Net回归。与前面两个方法1相比,在创建类市Elastic Net多了一个接收参数:


elastic_net = ElasticNet(alpha=1.0, l1_ratio=0.5)
1

L1_ratio参数控制L1正则化和L2正则化之间的权重,取值在0-1之间。取1即等同于Lasso,取0等同于Ridge。其他部分的方法与上面也完全一致。


4 案例实例

下面我们使用波士顿房价数据集进行对比三种正则的表现。

首先,我们导入数据,并对数据进行二阶多项式扩展。这里二项式扩展一是为了复习上一篇博客的内容,二是为了模拟日常项目中遇到的无用特征过多的情况。


import numpy as np  
from sklearn.datasets import load_boston  
from sklearn.preprocessing import PolynomialFeatures  
from sklearn.linear_model import LinearRegression, Lasso, Ridge, ElasticNet  
from sklearn.model_selection import cross_val_score, KFold
# 加载波士顿房价数据集  
boston = load_boston()  
X = boston.data  
y = boston.target  
# 进行2阶多项式扩展  
poly = PolynomialFeatures(degree=2, include_bias=False)  
X_poly = poly.fit_transform(X)



随后,分别定义定义LinearRegression、Lasso、Ridge、ElasticNet模型。这里Ridge回归的惩罚系数给的非常高,远高于另外两种模型。这是因为博主对这个数据集已经进行过尝试,找到了合适的超参范围。实际项目中,建议根据实际情况进行网格搜索(GridSearch)。


# 定义LinearRegression、Lasso、Ridge、ElasticNet模型  
lr = LinearRegression()  
lasso = Lasso(alpha=1.0)  
ridge = Ridge(alpha=100.0)  
elastic_net = ElasticNet()


为了对模型的评价更加客观,我们使用5折交叉验证,评估模型的表现。


# 定义5折交叉验证  
cv = KFold(n_splits=5, shuffle=True, random_state=1)  
# 使用交叉验证评估模型性能  
scores_lr = cross_val_score(lr, X_poly, y, scoring='r2', cv=cv)  
scores_lasso = cross_val_score(lasso, X_poly, y, scoring='r2', cv=cv)  
scores_ridge = cross_val_score(ridge, X_poly, y, scoring='r2', cv=cv)  
scores_elastic_net = cross_val_score(elastic_net, X_poly, y, scoring='r2', cv=cv)



最后,计算并输出每个模型的分数,选择最佳的模型。


# 计算交叉验证的R平方分数  
r2_lr = np.mean(scores_lr)  
r2_lasso = np.mean(scores_lasso)  
r2_ridge = np.mean(scores_ridge)  
r2_elastic_net = np.mean(scores_elastic_net)  
# 输出每个模型的R平方分数  
print('Linear Regression R2:', r2_lr)  
print('Lasso R2:', r2_lasso)  
print('Ridge R2:', r2_ridge)  
print('ElasticNet R2:', r2_elastic_net)


这段代码的整体输出结果为:


f3a3d112ff441f822f0eb384ab87a41b.png

可以看到各个模型的表现相差不大。这主要是因为波士顿数据集量足够且相对规范,各个模型的表现均较为良好。同时,我们也没有选择各个模型的最佳超参数。


最后提醒大家,如果需要使用模型的话,需要将最佳的模型与超参数取出,重新训练。因为在cv过程中,我们得到了5个模型,无法判断那个最佳,最好是使用全部数据集再训练一次。


相关文章
|
2天前
|
缓存 开发者 Python
探索Python中的装饰器:简化和增强你的代码
【10月更文挑战第32天】 在编程的世界中,简洁和效率是永恒的追求。Python提供了一种强大工具——装饰器,它允许我们以声明式的方式修改函数的行为。本文将深入探讨装饰器的概念、用法及其在实际应用中的优势。通过实际代码示例,我们不仅理解装饰器的工作方式,还能学会如何自定义装饰器来满足特定需求。无论你是初学者还是有经验的开发者,这篇文章都将为你揭示装饰器的神秘面纱,并展示如何利用它们简化和增强你的代码库。
|
3天前
|
机器学习/深度学习 自然语言处理 API
如何使用阿里云的语音合成服务(TTS)将文本转换为语音?本文详细介绍了从注册账号、获取密钥到编写Python代码调用TTS服务的全过程
如何使用阿里云的语音合成服务(TTS)将文本转换为语音?本文详细介绍了从注册账号、获取密钥到编写Python代码调用TTS服务的全过程。通过简单的代码示例,展示如何将文本转换为自然流畅的语音,适用于有声阅读、智能客服等场景。
20 3
|
1天前
|
搜索推荐 Python
快速排序的 Python 实践:从原理到优化,打造你的排序利器!
本文介绍了 Python 中的快速排序算法,从基本原理、实现代码到优化方法进行了详细探讨。快速排序采用分治策略,通过选择基准元素将数组分为两部分,递归排序。文章还对比了快速排序与冒泡排序的性能,展示了优化前后快速排序的差异。通过这些分析,帮助读者理解快速排序的优势及优化的重要性,从而在实际应用中选择合适的排序算法和优化策略,提升程序性能。
6 1
|
5天前
|
设计模式 缓存 测试技术
Python中的装饰器:功能增强与代码复用的艺术####
本文将深入探讨Python中装饰器的概念、用途及实现方式,通过实例演示其如何为函数或方法添加新功能而不影响原有代码结构,从而提升代码的可读性和可维护性。我们将从基础定义出发,逐步深入到高级应用,揭示装饰器在提高代码复用性方面的强大能力。 ####
|
3天前
|
算法 IDE API
Python编码规范与代码可读性提升策略####
本文探讨了Python编码规范的重要性,并深入分析了如何通过遵循PEP 8等标准来提高代码的可读性和可维护性。文章首先概述了Python编码规范的基本要求,包括命名约定、缩进风格、注释使用等,接着详细阐述了这些规范如何影响代码的理解和维护。此外,文章还提供了一些实用的技巧和建议,帮助开发者在日常开发中更好地应用这些规范,从而编写出更加清晰、简洁且易于理解的Python代码。 ####
|
6天前
|
缓存 测试技术 数据安全/隐私保护
探索Python中的装饰器:简化代码,增强功能
【10月更文挑战第29天】本文通过深入浅出的方式,探讨了Python装饰器的概念、使用场景和实现方法。文章不仅介绍了装饰器的基本知识,还通过实例展示了如何利用装饰器优化代码结构,提高代码的可读性和重用性。适合初学者和有一定经验的开发者阅读,旨在帮助读者更好地理解和应用装饰器,提升编程效率。
|
10天前
|
算法 测试技术 开发者
在Python开发中,性能优化和代码审查至关重要。性能优化通过改进代码结构和算法提高程序运行速度,减少资源消耗
在Python开发中,性能优化和代码审查至关重要。性能优化通过改进代码结构和算法提高程序运行速度,减少资源消耗;代码审查通过检查源代码发现潜在问题,提高代码质量和团队协作效率。本文介绍了一些实用的技巧和工具,帮助开发者提升开发效率。
14 3
|
10天前
|
设计模式 开发者 Python
Python编程中的设计模式:工厂方法模式###
本文深入浅出地探讨了Python编程中的一种重要设计模式——工厂方法模式。通过具体案例和代码示例,我们将了解工厂方法模式的定义、应用场景、实现步骤以及其优势与潜在缺点。无论你是Python新手还是有经验的开发者,都能从本文中获得关于如何在实际项目中有效应用工厂方法模式的启发。 ###
|
3天前
|
存储 人工智能 数据挖掘
从零起步,揭秘Python编程如何带你从新手村迈向高手殿堂
【10月更文挑战第32天】Python,诞生于1991年的高级编程语言,以其简洁明了的语法成为众多程序员的入门首选。从基础的变量类型、控制流到列表、字典等数据结构,再到函数定义与调用及面向对象编程,Python提供了丰富的功能和强大的库支持,适用于Web开发、数据分析、人工智能等多个领域。学习Python不仅是掌握一门语言,更是加入一个充满活力的技术社区,开启探索未知世界的旅程。
12 5
|
3天前
|
人工智能 数据挖掘 开发者
探索Python编程:从基础到进阶
【10月更文挑战第32天】本文旨在通过浅显易懂的语言,带领读者从零开始学习Python编程。我们将一起探索Python的基础语法,了解如何编写简单的程序,并逐步深入到更复杂的编程概念。文章将通过实际的代码示例,帮助读者加深理解,并在结尾处提供练习题以巩固所学知识。无论你是编程新手还是希望提升编程技能的开发者,这篇文章都将为你的学习之旅提供宝贵的指导和启发。

热门文章

最新文章