机器学习-Sklearn(第三版)Day9 回归大家族:线性回归,岭回归,Lasso与多项式回归

一、 概述

1 线性回归大家族
回归是一种应用广泛的预测建模技术,这种技术的核心在于预测的结果是连续型变量。决策树,随机森林,支持向量机的分类器等分类算法的预测标签是分类变量,多以{0,1}来表示,而无监督学习算法比如PCA,KMeans并不求解标签,注意加以区别。回归算法源于统计学理论,它可能是机器学习算法中产生最早的算法之一,其在现实中的应用非常广泛,包括使用其他经济指标预测股票市场指数,根据喷射流的特征预测区域内的降水量,根据公司的广告花费预测总销售额,或者根据有机物质中残留的碳-14的量来估计化石的年龄等等,只要一切基于特征预测连续型变量的需求,都使用回归技术。

既然线性回归是源于统计分析,是结合机器学习与统计学的重要算法。通常认为统计学注重先验,而机器学习看重结果,因此机器学习中不会提前为线性回归排除共线性等可能会影响模型的因素,反而会先建立模型以查看效果。模型确立之后,如果效果不好,就根据统计学的指导来排除可能影响模型的因素。课程会从机器学习的角度来为大家讲解回归类算法,如果希望理解统计学角度的小伙伴们,各种统计学教材都可以满足你的需求。

回归需求在现实中非常多,所以自然也有各种各样的回归类算法。最著名的就是线性回归和逻辑回归,从他们衍生出了岭回归,Lasso,弹性网,除此之外,还有众多分类算法改进后的回归,比如回归树,随机森林的回归,支持向量回归,贝叶斯回归等等。除此之外,还有各种鲁棒的回归:比如RANSAC,Theil-Sen估计,胡贝尔回归等等。考虑到回归问题在现实中的泛用性,回归家族可以说是非常繁荣昌盛,家大业大了。

回归类算法的数学相对简单,相信在经历了逻辑回归,主成分分析与奇异值分解,支持向量机这三个章节之后,大家不会感觉到线性回归中的数学有多么困难。通常,理解线性回归可以有两种角度:矩阵的角度和代数的角度。几乎所有机器学习的教材都是从代数的角度来理解线性回归的,类似于在逻辑回归和支持向量机中做的那样,将求解参数的问题转化为一个带条件的最优化问题,然后使用三维图像让大家理解求极值的过程。如果大家掌握了逻辑回归和支持向量机,这个过程可以说是相对简单的,因此在本章节中就不进行赘述了。相对的,在课程中一直都缺乏比较系统地使用矩阵来解读算法的角度,因此在本堂课中,将全程使用矩阵方式(线性代数的方式)为大家展现回归大家族的面貌。

学完这堂课之后,大家需要对线性模型有个相对全面的了解,尤其是需要掌握线性模型究竟存在什么样的优点和问题,并且如何解决这些问题。
2 sklearn中的线性回归
sklearn中的线性模型模块是linear_model,曾经在学习逻辑回归的时候提到过这个模块。linear_model包含了多种多样的类和函数,其中逻辑回归相关的类和函数在这里就不给大家列举了。今天的课中会为大家来讲解:普通线性回归,多项式回归,岭回归,LASSO,以及弹性网。

类/函数 含义
普通线性回归
linear_model.LinearRegression 使用普通最小二乘法的线性回归
岭回归
linear_model.Ridge 岭回归,一种将L2作为正则化工具的线性最小二乘回归
linear_model.RidgeCV 带交叉验证的岭回归
linear_model.RidgeClassifier 岭回归的分类器
linear_model.RidgeClassifierCV 带交叉验证的岭回归的分类器
linear_model.ridge_regression 【函数】用正太方程法求解岭回归
LASSO
linear_model.Lasso Lasso,使用L1作为正则化工具来训练的线性回归模型
linear_model.LassoCV 带交叉验证和正则化迭代路径的Lasso
linear_model.LassoLars 使用最小角度回归求解的Lasso
linear_model.LassoLarsCV 带交叉验证的使用最小角度回归求解的Lasso
linear_model.LassoLarsIC 使用BIC或AIC进行模型选择的,使用最小角度回归求解的Lasso
linear_model.MultiTaskLasso 使用L1 / L2混合范数作为正则化工具训练的多标签Lasso
linear_model.MultiTaskLassoCV 使用L1 / L2混合范数作为正则化工具训练的,带交叉验证的多标签Lasso
linear_model.lasso_path 【函数】用坐标下降计算Lasso路径
弹性网
linear_model.ElasticNet 弹性网,一种将L1和L2组合作为正则化工具的线性回归
linear_model.ElasticNetCV 带交叉验证和正则化迭代路径的弹性网
linear_model.MultiTaskElasticNet 多标签弹性网
linear_model.MultiTaskElasticNetCV 带交叉验证的多标签弹性网
linear_model.enet_path 【函数】用坐标下降法计算弹性网的路径
最小角度回归
linear_model.Lars 最小角度回归(Least Angle Regression,LAR)
linear_model.LarsCV 带交叉验证的最小角度回归模型
linear_model.lars_path 【函数】使用LARS算法计算最小角度回归路径或Lasso的路径
正交匹配追踪
linear_model.OrthogonalMatchingPursuit 正交匹配追踪模型(OMP)
linear_model.OrthogonalMatchingPursuitCV 交叉验证的正交匹配追踪模型(OMP)
linear_model.orthogonal_mp 【函数】正交匹配追踪(OMP)
linear_model.orthogonal_mp_gram 【函数】Gram正交匹配追踪(OMP)
贝叶斯回归
linear_model.ARDRegression 贝叶斯ARD回归。ARD是自动相关性确定回归(Automatic Relevance DeterminationRegression),是一种类似于最小二乘的,用来计算参数向量的数学方法。
linear_model.BayesianRidge 贝叶斯岭回归
其他回归
linear_model.PassiveAggressiveClassifier 被动攻击性分类器
linear_model.PassiveAggressiveRegressor 被动攻击性回归
linear_model.Perceptron 感知机
linear_model.RANSACRegressor RANSAC(RANdom SAmple Consensus)算法。
linear_model.HuberRegressor 胡博回归,对异常值具有鲁棒性的一种线性回归模型
linear_model.SGDRegressor 通过最小化SGD的正则化损失函数来拟合线性模型
linear_model.TheilSenRegressor Theil-Sen估计器,一种鲁棒的多元回归模型

二、 多元线性回归LinearRegression

1 多元线性回归的基本原理
线性回归是机器学习中最简单的回归算法,多元线性回归指的就是一个样本有多个特征的线性回归问题。对于一个有n个特征的样本i而言,它的回归结果可以写作一个几乎人人熟悉的方程:在这里插入图片描述
w被统称为模型的参数,其中w 0 w_0w0​被称为截距(intercept),w 1 w_1w1​~w n w_nwn​被称为回归系数(regression coefficient),有时也使用θ或者β来表示。这个表达式,其实就和小学时就无比熟悉的y=ax+b是同样的性质。其中y是目标变量,也就是标签。x i 1 x_{i1}xi1​~x i n x_{in}xin​是样本i上的不同特征。如果考虑有m个样本,则回归结果可以被写作:在这里插入图片描述
其中y是包含了m个全部的样本的回归结果的列向量。注意,通常使用粗体的小写字母来表示列向量,粗体的大写字母表示矩阵或者行列式。可以使用矩阵来表示这个方程,其中w可以被看做是一个结构为(n+1,1)的列矩阵,X是一个结构为(m,n+1)的特征矩阵,则有:在这里插入图片描述
线性回归的任务,就是构造一个预测函数来映射输入的特征矩阵X和标签值y的线性关系,这个预测函数在不同的教材上写法不同,可能写作f(x),y w ( x ) y_w(x)yw​(x),或者h(x)等等形式,但无论如何,这个预测函数的本质就是需要构建的模型,而构造预测函数的核心就是找出模型的参数向量w。但怎样才能够求解出参数向量呢?

记得在逻辑回归和SVM中,都是先定义了损失函数,然后通过最小化损失函数或损失函数的某种变化来将求解参数向量,以此将单纯的求解问题转化为一个最优化问题。在多元线性回归中,损失函数如下定义:在这里插入图片描述
其中y i y_iyi​是样本i对应的真实标签,在这里插入图片描述
首先,这个损失函数代表了向量y-y’的L2范式的平方结果,L2范式的本质是就是欧式距离,即是两个向量上的每个点对应相减后的平方和再开平方,现在只实现了向量上每个点对应相减后的平方和,并没有开方,所以损失函数是L2范式,即欧式距离的平方结果。

在这个平方结果下,y和y’分别是真实标签和预测值,也就是说,这个损失函数是在计算真实标签和预测值之间的距离。因此,认为这个损失函数衡量了构造的模型的预测结果和真实标签的差异,因此固然希望预测结果和真实值差异越小越好。所以求解目标就可以转化成:在这里插入图片描述
其中右下角的2表示向量y-Xw的L2范式,也就是损失函数所代表的含义。在L2范式上开平方,就是损失函数。这个式子,也正是sklearn当中,用在类Linear_model.LinerRegression背后使用的损失函数。往往称这个式子为SSE(Sum of Sqaured Error,误差平方和)或者RSS(Residual Sum of Squares 残差平方和)。在sklearn所有官方文档和网页上,都称之为RSS残差平方和,因此在课件中也这样称呼。
2 最小二乘法求解多元线性回归的参数
现在问题转换成了求解让RSS最小化的参数向量w,这种通过最小化真实值和预测值之间的RSS来求解参数的方法叫做最小二乘法。求解极值的第一步往往是求解一阶导数并让一阶导数等于0,最小二乘法也不能免俗。因此,现在残差平方和RSS上对参数向量w求导。这里的过程涉及到少数矩阵求导的内容,需要查表来确定,感兴趣可以走维基百科去查看矩阵求导的详细公式的表格:https://en.wikipedia.org/wiki/Matrix_calculus

接下来,就对w求导
在这里插入图片描述
在这里插入图片描述
到了这里,希望能够将w留在等式的左边,其他与特征矩阵有关的部分都放到等式的右边,如此就可以求w的最优解了。这个功能非常容易实现,只需要左乘X T X X^TXXTX的逆矩阵就可以。在这里,逆矩阵存在的充分必要条件是特征矩阵不存在多重共线性。将会在第四节详细讲解多重共线性这个主题。

假设矩阵的逆是存在的,此时w就是参数的最优解。求解出这个参数向量,就解出了Xw,也就能够计算出预测值y’了。对于多元线性回归的理解,到这里就足够了,如果大家还希望继续深入,那可以给大家一个方向:你们知道矩阵X T X X^TXXTX其实是使用奇异值分解来进行求解的吗?可以仔细去研究一下。以算法工程师和数据挖掘工程师为目标的大家,能够手动推导上面的求解过程是基本要求。

除了多元线性回归的推导之外,这里还需要提到一些在上面的推导过程中不曾被体现出来的问题。在统计学中,使用最小二乘法来求解线性回归的方法是一种”无偏估计“的方法,这种无偏估计要求因变量,也就是标签的分布必须服从正态分布。这是说,y必须经由正态化处理(比如说取对数,或者使用在第三章《数据预处理与特征工程》中提到的类QuantileTransformer或者PowerTransformer)。在机器学习中,会先考虑模型的效果,如果模型效果不好,那可能考虑改变因变量的分布。
3 linear_model.LinearRegression
class sklearn.linear_model.LinearRegression (fit_intercept=True, normalize=False, copy_X=True, n_jobs=None)

参数 含义
fit_intercep 布尔值,可不填,默认为True。是否计算此模型的截距。如果设置为False,则不会计算截距
normalize 布尔值,可不填,默认为False。当fit_intercept设置为False时,将忽略此参数。如果为True,则特征矩阵X在进入回归之前将会被减去均值(中心化)并除以L2范式(缩放)。如果希望进行标准化,请在fit数据之前使用preprocessing模块中的标准化专用类StandardScaler
copy_X 布尔值,可不填,默认为True。如果为真,将在X.copy()上进行操作,否则的话原本的特征矩阵X可能被线性回归影响并覆盖
n_jobs 整数或者None,可不填,默认为None。用于计算的作业数。只在多标签的回归和数据量足够大的时候才生效。除非None在joblib.parallel_backend上下文中,否则None统一表示为1。如果输入 -1,则表示使用全部的CPU来进行计算。

线性回归的类可能是目前为止学到的最简单的类,仅有四个参数就可以完成一个完整的算法。并且看得出,这些参数中并没有一个是必填的,更没有对模型有不可替代作用的参数。这说明,线性回归的性能,往往取决于数据本身,而并非是调参能力,线性回归也因此对数据有着很高的要求。幸运的是,现实中大部分连续型变量之间,都存在着或多或少的线性联系。所以线性回归虽然简单,却很强大。

顺便一提,sklearn中的线性回归可以处理多标签问题,只需要在fit的时候输入多维度标签就可以了。

做一次回归试试

#1. 导入需要的模块和库
from sklearn.linear_model import LinearRegression as LR
from sklearn.model_selection import train_test_split
from sklearn.model_selection import cross_val_score
from sklearn.datasets import fetch_california_housing as fch #加利福尼亚房屋价值数据集
import pandas as pd

#2. 导入数据,探索数据
housevalue = fch() #会需要下载,大家可以提前运行试试看
X = pd.DataFrame(housevalue.data) #放入DataFrame中便于查看
y = housevalue.target
print(X.shape)#(20640,8)
print(y.shape)
print(X.head())
print(housevalue.feature_names)
X.columns = housevalue.feature_names#特征名字
"""
MedInc:该街区住户的收入中位数      HouseAge:该街区房屋使用年代的中位数
AveRooms:该街区平均的房间数目      AveBedrms:该街区平均的卧室数目
Population:街区人口               AveOccup:平均入住率
Latitude:街区的纬度               Longitude:街区的经度
"""

#3. 分训练集和测试集
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])
print(Xtrain.shape)
#如果希望进行数据标准化,还记得应该怎么做吗?
#先用训练集训练标准化的类,然后用训练好的类分别转化训练集和测试集

#4. 建模
reg = LR().fit(Xtrain, Ytrain)
yhat = reg.predict(Xtest)
print(yhat)

#5. 探索建好的模型
print(reg.coef_)#w,系数向量
print([*zip(Xtrain.columns,reg.coef_)])
"""
MedInc:该街区住户的收入中位数    HouseAge:该街区房屋使用年代的中位数
AveRooms:该街区平均的房间数目    AveBedrms:该街区平均的卧室数目
Population:街区人口             AveOccup:平均入住率
Latitude:街区的纬度             Longitude:街区的经度
"""

属性 含义
coef_ 数组,形状为 (n_features, )或者(n_targets, n_features)。线性回归方程中估计出的系数。如果在fit中传递多个标签(当y为二维或以上的时候),则返回的系数是形状为(n_targets,n_features)的二维数组,而如果仅传递一个标签,则返回的系数是长度为n_features的一维数组
intercept_ 数组,线性回归中的截距项。

建模的过程在sklearn当中其实非常简单,但模型的效果如何呢?接下来看看多元线性回归的模型评估指标。

三、 回归类的模型评估指标

回归类算法的模型评估一直都是回归算法中的一个难点,但不像曾经讲过的无监督学习算法中的轮廓系数等等评估指标,回归类与分类型算法的模型评估其实是相似的法则——找真实标签和预测值的差异。只不过在分类型算法中,这个差异只有一种角度来评判,那就是是否预测到了正确的分类,而在回归类算法中,有两种不同的角度来看待回归的效果:

第一,是否预测到了正确的数值。第二,是否拟合到了足够的信息。

这两种角度,分别对应着不同的模型评估指标。
1 是否预测了正确的数值
回忆一下RSS残差平方和,它的本质是预测值与真实值之间的差异,也就是从第一种角度来评估回归的效力,所以RSS既是损失函数,也是回归类模型的模型评估指标之一。但是,RSS有着致命的缺点:它是一个无界的和,可以无限地大。只知道,想要求解最小的RSS,从RSS的公式来看,它不能为负,所以RSS越接近0越好,但没有一个概念,究竟多小才算好,多接近0才算好?为了应对这种状况,sklearn中使用RSS的变体,均方误差MSE(mean squared error)来衡量预测值和真实值的差异:在这里插入图片描述

均方误差,本质是在RSS的基础上除以了样本总量,得到了每个样本量上的平均误差。有了平均误差,就可以将平均误差和标签的取值范围在一起比较,以此获得一个较为可靠的评估依据。在sklearn当中,有两种方式调用这个评估指标,一种是使用sklearn专用的模型评估模块metrics里的类mean_squared_error,另一种是调用交叉验证的类cross_val_score并使用里面的scoring参数来设置使用均方误差。

from sklearn.metrics import mean_squared_error as MSE
MSE(yhat,Ytest)
print(y.max())
print(y.min())
cross_val_score(reg,X,y,cv=10,scoring="mean_squared_error")
#为什么报错了?来试试看!
import sklearn
sorted(sklearn.metrics.SCORERS.keys())
cross_val_score(reg,X,y,cv=10,scoring="neg_mean_squared_error")
#cross_val_score(reg,X,y,cv=10,scoring="neg_mean_squared_error")*(-1)

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

除了MSE,还有与MSE类似的MAE(Mean absolute error,绝对均值误差):
在这里插入图片描述
其表达的概念与均方误差完全一致,不过在真实标签和预测值之间的差异外使用的是L1范式(绝对值)。现实使用中,MSE和MAE选一个来使用就好了。在sklearn当中,使用命令from sklearn.metrics import mean_absolute_error来调用MAE,同时,也可以使用交叉验证中的scoring = “neg_mean_absolute_error”,以此在交叉验证时调用MAE。
2 是否拟合了足够的信息
对于回归类算法而言,只探索数据预测是否准确是不足够的。除了数据本身的数值大小之外,还希望模型能够捕捉到数据的”规律“,比如数据的分布规律,单调性等等,而是否捕获了这些信息并无法使用MSE来衡量。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值