- 这篇博文是DataWhale集成学习【上】的第二部分,主要是介绍机器学习里常用的回归模型
- 参考资料为DataWhale开源项目:机器学习集成学习与模型融合(基于python)和scikit-learn官网
- 学习交流欢迎联系 obito0401@163.com
前言
- 一般来说,一个完整的【监督】机器学习项目的主要步骤如下:
- 明确项目任务:分类 or 回归
- 收集数据集并选择合适的特征
- 选择度量模型性能的指标
- 选择具体的模型并进行训练
- 评估模型的性能并调整参数,优化模型
- 这一篇博客介绍的是一些常见的回归模型,主要介绍其原理以及Python的调用方法,对于具体的数学推导,目前打算在之后的一系列博客中予以展示(因为目前能力精力都达不到啊~ : ) )
数据集准备
- 这篇博客采用的数据集是 sklearn 自带的波士顿房价数据集 Boston,经典简洁,便于更快地理解回归模型的基本原理并加以实践
- 数据集的准备步骤如下所示:
import pandas as pd
from sklearn import datasets
# 加载原始数据集
boston = datasets.load_boston()
x = boston.data # 特征变量/自变量
y = boston.target # 目标变量/因变量
features = boston.feature_names # 特征名
# 合并
boston_data = pd.DataFrame(x,columns=features)
boston_data["Price"] = y
boston_data.head() # 展现示例数据集的头部信息
- 特征名称含义
name | info |
---|---|
CRIM | 各城镇的人均犯罪率 |
ZN | 规划地段超过25,000平方英尺的住宅用地比例 |
INDUS | 城镇非零售商业用地比例 |
CHAS | 是否在查尔斯河边(=1是) |
NOX | 一氧化氮浓度(/千万分之一) |
RM | 每个住宅的平均房间数 |
AGE | 1940年以前建造的自住房屋的比例 |
DIS | 到波士顿五个就业中心的加权距离 |
RAD | 放射状公路的可达性指数 |
TAX | 全部价值的房产税率(每1万美元) |
PTRATIO | 按城镇分配的学生与教师比例 |
B | 1000(Bk - 0.63)^2其中Bk是每个城镇的黑人比例 |
LSTAT | 较低地位人口 |
Price | 房价 |
模型评价指标
metric | intro |
---|---|
均方误差 | MSE ( y , y ^ ) = 1 n samples ∑ i = 0 n samples − 1 ( y i − y ^ i ) 2 . \text{MSE}(y, \hat{y}) = \frac{1}{n_\text{samples}} \sum_{i=0}^{n_\text{samples} - 1} (y_i - \hat{y}_i)^2. MSE(y,y^)=nsamples1∑i=0nsamples−1(yi−y^i)2. |
决定系数 | R 2 ( y , y ^ ) = 1 − ∑ i = 1 n ( y i − y ^ i ) 2 ∑ i = 1 n ( y i − y ˉ ) 2 R^2(y, \hat{y}) = 1 - \frac{\sum_{i=1}^{n} (y_i - \hat{y}_i)^2}{\sum_{i=1}^{n} (y_i - \bar{y})^2} R2(y,y^)=1−∑i=1n(yi−yˉ)2∑i=1n(yi−y^i)2 |
解释方差得分 | e x p l a i n e d _ v a r i a n c e ( y , y ^ ) = 1 − V a r { y − y ^ } V a r { y } explained\_{}variance(y, \hat{y}) = 1 - \frac{Var\{ y - \hat{y}\}}{Var\{y\}} explained_variance(y,y^)=1−Var{y}Var{y−y^} |
⋯ \cdots ⋯ | ⋯ \cdots ⋯ |
更多回归评价指标可以看这里
常用回归模型
线性回归模型
- 假设:数据集 D = { ( x 1 , y 1 ) , . . . , ( x N , y N ) } D = \{(x_1,y_1),...,(x_N,y_N) \} D={(x1,y1),...,(xN,yN)}, x i ∈ R p , y i ∈ R , i = 1 , 2 , . . . , N x_i \in R^p,y_i \in R,i = 1,2,...,N xi∈Rp,yi∈R,i=1,2,...,N, X = ( x 1 , x 2 , . . . , x N ) T , Y = ( y 1 , y 2 , . . . , y N ) T X = (x_1,x_2,...,x_N)^T,Y=(y_1,y_2,...,y_N)^T X=(x1,x2,...,xN)T,Y=(y1,y2,...,yN)T
- 假设X和Y之间存在线性关系,模型的具体形式为
y
^
=
f
(
w
)
=
w
T
x
\hat{y}=f(w) =w^Tx
y^=f(w)=wTx
- 而在估计参数时最常用的方法就是最小二乘法
L ( w ) = ∑ i = 1 N ∣ ∣ w T x i − y i ∣ ∣ 2 2 = ∑ i = 1 N ( w T x i − y i ) 2 = ( w T X T − Y T ) ( w T X T − Y T ) T = w T X T X w − 2 w T X T Y + Y Y T 因 此 , 我 们 需 要 找 到 使 得 L ( w ) 最 小 时 对 应 的 参 数 w , 即 : w ^ = a r g m i n L ( w ) 为 了 达 到 求 解 最 小 化 L ( w ) 问 题 , 我 们 应 用 高 等 数 学 的 知 识 , 使 用 求 导 来 解 决 这 个 问 题 : ∂ L ( w ) ∂ w = 2 X T X w − 2 X T Y = 0 , 因 此 : w ^ = ( X T X ) − 1 X T Y L(w) = \sum\limits_{i=1}^{N}||w^Tx_i-y_i||_2^2=\sum\limits_{i=1}^{N}(w^Tx_i-y_i)^2 = (w^TX^T-Y^T)(w^TX^T-Y^T)^T = w^TX^TXw - 2w^TX^TY+YY^T\\ 因此,我们需要找到使得L(w)最小时对应的参数w,即:\\ \hat{w} = argmin\;L(w)\\ 为了达到求解最小化L(w)问题,我们应用高等数学的知识,使用求导来解决这个问题: \\ \frac{\partial L(w)}{\partial w} = 2X^TXw-2X^TY = 0,因此: \\ \hat{w} = (X^TX)^{-1}X^TY L(w)=i=1∑N∣∣wTxi−yi∣∣22=i=1∑N(wTxi−yi)2=(wTXT−YT)(wTXT−YT)T=wTXTXw−2wTXTY+YYT因此,我们需要找到使得L(w)最小时对应的参数w,即:w^=argminL(w)为了达到求解最小化L(w)问题,我们应用高等数学的知识,使用求导来解决这个问题:∂w∂L(w)=2XTXw−2XTY=0,因此:w^=(XTX)−1XTY - 代码演示
from sklearn import linear_model # 引入线性回归方法
lin_reg = linear_model.LinearRegression() # 创建线性回归的类
lin_reg.fit(x,y) # 输入特征X和因变量y进行训练
print("模型系数:",lin_reg.coef_) # 输出模型的系数
print("模型得分:",lin_reg.score(x,y)) # 输出模型的决定系数R^2
线性回归模型推广
- 在线性回归中,我们假设因变量与特征之间的关系是线性关系,这样的假设很简单,但是也有个致命缺点,那就是当数据存在非线性关系时,我们使用线性回归模型进行预测会导致预测性能极其低下,因为模型的形式本身是线性的,无法表达数据中的非线性关系
- 因此也就会联想到推广线性回归模型,主要有两个形式:多项式回归和广义可加模型
多项式回归模型
- 为了体现因变量和特征的非线性关系,一个很自然而然的想法就是将标准的线性回归模型:
y i = w 0 + w 1 x i + ϵ i y_i = w_0 + w_1x_i + \epsilon_i yi=w0+w1xi+ϵi
换成一个多项式函数:
y i = w 0 + w 1 x i + w 2 x i 2 + . . . + w d x i d + ϵ y_i = w_0 + w_1x_i + w_2x_i^2 + ...+w_dx_i^d + \epsilon yi=w0+w1xi+w2xi2+...+wdxid+ϵ - 对于多项式的阶数d不能取过大,一般不大于3或者4,因为d越大,多项式曲线就会越光滑,在X的边界处有异常的波动(毕竟是指数波动嘛~)
- 代码实现
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import PolynomialFeatures # 多项式转换函数
poly = PolynomialFeatures(2) # 设置为二次多项式
x_train = poly.fit_transform(x)
model = LinearRegression().fit(x_train,y)
print("模型系数:",model.coef_) # 输出模型的系数
广义可加模型
- 广义可加模型(GAM:Generalized Additive Model)实际上是线性模型推广至非线性模型的一个框架,在这个框架中,每一个变量都用一个非线性函数来代替,但是模型本身保持整体可加性。
- GAM模型不仅仅可以用在线性回归的推广,还可以将线性分类模型进行推广。
- 具体的推广形式是:
标准的线性回归模型:
y i = w 0 + w 1 x i 1 + . . . + w p x i p + ϵ i y_i = w_0 + w_1x_{i1} +...+w_px_{ip} + \epsilon_i yi=w0+w1xi1+...+wpxip+ϵi
GAM模型框架:
y i = w 0 + ∑ j = 1 p f j ( x i j ) + ϵ i y_i = w_0 + \sum\limits_{j=1}^{p}f_{j}(x_{ij}) + \epsilon_i yi=w0+j=1∑pfj(xij)+ϵi - GAM模型的优点与不足:
- 优点:
- 简单容易操作,能够很自然地推广线性回归模型至非线性模型,使得模型的预测精度有所上升
- 由于模型本身是可加的,因此GAM还是能像线性回归模型一样把其他因素控制不变的情况下单独对某个变量进行推断,极大地保留了线性回归的易于推断的性质
- 缺点:
- GAM模型会经常忽略一些有意义的交互作用,比如某两个特征共同影响因变量,不过GAM还是能像线性回归一样加入交互项 x ( i ) × x ( j ) x^{(i)} \times x^{(j)} x(i)×x(j)的形式进行建模
- 代码实现
- 优点:
from pygam import LinearGAM
gam = LinearGAM().fit(x,y)
gam.summary()
回归树
- 基于树的回归方法主要是依据分层和分割的方式将特征空间划分为一系列简单的区域;对某个给定的待预测的自变量,用它所属区域中训练集的平均数或者众数对其进行预测;由于划分特征空间的分裂规则可以用树的形式进行概括,因此这类方法称为决策树方法
- 决策树由**结点(node)和有向边(diredcted edge)**组成
- 结点有两种类型:内部结点(internal node)和叶结点(leaf node)
- 内部结点表示一个特征或属性,叶结点表示一个类别或者某个值。区域
R
1
,
R
2
R_1,R_2
R1,R2等称为叶节点,将特征空间分开的点为内部节点
- 建立回归树的过程大致可以分为以下两步:
- 将自变量的特征空间(即 x ( 1 ) , x ( 2 ) , x ( 3 ) , . . . , x ( p ) x^{(1)},x^{(2)},x^{(3)},...,x^{(p)} x(1),x(2),x(3),...,x(p))的可能取值构成的集合分割成J个互不重叠的区域 R 1 , R 2 , . . . , R j R_1,R_2,...,R_j R1,R2,...,Rj。
- 对落入区域
R
j
R_j
Rj的每个观测值作相同的预测,预测值等于
R
j
R_j
Rj上训练集的因变量的简单算术平均。
具体来说,就是:
a. 选择最优切分特征j以及该特征上的最优点s:
遍历特征j以及固定j后遍历切分点s,选择使得下式最小的(j,s) m i n j , s [ m i n c 1 ∑ x i ∈ R 1 ( j , s ) ( y i − c 1 ) 2 + m i n c 2 ∑ x i ∈ R 2 ( j , s ) ( y i − c 2 ) 2 ] min_{j,s}[min_{c_1}\sum\limits_{x_i\in R_1(j,s)}(y_i-c_1)^2 + min_{c_2}\sum\limits_{x_i\in R_2(j,s)}(y_i-c_2)^2 ] minj,s[minc1xi∈R1(j,s)∑(yi−c1)2+minc2xi∈R2(j,s)∑(yi−c2)2]
b. 按照(j,s)分裂特征空间: R 1 ( j , s ) = { x ∣ x j ≤ s } 和 R 2 ( j , s ) = { x ∣ x j > s } , c ^ m = 1 N m ∑ x ∈ R m ( j , s ) y i , m = 1 , 2 R_1(j,s) = \{x|x^{j} \le s \}和R_2(j,s) = \{x|x^{j} > s \},\hat{c}_m = \frac{1}{N_m}\sum\limits_{x \in R_m(j,s)}y_i,\;m=1,2 R1(j,s)={x∣xj≤s}和R2(j,s)={x∣xj>s},c^m=Nm1x∈Rm(j,s)∑yi,m=1,2
c. 继续调用步骤1,2直到满足停止条件,就是每个区域的样本数小于等于5。
d. 将特征空间划分为J个不同的区域,生成回归树: f ( x ) = ∑ m = 1 J c ^ m I ( x ∈ R m ) f(x) = \sum\limits_{m=1}^{J}\hat{c}_mI(x \in R_m) f(x)=m=1∑Jc^mI(x∈Rm)
- 回归树与线性模型的比较:
- 线性模型的模型形式与树模型的模型形式有着本质的区别,具体而言,线性回归对模型形式做了如下假定: f ( x ) = w 0 + ∑ j = 1 p w j x ( j ) f(x) = w_0 + \sum\limits_{j=1}^{p}w_jx^{(j)} f(x)=w0+j=1∑pwjx(j),而回归树则是 f ( x ) = ∑ m = 1 J c ^ m I ( x ∈ R m ) f(x) = \sum\limits_{m=1}^{J}\hat{c}_mI(x \in R_m) f(x)=m=1∑Jc^mI(x∈Rm)
- 那问题来了,哪种模型更优呢?这个要视具体情况而言,如果特征变量与因变量的关系能很好的用线性关系来表达,那么线性回归通常有着不错的预测效果,拟合效果则优于不能揭示线性结构的回归树。反之,如果特征变量与因变量呈现高度复杂的非线性关系,那么树方法比传统方法更优
- 树模型的优缺点:
- 树模型的解释性强,在解释性方面可能比线性回归还要方便
- 树模型更接近人的决策方式,树模型可以用图来表示,可读性强
- 树模型可以直接做定性的特征而不需要像线性回归一样哑元化
- 树模型能很好处理缺失值和异常值,对异常值不敏感,但是这个对线性模型来说却是致命的
- 树模型的预测准确性一般无法达到其他回归模型的水平,但是改进的方法很多
- 代码实现
支持向量回归
-
支持向量回归是将支持向量机(SVM)的方法应用到回归问题上,称为SVR(Support Vector Regression)
-
在线性回归的理论中,每个样本点都要计算平方损失,但是SVR却是不一样的。SVR认为:落在 f ( x ) f(x) f(x)的 ϵ \epsilon ϵ邻域空间中的样本点不需要计算损失,这些都是预测正确的,其余的落在 ϵ \epsilon ϵ邻域空间以外的样本才需要计算损失,因此:
-
代码实现