博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
线性回归原理
阅读量:2242 次
发布时间:2019-05-09

本文共 18495 字,大约阅读时间需要 61 分钟。

线性回归

目录

一、线性回归介绍

二、多元线性回归

1、原理

2、最小二乘法求解多元线性回归的参数

3、sklearn练习

三、回归类模型评估指标

1、是否预测到了正确的数值

2、是否拟合到了足够的信息

四、岭回归和Lasso

1、多重共线性

2、岭回归

3、Lasso

一、线性回归介绍

回归是一种应用广泛的预测建模技术,这种技术的核心在于预测的结果是连续型变量。KNN这样的分类算法的预测标签是分类变量,而无监督学习算法比如KMeans并不求解标签。它可能是机器器学习算法中产生最早的算法之一,其在现实中的应用非常广泛。

线性回归是源于统计分析,是结合机器器学习与统计学的重要算法。通常来说,我们认为统计学注重先验,而机器器学习看重结果,因此机器学习中不会提前为线性回归排除共线性等可能会影响模型的因素,反而会先建立模型以查看效果。模型确立之后,如果效果不好,我们就根据统计学的指导来排除可能影响模型的因素。

回归需求在现实中非常多,所以我们自然也有各种各样的回归类算法。最著名的就是我们的线性回归和逻辑回归,从他们衍生出了了岭回归,Lasso,弹性网(岭回归和Lasso的组合),除此之外,还有众多分类算法改进后的回归,比如回归树,随机森林的回归,支持向量回归,贝叶斯回归等等。除此之外,我们还有各种鲁棒的回归:比如RANSAC,Theil-Sen估计,胡贝尔回归等等。

二、多元线性回归

1、原理

多元线性回归:

y ^ = w 0 + w 1 x 1 + w 2 x 2 + . . . + w n x n \hat{y}=w_0+w_1x_1+w_2x_2+...+w_nx_n y^=w0+w1x1+w2x2+...+wnxn
从矩阵来表示这个方程:
y ^ = X w \hat{y}=Xw y^=Xw
其中可以被看做是一个结构为(n+1,1)的列矩阵, 是一个结构为(m,n+1)的特征矩阵,就是构造一个预测函数来映射输入的特征矩阵和标签值的线性关系,对于这个模型来说,未知数就是w,所以线性回归原理的核心就是找出模型的参数向量w,我们希望找到一组参数w使模型最好的拟合数据,我们使用’‘损失函数’'这个评估指标,来衡量系数为的模型拟合训练集时产生的信息损失的大小,并以此衡量参数的优劣。

衡量参数的优劣的评估指标,用来求解最优参数的工具

损失函数小,模型在训练集上表现优异,拟合充分,参数优秀,
损失函数大,模型在训练集上表现差劲,拟合不足,参数糟糕,
我们追求,能够让损失函数最小化的参数组合。

多元线性回归的损失函数:

∑ i = 1 m ( y i − y ^ ) 2 = ∑ i = 1 m ( y i − X i w ) 2 \sum_{i=1}^{m}(y_i-\hat{y})^2=\sum_{i=1}^{m}(y_i-X_iw)^2 i=1m(yiy^)2=i=1m(yiXiw)2
其中 y i y_i yi是样本对应的真实标签​, y ^ \hat{y} y^也就是 X i w X_iw Xiw样本在一组参数 w w w下的预测标签, m m m代表样本的总量​。

上面说我们说损失函数越小,拟合越好,所以我们损失函数转化成:

m i n ∑ i = 1 m ( y i − X i w ) 2 min\sum_{i=1}^{m}(y_i-X_iw)^2 mini=1m(yiXiw)2
用矩阵可以这么表示:
( y i − X i w ) 2 = ( y − X w ) T ( y − X w ) = ∥ y − X w ∥ 2 2 (y_i-X_iw)^2=(y-Xw)^T(y-Xw)=\left \| y-Xw \right \|_2 ^2 (yiXiw)2=(yXw)T(yXw)=yXw22
矩阵相乘是对应未知元素相乘相加,就会得到和上⾯面的式子一模一样的结果。而这样的矩阵可以转变成L2范式的形式。我们往往称呼这个损失函数为SSE(Sum of Squared Error,误差平方和)或者RSS(Residual Sum of Squares 残差平方和)。在我们的课件中我们称之为RSS,残差平方和。

2、最小二乘法求解多元线性回归的参数

现在问题转化成了求解RSS最小化的参数向量w,这种通过最小化真实值和预测值之间的RSS来求解参数的方法叫做最小二乘法。求解极值的第一步往往是求解一阶导数并让一阶导数等于0。现在残差平方和RSS上对参数向量求导。

接下来,我们就来对求导:

∂ R S S ∂ w = ∂ ∥ y − X w ∥ 2 2 ∂ w \frac{\partial RSS}{\partial w}=\frac{\partial \left \| y-Xw \right \|_2^2}{\partial w} wRSS=wyXw22

= ∂ ( y − X w ) T ( y − X w ) ∂ w =\frac{\partial (y-Xw)^T(y-Xw)}{\partial w} =w(yXw)T(yXw)

∵ ( A − B ) T = A T − B T a n d ( A B ) T = B T ∗ A T \because (A-B)^T=A^T-B^T and (AB)^T=B^T*A^T (AB)T=ATBTand(AB)T=BTAT

∴ = ∂ ( y T − w T X T ) ( y − X w ) ∂ w \therefore =\frac{\partial (y^T-w^TX^T)(y-Xw)}{\partial w} =w(yTwTXT)(yXw)

= ∂ ( y T y − w T X T y − y T X w + w T X T X w ) ∂ w =\frac{\partial (y^Ty-w^TX^Ty-y^TXw+w^TX^TXw)}{\partial w} =w(yTywTXTyyTXw+wTXTXw)

矩阵求导中,a为常数,有如下规则:

∂ a ∂ A = 0 , ∂ A T B T C ∂ A = B T C , ∂ C T B A ∂ A = B T C , ∂ A T B A ∂ A = ( B + B T ) A \frac{\partial a}{\partial A}=0,\frac{\partial A^TB^TC}{\partial A}=B^TC,\frac{\partial C^TBA}{\partial A}=B^TC,\frac{\partial A^TBA}{\partial A}=(B+B^T)A Aa=0,AATBTC=BTC,ACTBA=BTC,AATBA=(B+BT)A

= 0 − X T y − X T y + 2 X T X w =0-X^Ty-X^Ty+2X^TXw =0XTyXTy+2XTXw

= X T X w − X T y =X^TXw-X^Ty =XTXwXTy

让一阶导函数等于0:

X T X w − X T y = 0 X^TXw-X^Ty=0 XTXwXTy=0

X T X w = X T y X^TXw=X^Ty XTXw=XTy

左 乘 一 个 ( X T X ) − 1 则 有 左乘一个(X^TX)^{-1}则有 (XTX)1

w = ( X T X ) − 1 X T y w=(X^TX)^{-1}X^Ty w=(XTX)1XTy
这里左乘了一个 ( X T X ) − 1 (X^TX)^{-1} (XTX)1逆矩阵,首先要逆矩阵存在,存在的充分必要条件是特征矩阵不存在多重共线性,在后面多重共线性再来看这个问题。

假设矩阵的逆是存在的,此时我们的w就是我们参数的最优解,这样我们就可以解除 X w , Xw, Xw也就能计算出我们的预测值 y ^ 了 \hat{y}了 y^

除了多元线性回归的推导之外,这里还需要提到一些在上面的推导过程中不曾被体现出来的问题。在统计学中,使用最小二乘法来求解线性回归的方法是一种’‘无偏估计’'的方法,这种无偏估计要求因变量,也就是标签的分布必须服从正态分布。这是说,我们的y必须经由正太化处理(比如说取对数)。在机器学习中,我们会先考虑模型的效果,如果模型效果不好,那我们可能考虑改变因变量的分布。

3、sklearn练习

class s k l e a r n . l i n e a r sklearn.linear sklearn.linear_ m o d e l . L i n e a r R e g r e s s i o n model.LinearRegression model.LinearRegression $(fit_intercept=True, normalize=False, copy_X=True,

n_jobs=None)

在这里插入图片描述

线性回归的类可能是最简单的类,仅有四个参数就可以完成一个完整的算法。并且看得出,这些参数中并没有一个是必填的,更没有对我们的模型有不可替代作用的参数。这说明,线性回归的性能,往往取决于数据本身,而并非是我们的调参能力力,线性回归也因此对数据有着很高的要求。幸运的是,现实中大部分连续型变量之间,都存在着或多或少的线性联系。所以线性回归虽然简单,却很强大。
而且,sklearn中的线性回归可以处理多标签问题,只需要在fit的时候输入多维度标签就可以了。

from sklearn.linear_model import LinearRegression as LRfrom sklearn.model_selection import train_test_splitfrom sklearn.model_selection import cross_val_scorefrom sklearn.datasets import fetch_california_housing as fch #加利福尼亚房屋价值数据集import pandas as pdhousevalue = fch() #这里需要下载数据# 分开特征和标签X = pd.DataFrame(housevalue.data)  #转换成数据框形式方便查看数据y = housevalue.target # 探索数据X.shape X.columns = housevalue.feature_namesX.head()#划分数据集Xtrain,Xtest,Ytrain,Ytest=train_test_split(X,y,test_size=0.3,random_state=420)for i in [Xtrain, Xtest]:    i.index = range(i.shape[0]) #划分数据集后一定记得重置索引Xtrain.shape #实例化与建模reg = LR().fit(Xtrain,Ytrain)reg.score(Xtest,Ytest)  # 返回分数0.6043,太低没意义,我们使用另外的评估指标R^2#其他接口reg.predict(Xtest) #返回预测值reg.coef_  # 返回系数w,从w1开始reg.intercept_  # 返回截距w0

三、回归类模型评估指标

回归类与分类型算法的模型评估其实是相似的法则——找真实标签和预测值的差异。只不过在分类型算法中,这个差异只有一种角度来评判,那就是否预测到了正确的分类,而在我们的回归类算法中,我们有两种不同的角度来看待回归的效果:

第一,我们是否预测到了正确的数值。
第二,我们是否拟合到了足够的信息。
这两种角度,分别对应着不同的模型评估指标。

1、是否预测到了正确的数值

我们的RSS残差平方和,它的本质是我们的预测值与真实值之间的差异,也就是从第一种角度来评估我们回归的效力,所以RSS既是我们的损失函数,也是我们回归类模型的模型评估指标之一。但是,RSS有着致命的缺点:它是一个无界的和,可以无限地大。我们想要求解最小的RSS,从RSS的公式来看,它不能为负,所以RSS越接近0越好,但是多接近0才算好?为了应对这种状况,sklearn中使用RSS的变体,均方误差MSE(mean squarederror)来衡量我们的预测值和真实值的差异:

M S E = 1 m ∑ i = 1 m ( y i − y ^ i ) 2 MSE=\frac{1}{m}\sum_{i=1}^{m}(y_i-\hat{y}_i)^2 MSE=m1i=1m(yiy^i)2
均方误差,本质是在RSS的基础上除以了样本总量,得到了每个样本量上的平均误差。有了平均误差,就可以将平均误差和标签的取值范围在一起比较,以此获得一个较为可靠的评估依据。在sklearn当中,有两种方式调用这个评估指标,一种是使用sklearn专用的模型评估模块metrics里的类mean_squared_error,另一种是调用交叉验证的类cross_val_score并使用里面的scoring参数来设置
使用均方误差。

from sklearn.metrics import mean_absolute_error as MSEyhat=reg.predict(Xtest)# cross_val_score(reg,X,y,cv=10,scoring="mean_squared_error") 这句会报错,为什么?

线性回归大坑一报错原因:因为均方误差为负,在决策树和随机森林中提到过,均方误差永远为正,,但是sklearn中的参数scoring下,均方误差作为评判标准时,却是计算”负均方误差“(neg_mean_squared_error)。这是因为sklearn在计算模型评估指标的时候,会考虑指标本身的性质,均方误差本身是一种误差,所以被sklearn划分为模型的一种损失(loss)。在sklearn当中,所有的损失都使用负数表示,因此均方误差也被显示为负数了。真正的均方误差MSE的数值,其实就是neg_mean_squared_error去掉负号的数字。

除了MSE,还有MAE(Mean absolute error,绝对均值误差):

M A E = 1 m ∑ i = 0 m − 1 ∣ y i − y ^ i ∣ MAE=\frac{1}{m}\sum_{i=0}^{m-1}\left | y_i-\hat{y}_i \right | MAE=m1i=0m1yiy^i
其表达的概念与均方误差完全一致,不过在真实标签和预测值之间的差异外使用的是L1范式(绝对值)。现实使用中,MSE和MAE选一个来使用就好了。在sklearn当中,使用命令fromsklearn.metrics import mean_absolute_error来调用MAE,同时,也可以使用交叉验证中的scoring = “neg_mean_absolute_error”,以此在交叉验证时调用MAE。

2、是否拟合到了足够的信息

对于回归类算法而言,只探索数据预测是否准确是不足够的。除了数据本身的数值大小之外,我们还希望我们的模型能够捕捉到数据的’‘规律’’,比如数据的分布规律,单调性等等,而是否捕获了了这些信息并无法使用MSE来衡量。

在这里插入图片描述

来看这张图,其中红色线是我们的真实标签,而蓝色线是我们的拟合模型。这是一种比较极端,但的确可能发生的情况。这张图像上,前半部分的拟合非常成功,看上去我们的真实标签和我们的预测结果几乎重合,但后半部分的拟合却非常糟糕,模型向着与真实标签完全相反的方向去了了。对于这样的一个拟合模型,如果我们使用MSE来对它进行判断,它的MSE会很小,因为大部分样本其实都被完美拟合了,少数样本的真实值和预测值的巨大差异在被均分到每个样本上之后,MSE就会很小。但这样的拟合结果必然不是一个好结果,因为一旦我的新样本是处于拟合曲线的后半段的,我的预测结果必然会有巨大的偏差,而这不是我们希望看到的。所以,我们希望找到新的指标,除了判断预测的数值是否正确之外,还能够判断我们的模型是否拟合了足够多的,数值之外的信息,而R方刚好可以。

R 2 = 1 − ∑ i = 0 m ( y i − y ^ i ) 2 ∑ i = 0 m ( y i − y ˉ ) 2 = 1 − R S S ∑ i = 0 M ( y i − y ˉ ) 2 R^{2}=1-\frac{\sum_{i=0}^{m}(y_i-\hat{y}_i)^{2}}{\sum_{i=0}^{m}(y_i-\bar{y})^{2}}=1-\frac{RSS}{\sum_{i=0}^{M}(y_i-\bar{y})^{2}} R2=1i=0m(yiyˉ)2i=0m(yiy^i)2=1i=0M(yiyˉ)2RSS

其中是我们的真实标签, 是我们的预测结果, 是我们的均值, 如果除以样本量m就是我们的方差。方差的本质是任意一个值和样本均值的差异,差异越大,这些值所带的信息越多。在中,分子是真实值和预测值之差的差值,也就是我们的模型没有捕获到的信息总量,分母是真实标签所带的信息量,所以其衡量的是1 - 我们的模型没有捕获到的信息量占真实标签中所带的信息量比例,所以,越接近1越好。

可以使用三种方式来调用,一种是直接从metrics中导入r2_score,输入预测值和真实值后打分。第二种是直接从线性回归LinearRegression的接口score来进行调用。第三种是在交叉验证中,输入"r2"来调用。

#调用R2yhat=reg.predict(Xtest)from sklearn.metrics import r2_scorer2_score(yhat,Ytest) #返回0.338r2 = reg.score(Xtest,Ytest) #返回0.604r2   # 这里会发现相同的评估指标不同的结果

线性回归大坑二不同的结果解释:在分类模型的评价指标当中,进行的是一种 if a == b的对比,这种判断和if b == a其实完全是一种概念,所以在进行模型评估的时候,从未踩到现在的这个坑里。然而看R2的计算公式,R2明显和分类模型的指标中的accuracy或者precision不一样,R2涉及到的计算中对预测值和真实值有极大的区别,必须是预测值在分子,真实值在分母,所以在调用metrcis模块中的模型评估指标的时候,必须要检查清楚,指标的参数中,究竟是要求先输入真实值还是先输入预测值。

#使用shift tab键来检查究竟哪个值先进行输入r2_score(Ytest,yhat)#或者你也可以指定参数,就不必在意顺序了r2_score(y_true = Ytest,y_pred = yhat)cross_val_score(reg,X,y,cv=10,scoring="r2").mean()

我们观察到,我们在加利利福尼亚房屋价值数据集上的MSE其实不是一个很大的数(0.5),但我们的不高,这证明我们的模型比较好地拟合了一部分数据的数值,却没有能正确拟合数据的分布。让我们用绘图来看看,究竟是不是这样一回事。我们可以在一张图上绘制出预测值的散点图和真实值的折线图,如果两者趋势越接近,并且预测值的散点图越靠近真实值,则我们认为模型拟合优秀。

yhat=reg.predict(Xtest)ind = np.argsort(Ytest)yhat= pd.DataFrame(yhat,index=ind)#让yhat按照Ytest中从小到大的排序来进行排序plt.plot(range(len(Ytest)),sorted(Ytest),c='k',label='Data')plt.plot(range(len(yhat)),sorted(yhat.iloc[:,0]),c='red',label='predict')plt.legend()plt.show()

在这里插入图片描述

可见,大部分数据的拟合其实还是围绕在真实值周围的,但是图像的整体趋势却不一致。如果在图像右侧分布着更多的数据,模型就会越来越偏离真正的标签。这种结果类似于前面提到的,虽然在有限的数据集上将数值预测相对正确了了,但却没有正确拟合数据的分布,如果有更多的数据进入我们的模型,那数据标签被预测错误的可能性是非常大的。

import numpy as nprng = np.random.RandomState(42)X = rng.randn(100, 80)y = rng.randn(100)cross_val_score(LR(), X, y, cv=5, scoring='r2')#返回array([-179.11480837,   -5.70837982,  -15.38196168,  -77.07714165,        -61.98484963])

线性回归的大坑三:负的 R 2 R^2 R2

除了RSS之外,我们还有解释平方和ESS(Explained Sum of Squares,也叫做SSR回归平方和)以及总离差平方和TSS(Total Sum of Squares,也叫做SST总离差平方和)。解释平方和ESS定义了我们的预测值和样本均值之间的差异,而总离差平方和定义了真实值和样本均值之间的差异(就是中的分母),两个指标分别写作:

T S S = ∑ i = 0 m ( y i − y ˉ ) 2 TSS=\sum_{i=0}^{m}(y_i-\bar{y})^{2} TSS=i=0m(yiyˉ)2

E S S = ∑ i = 0 m ( y ^ − y ˉ ) 2 ESS=\sum_{i=0}^{m}(\hat{y}-\bar{y})^{2} ESS=i=0m(y^yˉ)2

下面推导下:

在这里插入图片描述

许多教材让这个式子为0,公式自然就成立了,但要让这个式子成立是有条件的。现在有了这个式子的存在, 就可以是一个负数了。只要我们的衡量的是真实值到预测值的距离,而衡量的是预测值到均值的距离,只要当这两个部分的符号不同的时候,我们的式子就为负,而就有机会是一个负数。

看下面这张图,蓝色的横线是我们的均值线,橙色的线是我们的模型,蓝色的点是我们的样本点。现在对于来说,我们的真实标签减预测值的值为正,但我们的预测值却是一个负数,这说明,数据本身的均值,比我们对数据的拟合模型本身更接近数据的真实值,那我们的模型就是废的,完全没有作用,类似于分类模型中的分类准确率为50%,不如瞎猜。

在这里插入图片描述
也就是说,当我们的显示为负的时候,这证明我们的模型对我们的数据的拟合非常糟糕,模型完全不能使用。所有,一个负的是合理的。当然了,现实应用中,如果你发现你的线性回归模型出现了了负的,不代表你就要接受他了,首先检查你的建模过程和数据处理理过程是否正确,也许你已经伤害了数据本身,也许你的建模过程是存在bug的。如果是集成模型的回归,检查你的弱评估器器的数量是否不足,随机森林,提升树这些模型在只有两三棵树的时候很容易易出现负的。如果你检查了所有的代码,也确定了你的预处理没有问题,但你的也还是负的,那这就证明,线性回归模型不适合你的数据,试试看其他的算法吧。

四、岭回归和Lasso

1、多重共线性

前面推导多元线性回归使用最小二乘法的求解原理,得到w的式子和方程:

w = ( X T X ) − 1 X T y w=(X^TX)^{-1}X^Ty w=(XTX)1XTy

最后得出逆矩阵存在的充分必要条件是特征矩阵不存在多重共线性。逆矩阵存在充分必要条件是矩阵的行列式不为0。不为0的条件是梯形矩阵对角线没有一个元素为0,这种矩阵也称为满秩矩阵,换句话说,矩阵中两行或多行之间存在完全相关,则一行通过变换可以让另一行为0,在这种完全相关的关系下,矩阵的行列式为0,则矩阵的逆不存在,如果矩阵存在这种完全相关关系,则逆不存在,最小二乘法完全无法使用,线性回归会无法求出结果。
( X T X ) − 1 = 1 ∣ X T X ∣ ( X T X ) ∗ → 1 0 ( X T X ) (X^TX)^{-1}=\frac{1}{\left | X^TX \right |}(X^TX)^{*}\rightarrow \frac{1}{0}(X^TX) (XTX)1=XTX1(XTX)01(XTX)
有一种情况,两行之间非常接近于完全相关,但又不是完全的,一行不能使另外一行为0,这种关系称为’高度相关关系’,在这种高度相关关系下,矩阵的行列式不为0,但是一个非常接近0数,矩阵A的逆存在,不过接近于无限大。在这种情况下,最小二乘法可以使用,不过得到的逆会很大,直接影响我们对参数向量的求解:

( X T X ) − 1 = 1 ∣ X T X ∣ ( X T X ) ∗ → 1 非 常 接 近 0 的 数 ( X T X ) → ∞ (X^TX)^{-1}=\frac{1}{\left | X^TX \right |}(X^TX)^{*}\rightarrow \frac{1}{非常接近0的数}(X^TX)\rightarrow\infty (XTX)1=XTX1(XTX)01(XTX)

w = ( X T X ) − 1 ( X T Y ) → ∞ w=(X^TX)^{-1}(X^TY)\rightarrow\infty w=(XTX)1(XTY)

这样求解出来的参数向量会大,因此会影响建模的结果,造成模型有偏差或者不可用。精确相关关系和高度相关关系并称为"多重共线性"。在多重共线性下,模型无法建立,或者模型不可用。

从上面的所有过程我们可以看得出来,一个矩阵如果要满秩,则要求矩阵中每个向量之间不能存在多重共线性,这也构成了线性回归算法对于特征矩阵的要求。

在这里插入图片描述
2、岭回归

岭回归,又称为吉洪诺夫正则化(Tikhonov regularization)。岭回归在多元线性回归的损失函数上加上了正则项,表达为系数的L2范式(即系数的平方项)乘以正则化系数。如果看其他教材中的代数推导,正则化系数会写作,用以和Lasso区别,不过在sklearn中由于是两个不同的算法,因此正则项系数都使用来代表。岭回归的损失函数的完整表达式写作:

m i n ∥ X w − y ∥ 2 2 + α ∥ w ∥ 2 2 min\left \| Xw-y \right \|_2^2+\alpha \left \| w \right \|_2^2 minXwy22+αw22

下面用最小二乘法来求解:
在这里插入图片描述
现在,只要 ( X T X + α I ) (X^TX+αI) (XTX+αI)存在逆矩阵,我们就可以求解出w。一个矩阵存在逆矩阵的充分必要条件是这个矩阵的行列式不为0。下面看转换成梯形矩阵结果
在这里插入图片描述
最后得到的这个行列式还是一个梯形行列式,然而它的已经不存在全0行或者全0列了了,除非:
(1) α等于0,或者
(2) 原本的矩阵 ( X T X ) (X^TX) (XTX)中存在对角线上元素为-α,其他元素都为0的行或者列
否则矩阵 ( X T X + α I ) (X^TX+αI) (XTX+αI)永远都是满秩。在sklearn中, α的值我们可以自由控制,因此我们可以让它不为0,以避免第一种情况。而第二种情况,如果我们发现某个α的取值下模型无法求解,那我们只需要换一个的取值就好了,也可以顺利利避免。也就是说,矩阵的逆是永远存在的!

这样就避免了完全相关关系带来的影响,最小二乘法就可以使用了,对于高度相关关系的矩阵,可以通过调大α值来让 ( X T X + α I ) (X^TX+αI) (XTX+αI)矩阵的行列式变大,从而让逆矩阵变小,以此控制参数向量w的偏移。当α越大,模型越不容易受到共线性的影响。

( X T X + α I ) − 1 = 1 ∣ X T X + α I ∣ ( X T X + α I ) ∗ (X^TX+αI)^{-1}=\frac{1}{\left | X^TX+ αI \right |}(X^TX+αI)^{*} (XTX+αI)1=XTX+αI1(XTX+αI)
如此,多重共线性就被控制住了:最小二乘法一定有解,并且这个解可以通过来进行调节,以确保不会偏离太多。当然了, α挤占了w中由原始的特征矩阵贡献的空间,因此如果α太大,也会导致的估计出现较大的偏移,无法正确拟合数据的真实面貌。我们在使用中,需要找出让模型效果变好的最佳取值。

class sklearn.linear_model.Ridge (alpha=1.0, fit_intercept=True, normalize=False, copy_X=True,max_iter=None, tol=0.001, solver=’auto’, random_state=None)

之前我们在加利佛尼亚房屋价值数据集上使用线性回归,得出的结果大概是训练集上的拟合程度是60%,测试集上的拟合程度也是60%左右,现在我们用岭回归来看看拟合程度多少,如果分数差不多,说明数据不存在多重共线性,反之存在。下面我们来验证下。

import numpy as npimport pandas as pdfrom sklearn.linear_model import Ridge, LinearRegression, Lassofrom sklearn.model_selection import train_test_split as TTSfrom sklearn.datasets import fetch_california_housing as fchimport matplotlib.pyplot as plthousevalue = fch() #下载加利福利亚房屋数据集X = pd.DataFrame(housevalue.data)y = housevalue.targetX.columns = ["住户收入中位数","房屋使用年代中位数","平均房间数目"            ,"平均卧室数目","街区人口","平均入住率","街区的纬度","街区的经度"]X.head() #查看下数据Xtrain,Xtest,Ytrain,Ytest = TTS(X,y,test_size=0.3,random_state=420)#数据集索引恢复for i in [Xtrain,Xtest]:i.index = range(i.shape[0])#建模reg=Ridge(alpha=1).fit(Xtrain,Ytrain)reg.score(Xtest,Ytest)#交叉验证下,与线性回归相比,岭回归的结果如何变化?alpharange = np.arange(1,1001,100)ridge, lr = [], []for alpha in alpharange:    reg = Ridge(alpha=alpha)    linear = LinearRegression()    regs = cross_val_score(reg,X,y,cv=5,scoring = "r2").mean()    linears = cross_val_score(linear,X,y,cv=5,scoring = "r2").mean()    ridge.append(regs)    lr.append(linears)plt.plot(alpharange,ridge,color="red",label="Ridge")plt.plot(alpharange,lr,color="orange",label="LR")plt.title("Mean")plt.legend()plt.show()#细化学习曲线alpharange = np.arange(1,201,10) #这里可以细化学习曲线看下(1-200)曲线的情况

在这里插入图片描述

可以看出,加利佛尼亚数据集上,岭回归的结果轻微上升,随后骤降。可以说,加利佛尼亚房屋价值数据集带有很轻微的一部分共线性,这种共线性被正则化参数消除后,模型的效果提升了一点点,但是对于整个模型而言是杯水车薪。在过了控制多重共线性的点后,模型的效果飞速下降,显然是正则化的程度太重,挤占了参数 w w w本来的估计空间。从这个结果可以看出,加利佛尼亚数据集的核心问题不在于多重共线性,岭回归不能够提升模型表现。如果我们使用岭回归或者Lasso,那模型的效果都是会降低的,很难升高,这恐怕也是岭回归和Lasso一定程度上被机器器学习领域冷遇的原因。

利用交叉验证寻找最佳α

class sklearn.linear_model.RidgeCV (alphas=(0.1, 1.0, 10.0), fit_intercept=True, normalize=False,scoring=None, cv=None, gcv_mode=None, store_cv_values=False)

在这里插入图片描述

import numpy as npimport pandas as pdfrom sklearn.linear_model import RidgeCV, LinearRegressionfrom sklearn.model_selection import train_test_split as TTSfrom sklearn.datasets import fetch_california_housing as fchimport matplotlib.pyplot as plthousevalue = fch()X = pd.DataFrame(housevalue.data)y = housevalue.targetX.columns = ["住户收入中位数","房屋使用年代中位数","平均房间数目"            ,"平均卧室数目","街区人口","平均入住率","街区的纬度","街区的经度"]Ridge_ = RidgeCV(alphas=np.arange(1,1001,100)                #,scoring="neg_mean_squared_error"                 ,store_cv_values=True                #,cv=5                ).fit(X, y)#无关交叉验证的岭回归结果Ridge_.score(X,y)#调用所有交叉验证的结果Ridge_.cv_values_.shape#进行平均后可以查看每个正则化系数取值下的交叉验证结果Ridge_.cv_values_.mean(axis=0)#查看被选择出来的最佳正则化系数Ridge_.alpha_

3、Lasso

Lasso全称最小绝对收缩和选择算子(leastabsolute shrinkage and selection operator),由于这个名字过于复杂所以简称为Lasso。和岭回归一样,Lasso是被创造来作用于多重共线性问题的算法,不过Lasso使用的是系数的L1范式(L1范式则是系数的绝对值)乘以正则化系数,所以Lasso的损失函数表达式为:

m i n ∥ X w − y ∥ 2 2 + α ∥ w ∥ 1 min\left \| Xw-y \right \|_2^{2}+\alpha \left \| w \right \|_1 minXwy22+αw1
当我们使用最小二乘法来求解Lasso中的参数,我们依然对损失函数进行求导:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gZ7BMcnh-1575179653531)(D:\学习知识整理\Python\图片\机器学习图片\线性回归11.png)]

现在问题又回到了要求 X T X X^TX XTX的逆必须存在。在岭回归中,我们通过正则化系α能够向方阵 X T X X^TX XTX加上一个单位矩阵,以此来防止方阵 X T X X^TX XTX的行列式为0,而现在L1范式所带的正则项α在求导之后并不带有 w w w这个项,因此它无法对 X T X X^TX XTX造成任何影响。也就是说,Lasso无法解决特征之间’‘精确相关’'的问题。当我们使用最小二乘法求解线性回归时,如果线性回归无解或者报除零错误,换Lasso不能解决任何问题。

所以岭回归可以解决特征间的精确相关关系导致的最小二乘法无法使用的问题,而Lasso不行。

w = ( X T X ) − 1 ( X T Y − α I 2 ) w=(X^TX)^{-1}(X^TY-\frac{\alpha I}{2}) w=(XTX)1(XTY2αI)
通过增大α,我们可以为的计算增加一个负项,从而限制参数估计中 w w w的大小,而防止多重共线性引起的参数 w w w被估计过大导致模型失准的问题。Lasso不是从根本上解决多重共线性问题,而是限制多重共线性带来的影响。何况,这还是在我们假设所有的系数都为正的情况下,假设系数 w w w无法为正,则很有可能我们需要将我们的正则项参数α设定为负,因此α可以取负数,并且负数越大,对共线性的限制也越大。

所有这些让Lasso成为了了一个神奇的算法,尽管它是为了了限制多重共线性被创造出来的,然而世人其实并不使用它来抑制多重共线性,反而接受了它在其他方面的优势。事实上,岭回归和Lasso的不同就是L1和L2正则化,而这两个正则化的核心差异就是他们对系数 w w w的影响:两个正则化都会压缩 w w w系数的大小,对标签贡献更少的特征的系数会更小,也会更容易被压缩。不过,L2正则化只会将系数压缩到尽量接近0,但L1正则化主导稀疏性,因此会将系数压缩到0。这个性质,让Lasso成为了了线性模型中的特征选择工具首选,接下来,我们就来看看如何使用Lasso来选择特征。

class sklearn.linear_model.Lasso (alpha=1.0, fit_intercept=True, normalize=False,precompute=False, copy_X=True, max_iter=1000, tol=0.0001, warm_start=False, positive=False,random_state=None, selection=’cyclic’)

sklearn中我们使用类Lasso来调用lasso回归,众多参数中我们需要比较在意的就是参数α,正则化系数。另外需要注意的就是参数positive。当这个参数为"True"的时候,是我们要求Lasso回归出的系数必须为正数,以此来保证我们的α一定以增大来控制正则化的程度。

需要注意的是,在sklearn中我们的Lasso使用的损失函数是:
m i n 1 2 m ∥ X w − y ∥ 2 2 + α ∥ w ∥ 1 min\frac{1}{2m}\left \| Xw-y \right \|_2^{2}+\alpha \left \| w \right \|_1 min2m1Xwy22+αw1
其中 1 2 m \frac{1}{2m} 2m1只是作为系数存在,用来消除我们对损失函数求导后多出来的那个2的(求解时所带的1/2),然后对整体的RSS求了了一个平均而已,无论时从损失函数的意义来看还是从Lasso的性质和功能来看,这个变化没有造成任何影响,只不过计算上会更加简便便一些。

import numpy as npimport pandas as pdfrom sklearn.linear_model import Ridge, LinearRegression, Lassofrom sklearn.model_selection import train_test_split as TTSfrom sklearn.datasets import fetch_california_housing as fchimport matplotlib.pyplot as plthousevalue = fch()X = pd.DataFrame(housevalue.data)y = housevalue.targetX.columns = ["住户收入中位数","房屋使用年代中位数","平均房间数目"            ,"平均卧室数目","街区人口","平均入住率","街区的纬度","街区的经度"]X.head()Xtrain,Xtest,Ytrain,Ytest = TTS(X,y,test_size=0.3,random_state=420)#恢复索引for i in [Xtrain,Xtest]:i.index = range(i.shape[0])#线性回归进行拟合reg = LinearRegression().fit(Xtrain,Ytrain)(reg.coef_*100).tolist()#岭回归进行拟合Ridge_ = Ridge(alpha=1).fit(Xtrain,Ytrain)(Ridge_.coef_*100).tolist()#Lasso进行拟合lasso_ = Lasso(alpha=1).fit(Xtrain,Ytrain)  # lasso中惩罚系数α不宜过高(lasso_.coef_*100).tolist()#将系数进行绘图plt.plot(range(1,9),(reg.coef_*100).tolist(),color="red",label="LR")plt.plot(range(1,9),(Ridge_.coef_*100).tolist(),color="orange",label="Ridge")plt.plot(range(1,9),(lasso_.coef_*100).tolist(),color="k",label="Lasso")plt.plot(range(1,9),[0]*8,color="grey",linestyle="--")plt.xlabel('w') #横坐标是每一个特征所对应的系数plt.legend()plt.show()

在这里插入图片描述

这是要知道sklearn中的Lasso类不是使用最小二乘法来进行求解,而是使用坐标下降。有了坐标下降,就有迭代和收敛的问题,因此sklearn不推荐我们使用0这样的正则化系数。如果我们的确希望取到0,那我们可以使用一个比较很小的数,比如0.01,或者 10 ∗ e − 3 10*e^{-3} 10e3这样的值

*100).tolist(),color=“red”,label=“LR”)

plt.plot(range(1,9),(Ridge.coef_*100).tolist(),color=“orange”,label=“Ridge”)
plt.plot(range(1,9),(lasso_.coef_*100).tolist(),color=“k”,label=“Lasso”)
plt.plot(range(1,9),[0]*8,color=“grey”,linestyle="–")
plt.xlabel(‘w’) #横坐标是每一个特征所对应的系数
plt.legend()
plt.show()

![在这里插入图片描述](https://img-blog.csdnimg.cn/20191201140020214.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0FJamlhbmtlamk=,size_16,color_FFFFFF,t_70)这是要知道sklearn中的Lasso类不是使用最小二乘法来进行求解,而是使用坐标下降。有了坐标下降,就有迭代和收敛的问题,因此sklearn不推荐我们使用0这样的正则化系数。如果我们的确希望取到0,那我们可以使用一个比较很小的数,比如0.01,或者$10*e^{-3}$这样的值可见,比起岭回归,Lasso所带的L1正则项对于系数的惩罚要重得多,并且它会将系数压缩至0,因此可以被用来做特征选择。也因此,我们往往让Lasso的正则化系数在很小的空间中变动,以此来寻找最佳的正则化系数。

转载地址:http://lxqbb.baihongyu.com/

你可能感兴趣的文章
linux系统 阿里云源
查看>>
国内外helm源记录
查看>>
牛客网题目1:最大数
查看>>
散落人间知识点记录one
查看>>
Leetcode C++ 随手刷 547.朋友圈
查看>>
手抄笔记:深入理解linux内核-1
查看>>
内存堆与栈
查看>>
Leetcode C++《每日一题》20200621 124.二叉树的最大路径和
查看>>
Leetcode C++《每日一题》20200622 面试题 16.18. 模式匹配
查看>>
Leetcode C++《每日一题》20200625 139. 单词拆分
查看>>
Leetcode C++《每日一题》20200626 338. 比特位计数
查看>>
Leetcode C++ 《拓扑排序-1》20200626 207.课程表
查看>>
Go语言学习Part1:包、变量和函数
查看>>
Go语言学习Part2:流程控制语句:for、if、else、switch 和 defer
查看>>
Go语言学习Part3:struct、slice和映射
查看>>
Go语言学习Part4-1:方法和接口
查看>>
Leetcode Go 《精选TOP面试题》20200628 69.x的平方根
查看>>
leetcode 130. Surrounded Regions
查看>>
【Python】详解Python多线程Selenium跨浏览器测试
查看>>
Jmeter之参数化
查看>>