(六十一)线性模型:线性回归、岭回归和套索回归

线性回归(OLS)

OLS的原理是,找到当训练集中y的预测值和真实值之差(残差)的平方和最小时,对应的参数(斜率、截距)值。需要使用的模块有:

LinearRegression:线性回归模型;

make_regression(n_samples,n_features,n_informative,noise,random_state):生成数据集,n_samples:样本数,n_features:特征数,n_informative:参与建模特征数,noise:噪音标准差,random_state:若为固定值则每次产生的数据都一样;

train_test_split:将数据集分成训练集和测试集,test_size测试集的比例,默认25%。

from sklearn.linear_model import LinearRegression
from sklearn.datasets import make_regression#生成数据集
from sklearn.model_selection import train_test_split#将数据集分成训练集和测试集

x,y=make_regression(n_samples=100,n_features=2,n_informative=2,noise=10,random_state=8)
#各生成100个x1、x2和y数据点
x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.25)
#划出25%为测试集
lr=LinearRegression().fit(x_train,y_train)#拟合线性回归
print('系数:{}'.format(lr.coef_.round(4)))
print('截距:{:.4f}'.format(lr.intercept_))#结果可能不一样
print('训练集得分:{:.4f}'.format(lr.score(x_train,y_train)))
print('测试集得分:{:.4f}'.format(lr.score(x_test,y_test)))
系数:[ 7.0047 83.5138]
截距:-0.6836
训练集得分:0.9905
测试集得分:0.9872

下面引入一个真实的糖尿病病情数据集(442个样本,10个特征),由于真实数据比我们手工生成的数据要复杂得多,因此训练集和测试集得分都有所下降,且训练集得分更高、二者相差越大代表模型的过拟合问题越严重。为了更好地控制模型的复杂度,我们可以使用Ridge回归和Lasso回归。

from sklearn.datasets import load_diabetes
x,y=load_diabetes().data,load_diabetes().target
x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.25)
lr=LinearRegression().fit(x_train,y_train)
print('训练集得分:{:.4f}'.format(lr.score(x_train,y_train)))
print('测试集得分:{:.4f}'.format(lr.score(x_test,y_test)))
训练集得分:0.5403
测试集得分:0.3608

岭(Ridge)回归

根据OLS的参数估计过程我们知道,系数向量 β = (XTX)-1(XTY),若存在多重共线性,那么 Xi 就会和其他自变量 Xj 之间存在线性关系,根据矩阵的性质,自变量矩阵X的行列式值为0,因此在估计β时 (XTX)-1因除数为0无法求出。岭回归人为的加入了一个误差项 λI,I为单位矩阵,λ为常数,使得β = (XTX + λI)-1(XTY),对应的最优化问题变为argmin(∑(Y−Xβ) 2 +∑λβ2),当多重共线性严重时,岭回归作为β的估计比最小二乘估计稳定得多。显然当λ=0时的岭回归估计就是普通的最小二乘估计。具体推导过程可参考Magic 杨:岭回归和LASSO回归

通常岭回归方程中的R2会稍低于线性回归,但回归系数的显著性往往更高。对于岭回归而言,λ越大,模型的方差就越小,β 的估计值更加偏离真实值,模型的偏差就越大。所以岭回归的关键是找到一个合理的λ值来平衡模型的方差和偏差。
在这里插入图片描述
在岭回归中,模型会保留所有的特征变量,但是会减小特征变量的系数值(除数变大),让特征变量对预测结果的影响变小,在岭回归中是通过改变其alpha参数(即λ值)来控制特征变量系数减小的程度。而这种通过保留全部特征变量,只是降低特征变量的系数值来避免过拟合的方法,称之为L2正则化。仍然以上述糖尿病数据为例:

from sklearn.linear_model import Ridge
ridge10=Ridge(alpha=10).fit(x_train,y_train)
print('训练集得分:{:.4f}'.format(ridge10.score(x_train,y_train)))
print('测试集得分:{:.4f}'.format(ridge10.score(x_test,y_test)))
训练集得分:0.1564
测试集得分:0.1266

alpha=10时,模型的得分大大降低了,但是训练集和测试集之间的分差也在减小,这说明如果模型出现了过拟合的现象,可以提高alpha值(默认为1)来降低过拟合的程度。较高的alpha值代表模型的限制更加严格,所以在较高的alpha值下,coef_的数值会更小,反之coef_属性的数值更大:

import matplotlib.pyplot as plt
plt.plot(Ridge().fit(x_train,y_train).coef_, 's', label = 'Ridge alpha=1')
plt.plot(ridge10.coef_, '^', label = 'Ridge alpha=10')
plt.plot(Ridge(alpha=0.1).fit(x_train,y_train).coef_, 'v', label = 'Ridge alpha=0.1')
plt.plot(lr.coef_, 'o', label = 'linear regression')
plt.xlabel("coefficient index")
plt.ylabel("coefficient magnitude")
plt.hlines(0,0,len(lr.coef_))#绘制水平线
plt.legend(loc='best')

在这里插入图片描述
可以发现alpha=10时,10个系数值都在0附近徘徊,且系数值随着alpha值的变大而增大,alpha=0.1时,系数值已经十分接近OLS的结果了。

另外,不论是在岭回归中还是在线性回归中,训练数据集的得分都比测试数据集的得分要高。而由于岭回归是经过正则化的模型,因此它训练数据集的得分要比线性回归的得分低。然而,岭回归在测试数据集的得分与训练数据集的得分差异就要小一些,尤其是在数据集比较小的情况下。在数据量小于50条的情况下,线性回归几乎不能让机器学到任何东西。随着数据集的规模越来越大,两个模型的表现也越来越好。不难看出,如果有足够多的数据,那么正则化就显得不是那么重要了,岭回归和线性回归的表现也相差无几。

在这里插入图片描述

套索(Lasso)回归

和岭回归一样,套索回归也会将系数限制在非常接近0的范围内,但它进行限制的方式稍微有一点不同,我们称之为 L1正则化。L1正则化会导致在使用套索回归时,有一部分特征的系数会正好等于0,以突出体现模型中最重要的那些特征,对应的最优化问题变为argmin(∑(Y−Xβ) 2 +∑λ|β|)。与岭回归类似, 套索回归也有一个正则化参数alpha(默认为1),用来控制特征变量系数被约束到0的强度。具体推导过程可参考Magic 杨:岭回归和LASSO回归。仍然使用糖尿病数据集进行套索回归:

import numpy as np
from sklearn.linear_model import Lasso
lasso = Lasso().fit(x_train, y_train)
print("套索回归在训练数据集的得分:{:.2f}".format(lasso.score(x_train, y_train)))
print("套索回归在测试数据集的得分:{:.2f}".format(lasso.score(x_test, y_test)))
print("套索回归使用的特征数:{}".format(np.sum(lasso.coef_ != 0)))
套索回归在训练数据集的得分:0.34
套索回归在测试数据集的得分:0.38
套索回归使用的特征数:3

alpha过大(比如10)时,训练集和测试集得分低,使用的特征数也越少,这表明出现了欠拟合问题。为了降低欠拟合的程度,我们可以降低 alpha 的值。与此同时,我们还需要增加最大迭代次数max_iter。

lasso01 = Lasso(alpha=0.1, max_iter=100000).fit(x_train, y_train)
print("alpha=0.1时套索回归在训练数据集的得分:{:.2f}".format(lasso01.score(x_train, y_train)))
print("alpha=0.1时套索回归在测试数据集的得分:{:.2f}".format(lasso01.score(x_test, y_test)))
print("alpha=0.1时套索回归使用的特征数:{}".format(np.sum(lasso01.coef_ != 0)))
alpha=0.1时套索回归在训练数据集的得分:0.51
alpha=0.1时套索回归在测试数据集的得分:0.50
alpha=0.1时套索回归使用的特征数:7

从结果来看,降低alpha值可以拟合出更复杂的模型,从而在训练数据集和测试数据集都能获得良好的表现。但是,如果我们把alpha值设置得太低,就等于把正则化的效果去除了,那么模型就可能会像线性回归一样,出现过拟合的问题。

总结

在实践当中,岭回归往往是这两个模型中的优选。但是如果你的数据特征过多,而且其中只有一小部分是真正重要的,那么套索回归(L1正则化模型)就是更好的选择,套索回归会让你的模型更容易被理解,因为它只是使用了输入的特征值中的一部分。如果数据集中的特征本来就不多,而且每一个都有重要作用的话,那么就应该使用L2正则化的模型,如岭回归。实践中常用交叉验证(cross validation)的方法找出岭回归或套索回归的最优alpha,可参考Magic 杨:岭回归和LASSO回归

scikit-learn 还提供了一种模型,称为弹性网模型(Elastic Net)。其综合了套索回归和岭回归的惩罚因子。在实践中这两个模型的组合是效果最好的,需要调整L1正则化和L2正则化两个参数。

参考文献

https://blog.csdn.net/weixin_43374551/article/details/83688913
段小手《深入浅出Python机器学习》,清华大学出版社

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值