一天一个机器学习小知识——Lasso、Ridge以及ElasticNet


前言

上一小节主要介绍了线性回归算法,并且在文章的末尾提到了它所存在的一些缺陷,事实上在线性回归的基础上稍作改进就可以很好的客服这些缺陷。因此本小节主要介绍线性回归的几个拓展模型:Lasso、Ridge以及ElasticNet(弹性网)

一、算法推导

李航老师的《统计学习方法》中提到,统计学习方法都是由模型策略算法构成的,因此本文在算法推导也主要从这三部分进行展开讨论。

1.1 Lasso模型

模型通俗来说就是最后要得到一个什么样的方程。Lasso是线性回归的一个拓展,其模型与线性回归模型一样,最终都是得到一个线性方程:
f ( x ) = w 0 T x + b = w T x f(x) = w_{0}^Tx + b=w^Tx f(x)=w0Tx+b=wTx
其中在训练阶段 f ( x ) 和 x f(x)和x f(x)x都是已知的, w 和 b w和b wb是需要估计的参数。

1.2 Lasso策略

有了模型,接下来就需要考虑按照什么样准则学习或选择最优的模型。选择最优模型的原则一般是最小化损失函数,所以策略其实是给出损失函数。Lasso是在线性回归的损失函数基础上,加入了L1惩罚项,可以实现变量筛选(降维),缓解过拟合问题
Lasso损失函数:
J ( w ) = 1 m ∑ i = 1 m ( w T x i − y i ) 2 + λ ∣ ∣ w ∣ ∣ 1 J(w)=\frac{1}{m} \sum_{i=1}^{m}\left(w^Tx_{i}-y_{i}\right)^{2} + \lambda||w||_{1} J(w)=m1i=1m(wTxiyi)2+λw1
其中 f ( x i ) f(x_{i}) f(xi)是模型的预测值, y i y_{i} yi是真实值。
w w w的L1范数是 w w w每个向量的绝对值之和,从直观上理解,Lasso的损失函数比普通的线性回归的损失函数多了一项约束,而 1 m ∑ i = 1 m ( f ( x i ) − y i ) 2 \frac{1}{m} \sum_{i=1}^{m}\left(f\left(\boldsymbol{x}_{i}\right)-y_{i}\right)^{2} m1i=1m(f(xi)yi)2可以看成是一个椭圆,最小化loss就等价于在满足约束下,求 1 m ∑ i = 1 m ( f ( x i ) − y i ) 2 \frac{1}{m} \sum_{i=1}^{m}\left(f\left(\boldsymbol{x}_{i}\right)-y_{i}\right)^{2} m1i=1m(f(xi)yi)2的最小值。如下图所示:
在这里插入图片描述
红色菱形就是L1范数的约束,最终最优解会落在菱形的顶点处。在上图中,最优解如果落在上面的顶点,会导致w2=0,此时 x 2 x_{2} x2将对最终的模型不产生作用,从而达到了变量筛选(降维)的效果。

1.3 Lasso算法

算法部分就是通过最小化Loss来求出参数 w w w,Lasso的损失函数中包含有绝对值,无法直接求导,从而经典的梯度下降就不可用了。替代方法有坐标下降法和最小角回归,这里简单介绍一下前一个。坐标下降法其实也是一个迭代算法,它跟梯度下降最大的区别是,梯度下降是沿着负梯度的方向去更新参数,而坐标下降是沿着坐标轴的方向去更新参数,所以坐标下降法每一次都是固定其他k-1个维度,然后更新剩下的一个维度,如此反复,直到所有的坐标都收敛,其实这跟支持向量机中使用的序列最小优化算法(SMO)是一样的想法。由于是迭代法,所以不存在像线性回归那样的显式解。

2.1 Ridge模型

Ridge也是线性回归的一个拓展,其模型与线性回归模型一样,最终都是得到一个线性方程:
f ( x ) = w 0 T x + b = w T x f(x) = w_{0}^Tx + b=w^Tx f(x)=w0Tx+b=wTx
其中在训练阶段 f ( x ) 和 x f(x)和x f(x)x都是已知的, w 和 b w和b wb是需要估计的参数。

2.2 Ridge策略

Rigde是在线性回归的损失函数的基础上,加入了L2惩罚项,可以解决共线性问题
Ridge损失函数:
J ( w ) = 1 m ∑ i = 1 m ( w T x i − y i ) 2 + λ ∣ ∣ w ∣ ∣ 2 2 J(w)=\frac{1}{m} \sum_{i=1}^{m}\left(w^Tx_{i}-y_{i}\right)^{2} + \lambda||w||^{2}_{2} J(w)=m1i=1m(wTxiyi)2+λw22
其中 f ( x i ) f(x_{i}) f(xi)是模型的预测值, y i y_{i} yi是真实值。
w w w的L2范数是 w w w每个向量的平方和之和,从直观上理解,Ridge的损失函数比普通的线性回归的损失函数多了一项约束,而 1 m ∑ i = 1 m ( f ( x i ) − y i ) 2 \frac{1}{m} \sum_{i=1}^{m}\left(f\left(\boldsymbol{x}_{i}\right)-y_{i}\right)^{2} m1i=1m(f(xi)yi)2可以看成是一个椭圆,最小化loss就等价于在满足约束下,求 1 m ∑ i = 1 m ( f ( x i ) − y i ) 2 \frac{1}{m} \sum_{i=1}^{m}\left(f\left(\boldsymbol{x}_{i}\right)-y_{i}\right)^{2} m1i=1m(f(xi)yi)2的最小值。如下图所示:
在这里插入图片描述
红色椭圆形就是L2范数的约束,最终最优解不一定落在顶点处。所以L2不具备变量筛选的功能,但是为什么可以解决共线性问题呢?

2.3 Ridge算法

上一小节我们推导出线性回归参数的最优解
w ∗ = ( X T X ) − 1 X T y w^{*}=\left(X^{T} X\right)^{-1} X^{T} y w=(XTX)1XTy
当变量之间存在共线性的时候, X T X X^TX XTX就不是满秩的,换言之 X T X X^TX XTX不可逆。但是我们通过对Ridge的 J ( w ) J(w) J(w)求导,并令其等于0,可以发现,通过加入L2惩罚项
w ∗ = ( X T X + λ I ) − 1 X T y w^{*}=\left(X^{T} X+\lambda I\right)^{-1} X^{T} y w=(XTX+λI)1XTy
其中 I I I是一个单位矩阵,可以看到Ridge跟普通线性回归的区别主要在于求逆的时候多加了一个 λ I \lambda I λI矩阵,加入这个之后会使得 ( X T X + λ I ) (X^{T}X+\lambda I) XTX+λI变得可逆,从而解决了共线性带来矩阵不可逆的问题。另一方面, λ I \lambda I λI是一个单位矩阵乘以一个实数,所以它看起来像一条脊,因此叫做Ridge回归(Rigde的翻译叫岭、脊)。

**ElasticNet(弹性网)**是Lasso和Ridge的结合,它在线性回归的基础上同时加入了L1和L2惩罚项,同时具备变量筛选和解决共线性的功能,由于它的模型、策略和算法与Lasso以及Ridge差不多,这里就不再花篇幅进行赘述了。

二、应用场景

Lasso作为线性回归的拓展,并且具备特征选择的能力,在现阶段经济学中应用的比较多。
Ridge主要用于解决变量之间的共线性问题,因此当数据之间的相关性不叫明显的时候,可以尝试使用Ridge回归。

三、代码实现

这里主要使用sklearn这个库来实现机器学习算法。

1.导入相关库

from sklearn.linear_model import Lasso
from sklearn.model_selection import train_test_split
from sklearn.model_selection import cross_val_score
from sklearn.datasets import fetch_california_housing
from sklearn.metrics import mean_squared_error
import pandas as pd
import numpy as np

2.读取样例数据

data = fetch_california_housing() # 获取样例数据,这里的数据是加利福利亚的放假数据
X = pd.DataFrame(data.data,columns=data.feature_names)
y = data.target

在这里插入图片描述

"""
MedInc:该街区住户的收入中位数
HouseAge:该街区房屋使用年代的中位数
AveRooms:该街区平均的房间数目
AveBedrms:该街区平均的卧室数目
Population:街区人口
AveOccup:平均入住率
Latitude:街区的纬度
Longitude:街区的经度
"""

3.划分训练集和测试集

X_train, X_test, y_train, y_test =train_test_split(X,y,test_size=0.3,random_state=0)

4.建立模型

lasso_ = Lasso(alpha=0.05).fit(X_train,y_train)
ridge_ = Ridge(alpha=0.05).fit(X_train,y_train)
elast_ = ElasticNet(alpha=0.05,l1_ratio=0.5).fit(X_train,y_train)
las_pred = lasso_.predict(X_test)
rid_pred = ridge_.predict(X_test)
ela_pred = elast_.predict(X_test)
最终模型参数

为了对比普通线性回归和Lasso的结果,我这里把上一小结的结果粘贴了过来,可以看到相比于普通的线性回归,Lasso得到的系数中会有部分的系数等于0,这说明了Lasso起到变量筛选的效果。

普通线性回归得到的系数
在这里插入图片描述
Lasso得到的系数
在这里插入图片描述
Ridge得到的系数
在这里插入图片描述
ElasticNet得到的系数
在这里插入图片描述

5.评估模型

计算均方误差MSE

print('Lasso MSE:%.3f'%(mean_squared_error(y_test,las_pred)))
print('Rigde MSE:%.3f'%(mean_squared_error(y_test,rid_pred)))
print('ElasticNet MSE:%.3f'%(mean_squared_error(y_test,ela_pred)))
Lasso MSE:0.574
Rigde MSE:0.543
ElasticNet MSE:0.565

其实上面用的方法是留出法,我们也可以使用交叉验证法来计算模型误差。这样就把划分训练集和测试集、建立模型以及评估模型这几步合并在一起。

las_mse = -np.mean(cross_val_score(Lasso(alpha=0.01),X,y,cv=10,scoring='neg_mean_squared_error'))
print('Lass MSE:%.3f'%(las_mse))
rid_mse = -np.mean(cross_val_score(Ridge(alpha=0.01),X,y,cv=10,scoring='neg_mean_squared_error'))
print('Lass MSE:%.3f'%(rid_mse))
ela_mse = -np.mean(cross_val_score(ElasticNet(alpha=0.05,l1_ratio=0.5),X,y,cv=10,scoring='neg_mean_squared_error'))
print('Lass MSE:%.3f'%(ela_mse))
Lass MSE:0.557
Lass MSE:0.551
Lass MSE:0.575

但值得注意的是,Lasso和ElasticNet模型的测试误差并没有比普通的线性回归低,这主要是因为这里的特征个数较少,并且每个变量都对模型起作用,所以Lasso强行把系数压缩至0并不是一种很合适的做法。Lasso更适合与那种特征数量很多的应用场景。同时也说明了模型并不是越复杂越好,没有最好的模型,只有最合适的模型,有时候拿神经网络硬train一发的效果并不就见得比简单的线性回归好。

四、优缺点

1.优点

Lasso
(1)可解释性强,可以清晰的知道每个特征对模型的影响
(2)简单快速
Ridge
(1)可解释性强,可以解决共线性问题
(2)加入L2惩罚项,一定程度上缓解了过拟合的问题

2.缺点

Lasso
(1)只适用于数据之间的线性关系,但现实生活中大多数特征之间的关系是非线性的。
(2)需要满足一些假设,特征之间不能存在共线性
Ridge
(1)不具备变量筛选功能
(2)本质上仍然是一个线性回归,无法解决非线性问题

  • 8
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值