集成学习(2)- 回归模型

2021-03-18  本文已影响0人  木头里有虫911

接下来我们开始构建简单的回归模型,并使用sklearn中自带的数据集进行演示。我们会介绍三种常用的回归模型,分别是线性回归,回归树和SVM支持向量机模型。

对于任何一个机器学习模型,我们都可以从三个方面来进行解剖,即:

说道策略,一般会讲到,经验风险最小化作为常用的标准。经验风险最小是指,用这个模型,套到已有的观测数据上,基本上是靠谱的。这也是大多数时候我们在机器学习时候有意或无意就用到的准侧。经验风险最小化是一个参数优化的过程,我们需要构造一个损失函数来描述经验风险,损失函数可以理解为我们预测一个数据错了给我们带来的代价。每个人对损失函数的定义都不同,所以优化出来的结果也不同,这也导致最终我们学习到的模型会各种各样,解决一个问题的方案有多种多样…

我们通过策略实现模型的方法就是算法
我们有了数据,有了学习模型的策略,然后就要开始去构造模型了,如果模型的基本形式有了,就是一个优化模型参数的问题了。如果学习过确定性模型的朋友,优化并不陌生,但是优化过程往往是复杂的,面对复杂的数学优化问题我们通常难以通过简单的求导获得最终的结果,所以就要构造一系列的算法。

我们的目标是让算法尽量高效,更少的计算机内存代价,更快的运算速度,更有效的参数优化结果…

模型、策略和算法这三样东西好比打开机器学习模型的三把金钥匙,明白了这三把钥匙的含义,也就能深入理解这个模型了。下面分别阐述

1. 线性回归

模型:对于线性回归的模型,一般可以用如下的矩阵来描述:
假设:数据集D = \{(x_1,y_1),...,(x_N,y_N) \}x_i \in R^p,y_i \in R,i = 1,2,...,NX = (x_1,x_2,...,x_N)^T,Y=(y_1,y_2,...,y_N)^T
假设X和Y之间存在线性关系,模型的具体形式为:
\hat{y}=f(w) =w^Tx

策略:
我们采用真实值y_i与线性回归模型的预测值w^Tx_i之间的差距,在这里我们和使用二范数的平方和L(w)来描述这种差距,即:
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
我们需要找到使得L(w)最小时对应的参数w,即:\\ \hat{w} = argmin\;L(w)\\
所以,我们策略就是寻找最小的w组合,使得L(w)最小。

如何寻找呢?这就是算法了。
一般我们采用梯度下降算法来解决,及对L(w)求导。

线性模型形式简单、易于建模。但是却蕴含着机器学习中一些重要的基本思想。许多功能更为强大的非线性模型可以在线性模型的基础上通过引入层级结构或高维映射而得。此外,由于w直观表达了各属性在预测中的重要性,因此线性模型有很好的可解释性。并且经常作为各个系统的基线模型。

2. 回归树

决策树(Decision Tree)是一种基本的分类与回归方法,当决策树用于分类时称为分类树,用于回归时称为回归树。
基于树的回归方法主要是依据分层和分割的方式将特征空间划分为一系列简单的区域。对某个给定的待预测的自变量,用他所属区域中训练集的平均数或者众数对其进行预测。由于划分特征空间的分裂规则可以用树的形式进行概括,因此这类方法称为决策树方法。决策树由结点(node)和有向边(diredcted edge)组成。结点有两种类型:内部结点(internal node)和叶结点(leaf node)。内部结点表示一个特征或属性,叶结点表示一个类别或者某个值。区域 𝑅1,𝑅2R1,R2 等称为叶节点,将特征空间分开的点为内部节点。

建立回归树的过程大致可以分为以下两步:
- 1. 将自变量的特征空间(即x^{(1)},x^{(2)},x^{(3)},...,x^{(p)})的可能取值构成的集合分割成J个互不重叠的区域R_1,R_2,...,R_j
- 2. 对落入区域R_j的每个观测值作相同的预测,预测值等于R_j上训练集的因变量的简单算术平均。
具体来说,就是:
a. 选择最优切分特征j以及该特征上的最优点s:
遍历特征j以及固定j后遍历切分点s,选择使得下式最小的(j,s) 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 ]
b. 按照(j,s)分裂特征空间: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
c. 继续调用步骤1,2直到满足停止条件,就是每个区域的样本数小于等于5。
d. 将特征空间划分为J个不同的区域,生成回归树:f(x) = \sum\limits_{m=1}^{J}\hat{c}_mI(x \in R_m)
树模型的优缺点:
- 树模型的解释性强,在解释性方面可能比线性回归还要方便。
- 树模型更接近人的决策方式。
- 树模型可以用图来表示,非专业人士也可以轻松解读。
- 树模型可以直接做定性的特征而不需要像线性回归一样哑元化。
- 树模型能很好处理缺失值和异常值,对异常值不敏感,但是这个对线性模型来说却是致命的。
- 树模型的预测准确性一般无法达到其他回归模型的水平,但是改进的方法很多。

3. 支持向量机回归(SVR)

支持向量机模型可以之前的文章: https://www.jianshu.com/p/b6b8ae283471

下面通过sklearn中的数据集进行演示,我们还是用之前房价预测数据集

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()
image.png

下面分别导入线性回归、决策树、和SVR模型进行训练和预测:

from sklearn.tree import DecisionTreeRegressor  # 导入回归树模型
from sklearn.svm import SVR # 支持向量机模型

lin_reg = linear_model.LinearRegression()       # 创建线性回归的类
lin_reg.fit(X,y)        # 输入特征X和因变量y进行训练
print('使用线性回归模型:')
print("模型系数:",lin_reg.coef_)             # 输出模型的系数
print("模型得分:",lin_reg.score(X,y))    # 输出模型的决定系数R^2
print('-' * 20)
  
reg_tree = DecisionTreeRegressor(criterion = "mse",min_samples_leaf = 5)
reg_tree.fit(X,y)
print('使用决策树回归模型:')
print('模型的得分为:', reg_tree.score(X,y))
print('-' * 20)

from sklearn.preprocessing import StandardScaler     # 标准化数据
from sklearn.pipeline import make_pipeline   # 使用管道,把预处理和模型形成一个流程
print('使用SVR回归模型:')
reg_svr = make_pipeline(StandardScaler(), SVR(C=1.0, epsilon=0.2))
reg_svr.fit(X, y)
print("使用SVR模型的分数 :" , reg_svr.score(X,y))
>>>
使用线性回归模型:
模型系数: [-1.08011358e-01  4.64204584e-02  2.05586264e-02  2.68673382e+00
 -1.77666112e+01  3.80986521e+00  6.92224640e-04 -1.47556685e+00
  3.06049479e-01 -1.23345939e-02 -9.52747232e-01  9.31168327e-03
 -5.24758378e-01]
模型得分: 0.7406426641094095
--------------------
使用决策树回归模型:
模型的得分为: 0.9376307599929274
--------------------
使用SVR回归模型:
使用SVR模型的分数 : 0.7024525421955277
  1. 模型优化
    当完成一个完整的模型构建训练并预测出结果后,相当与我们完成了一个机器学习的baseline,剩下的部分就是如何优化提高模型分数了。这一部分一般可以从两个方面着手:
# 我们先来对未调参的SVR进行评价: 
from sklearn.svm import SVR     # 引入SVR类
from sklearn.pipeline import make_pipeline   # 引入管道简化学习流程
from sklearn.preprocessing import StandardScaler # 由于SVR基于距离计算,引入对数据进行标准化的类
from sklearn.model_selection import GridSearchCV  # 引入网格搜索调优
from sklearn.model_selection import cross_val_score # 引入K折交叉验证
from sklearn import datasets


boston = datasets.load_boston()     # 返回一个类似于字典的类
X = boston.data
y = boston.target
features = boston.feature_names
pipe_SVR = make_pipeline(StandardScaler(),
                                                         SVR())
score1 = cross_val_score(estimator=pipe_SVR,
                                                     X = X,
                                                     y = y,
                                                     scoring = 'r2',
                                                      cv = 10)       # 10折交叉验证
print("CV accuracy: %.3f +/- %.3f" % ((np.mean(score1)),np.std(score1)))
>>>
CV accuracy: 0.187 +/- 0.649

下面我们使用网格搜索来对SVR调参:

# 下面我们使用网格搜索来对SVR调参:
from sklearn.pipeline import Pipeline
pipe_svr = Pipeline([("StandardScaler",StandardScaler()),
                                                         ("svr",SVR())])
param_range = [0.0001,0.001,0.01,0.1,1.0,10.0,100.0,1000.0]
param_grid = [{"svr__C":param_range,"svr__kernel":["linear"]},  # 注意__是指两个下划线,一个下划线会报错的
                            {"svr__C":param_range,"svr__gamma":param_range,"svr__kernel":["rbf"]}]
gs = GridSearchCV(estimator=pipe_svr,
                                                     param_grid = param_grid,
                                                     scoring = 'r2',
                                                      cv = 10)       # 10折交叉验证
gs = gs.fit(X,y)
print("网格搜索最优得分:",gs.best_score_)
print("网格搜索最优参数组合:\n",gs.best_params_)
>>>
网格搜索最优得分: 0.6081303070817233
网格搜索最优参数组合:
 {'svr__C': 1000.0, 'svr__gamma': 0.001, 'svr__kernel': 'rbf'}
上一篇 下一篇

猜你喜欢

热点阅读