【机器学习】一文理解集成学习Boosting思想之GBDT、XGBoost,附带案例

前言

AdaBoost

前面我们介绍了使用 Boosting 思想的 AdaBoost ,它是通过前一轮决策的结果来给样本设置权重,决策正确的权重减小,决策错误的权重增加;然后将加权后的数据集输入下一个弱学习器训练,直到达到训练停止条件。

Boosting 思想的GBDTXGBoost,在目前的竞赛和工业界中使用非常频繁,能够有效的应用到分类、回归,更是因为近几年被应用于构建搜索排序的机器学习模型而引起广泛关注。虽然用起来不难,但是要想完整理解它的原理及推导不是那么容易,本篇尽可能通过简单的方式来介绍。

本篇代码可见:Github

一、提升树模型

在介绍 GBDT 前,我们先来理解何为提升树:

提升树是以决策树为基本分类器(弱分类器)的提升方法,提升树被认为是模型性能最好的方法之一。

  • 对于分类问题决策树为二叉分类树;
  • 对于回归问题决策树为二叉回归树。

提升树模型可以表示为决策树的加法模型:

f M ( x ) = ∑ m = 1 M T ( x ;   Θ m ) f_M(x) = \sum_{m=1}^M T(x;\ Θ_m) fM(x)=m=1MT(x; Θm)

其中, T ( x ;   Θ m ) T(x;\ Θ_m) T(x; Θm)表示决策树; Θ m Θ_m Θm表示决策树的参数; M M M表示数的个数

1、提升树算法

由于提升树是树的线性组合,而树的线性组合可以很好地拟合训练数据,即使数据中的输入和输出之间的关系很复杂也是如此,所以提升树是一个高功能的学习算法。

提升树学习算法的主要区别在于使用的损失函数不同:

  • 平方误差损失函数的回归问题;
  • 指数损失函数的分类问题;
  • 一般损失函数的一般决策问题。
  1. 分类问题

\quad\quad 对于二分类问题,提升树只需要将 AdaBoost 算法中的基本分类器(弱学习器)限定为二分类数即可,可以说这时的提升树是AdaBoost 算法的特殊情况,具体参考 AdaBoost 的介绍来理解。

  1. 回归问题

\quad\quad 已知一个训练数据集 T = { ( x 1 , y 1 ) , ( x 2 , y 2 ) , . . . , ( x N , y N ) } T = \{(x_1,y_1),(x_2,y_2),...,(x_N,y_N)\} T={(x1,y1),(x2,y2),...,(xN,yN)} x i ∈ X ⊆ R n x_i \in \mathcal{X} \subseteq R^{n} xiXRn X \mathcal{X} X为输入空间, y i ∈ Y ⊆ R y_i \in \mathcal{Y} \subseteq R yiYR Y \mathcal{Y} Y为输出空间。

如果将输入空间划分为 J J J 个互相不相交的区域 R 1 , R 2 , . . . , R J R_1,R_2,...,R_J R1R2...RJ,并且在每个区域上确定输出的常量 c j c_j cj,那么决策树可表示为:

T ( x ; Θ ) = ∑ j = 1 J c j I ( x ∈ R j ) T(x; Θ) = \sum_{j=1}^J c_jI(x \in R_j) T(x;Θ)=j=1JcjI(xRj)

I ( x ∈ R j ) I(x \in R_j) I(xRj)为指示函数,表示 如果 x x x 在分区 R j R_j Rj中返回1,否则返回0;$T(x; Θ) $表示每个区域的输出常量的集合
其中,参数 Θ = { ( R 1 , c 1 ) , ( R 2 , c 2 ) , . . . , ( R j , c j ) } Θ = \{(R_1,c_1),(R_2,c_2),...,(R_j,c_j)\} Θ={(R1,c1),(R2,c2),...,(Rj,cj)}表示数的区域划分和各区域上的常量; J J J是回归树的复杂度,即叶子节点

回归问题提升树使用以下前向分步算法:
f 0 ( x ) = 0 f_0(x) = 0 f0(x)=0
f m ( x ) = f m − 1 ( x ) + T ( x ; Θ m ) m = 1 , 2 , 3 , . . . , M f_m(x) = f_{m-1}(x) + T(x; Θ_m)\quad\quad m = 1,2,3,...,M fm(x)=fm1(x)+T(x;Θm)m=1,2,3,...,M
f M ( x ) = ∑ m = 1 M T ( x ; Θ m ) f_M(x) = \sum_{m=1}^M T(x; Θ_m) fM(x)=m=1MT(x;Θm)
在前向分步算法的第m步,给定当前模型 f m − 1 ( x ) f_{m-1}(x) fm1(x),需求解:
Θ m ^ = a r g min ⁡ Θ m ∑ i = 1 N L ( y i , f m − 1 ( x i ) + T ( x ; Θ m ) ) \hat{Θ_m} = arg \min_{Θ_m} \sum_{i=1}^N L\Big(y_i, f_{m-1}(x_i) + T(x;Θ_m)\Big) Θm^=argΘmmini=1NL(yi,fm1(xi)+T(x;Θm))
得到 Θ m ^ \hat{Θ_m} Θm^ ,即第m棵树的参数。

其中, L ( y i , f m − 1 ( x i ) + T ( x ; Θ m ) ) L\Big(y_i, f_{m-1}(x_i) + T(x;Θ_m)\Big) L(yi,fm1(xi)+T(x;Θm))为损失函数,当使用平方误差损失时:
L ( y , f ( x ) ) = ( y − f ( x ) ) 2 L(y, f(x)) = (y - f(x)) ^2 L(y,f(x))=(yf(x))2
y y y为真实值, f ( x ) f(x) f(x)为预测值

Θ m ^ \hat{Θ_m} Θm^中的损失变为:

L ( y i , f m − 1 ( x i ) + T ( x ; Θ m ) ) L\Big(y_i, f_{m-1}(x_i) + T(x;Θ_m)\Big) L(yi,fm1(xi)+T(x;Θm))
= [ y − ( f m − 1 ( x ) + T ( x ; Θ m ) ] 2 = [y - (f_{m-1}(x) + T(x;Θ_m)]^2 =[y(fm1(x)+T(x;Θm)]2
= [ r − T ( x ; Θ m ) ] 2 = [r -T(x;Θ_m)]^2 =[rT(x;Θm)]2

其中, r = y − f m − 1 ( x ) r = y - f_{m-1}(x) r=yfm1(x)是当前模型拟合数据的残差

所以对于回归问题的提升树算法来说,只需要简单地拟合当前模型的残差即可。

回归问题的提升树算法:

输入: T = { ( x 1 , y 1 ) , ( x 2 , y 2 ) , . . . , ( x N , y N ) } T = \{(x_1,y_1),(x_2,y_2),...,(x_N,y_N)\} T={(x1,y1),(x2,y2),...,(xN,yN)} x i ∈ X ⊆ R n x_i \in \mathcal{X} \subseteq R^{n} xiXRn y i ∈ Y ⊆ R y_i \in \mathcal{Y} \subseteq R yiYR
输出:提升树 f M ( x ) f_M(x) fM(x)
(1)初始化树 f 0 ( x ) = 0 f_0(x) = 0 f0(x)=0
(2)对 m = 1 , 2 , . . . , M m = 1,2,...,M m=1,2,...,M

  • (a)计算残差

r m i = y i − f m − 1 ( x i ) i = 1 , 2 , . . . , N r_{mi} = y_i - f_{m-1}(x_i) \quad\quad i = 1,2,...,N rmi=yifm1(xi)i=1,2,...,N

  • (b)拟合残差 $r_{mi} $ 学习一个回归树,得到 T ( x ; Θ m ) T(x;Θ_m) T(x;Θm)
  • (c)更新 f m ( x ) = f m − 1 ( x ) + T ( x ; Θ m ) f_m(x) = f_{m-1}(x) + T(x; Θ_m) fm(x)=fm1(x)+T(x;Θm)

(3)得到回归提升树:
f M ( x ) = ∑ m = 1 M T ( x ; Θ m ) f_M(x) = \sum_{m=1}^M T(x; Θ_m) fM(x)=m=1MT(x;Θm)

2、实例

通过数据数据进一步理解回归提升树。已知训练数据 x x x的取值范围为 [ 0.5 , 10.5 ] [0.5, 10.5] [0.5,10.5] y y y的取值范围为 [ 5.0 , 10.0 ] [5.0, 10.0] [5.0,10.0],如下表:

x i x_i xi12345678910
y i y_i yi5.565.705.916.406.807.058.908.709.009.05

下面就按照上面的回归问题的提升树算法来求:

考虑以下优化问题:
min ⁡ s [ min ⁡ c 1 ∑ x i ∈ R 1 ( y i − c 1 ) 2 + min ⁡ c 2 ∑ x i ∈ R 2 ( y i − c 2 ) 2 ] \min_s[\min_{c_1}\sum_{x_i \in R_1}(y_i - c_1)^2 +\min_{c_2}\sum_{x_i \in R_2}(y_i - c_2)^2 ] smin[c1minxiR1(yic1)2+c2minxiR2(yic2)2]
求解训练数据的切分点s:
R 1 = { x ∣ x ⩽ s } R 2 = { x ∣ x > s } R_1=\{x|x \leqslant s\} \quad\quad R_2= \{x|x > s\} R1={xxs}R2={xx>s}
容易求得在 R 1 , R 2 R_1,R_2 R1,R2内部使平方损失误差达到最小值的 c 1 , c 2 c_1,c_2 c1,c2为:
c 1 = 1 N ∑ x i ∈ R 1 y i c 2 = 1 N ∑ x i ∈ R 2 y i c_1 = \frac{1}{N}\sum_{x_i \in R_1} y_i \quad\quad c_2 = \frac{1}{N}\sum_{x_i \in R_2} y_i c1=N1xiR1yic2=N1xiR2yi
这里 N 1 , N 2 N_1,N_2 N1,N2 R 1 , R 2 R_1,R_2 R1,R2的样本点数。

第一步:求 T 1 ( x ) T_1(x) T1(x)

求训练数据的切分点,根据所给数据,考虑如下切分点:
1.5 ,   2.5 ,   3.5 ,   4.5 ,   5.5 ,   6.5 ,   7.5 ,   8.5 ,   9.5 1.5,\ 2.5,\ 3.5,\ 4.5,\ 5.5,\ 6.5,\ 7.5,\ 8.5,\ 9.5 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5, 9.5
对各切分点,不难求出相应的 R 1 , R 2 , c 1 , c 2 R_1,R_2,c_1,c_2 R1,R2,c1,c2
m ( s ) = min ⁡ c 1 ∑ x i ∈ R 1 ( y i − c 1 ) 2 + min ⁡ c 2 ∑ x i ∈ R 2 ( y i − c 2 ) 2 m(s) = \min_{c_1}\sum_{x_i \in R_1}(y_i - c_1)^2 +\min_{c_2}\sum_{x_i \in R_2}(y_i - c_2)^2 m(s)=c1minxiR1(yic1)2+c2minxiR2(yic2)2

例如,当 s = 1.5 s = 1.5 s=1.5时, R 1 = { 1 } , R 2 = { 2 , 3 , . . . , 10 } , c 1 = 5.56 , c 2 = 7.50 R_1=\{1\},R_2 = \{2,3,...,10\},c_1=5.56,c_2=7.50 R1={1}R2={2,3,...,10}c1=5.56c2=7.50
m ( s ) = min ⁡ c 1 ∑ x i ∈ R 1 ( y i − c 1 ) 2 + min ⁡ c 2 ∑ x i ∈ R 2 ( y i − c 2 ) 2 = 0 + 15.72 = 15.72 m(s) = \min_{c_1} \sum_{x_i \in R_1}(y_i - c_1)^2 + \min_{c_2} \sum_{x_i \in R_2}(y_i - c_2)^2 = 0 + 15.72 = 15.72 m(s)=c1minxiR1(yic1)2+c2minxiR2(yic2)2=0+15.72=15.72

计算所有切分点 s s s m ( s ) m(s) m(s),如下表:

s1.52.53.54.55.56.57.58.59.5
m ( s ) m(s) m(s)15.7212.078.365.783.911.938.0111.7315.74

由上表可知,当 s = 6.5 s = 6.5 s=6.5 m ( s ) m(s) m(s)达到最小值,此时 R 1 = { 1 , 2 , 3 , 4 , 5 , 6 } , R 2 = { 7 , 8 , 9 , 10 } , c 1 = 6.24 , c 2 = 8.91 R_1=\{1,2,3,4,5,6\},R_2=\{7,8,9,10\},c_1=6.24,c_2=8.91 R1={1,2,3,4,5,6}R2={7,8,9,10}c1=6.24c2=8.91,所以回归树 T 1 ( x ) T_1(x) T1(x)为:
T 1 ( x ) = { 6.24 , x &lt; 6.5 8.91 , x ⩾ 6.5 T_1(x)=\begin{cases} 6.24, \quad x &lt; 6.5 \\ 8.91, \quad x \geqslant 6.5 \end{cases} T1(x)={6.24,x<6.58.91,x6.5
f 1 ( x ) = T 1 ( x ) f_1(x) = T_1(x) f1(x)=T1(x)

f 1 ( x ) f_1(x) f1(x) 拟合训练数据的残差如下表, r 2 i = y i − f 1 ( x i ) , i = 1 , 2 , . . . , 10 r_{2i} = y_i - f_1(x_i),\quad i=1,2,...,10 r2i=yif1(xi),i=1,2,...,10

x i x_i xi12345678910
r 2 i r_{2i} r2i-0.68-0.54-0.330.160.560.81-0.01-0.210.090.14

f 1 ( x ) f_1(x) f1(x) 拟合训练数据的平方损失误差:
L ( y , f 1 ( x ) ) = ∑ i = 1 10 ( y i − f 1 ( x i ) ) 2 = 1.93 L(y, f_1(x)) = \sum_{i=1}^{10}(y_i - f_1(x_i))^2 = 1.93 L(y,f1(x))=i=110(yif1(xi))2=1.93

第二步:求 T 2 ( x ) T_2(x) T2(x)

方法与第一步一样,只是拟合的数据从原数据变为残差数据,可以得到:
T 2 ( x ) = { − 0.52 , x &lt; 3.5 0.22 ,     x ⩾ 3.5 T_2(x)=\begin{cases} -0.52, \quad x &lt; 3.5 \\ 0.22, \ \ \ \quad x \geqslant 3.5 \end{cases} T2(x)={0.52,x<3.50.22,   x3.5
f 2 ( x ) = f 1 ( x ) + T 2 ( x ) = { 5.72 , x &lt; 3.5 6.46 , 3.5 ⩽ x &lt; 6.5 9.13 , x ⩾ 6.5 f_2(x) = f_1(x) + T_2(x) = \begin{cases} 5.72, \quad x &lt; 3.5 \\ 6.46, \quad 3.5 \leqslant x &lt; 6.5 \\ 9.13, \quad x \geqslant 6.5 \end{cases} f2(x)=f1(x)+T2(x)=5.72,x<3.56.46,3.5x<6.59.13,x6.5

f 2 ( x ) f_2(x) f2(x) 拟合训练数据的平方损失误差:
L ( y , f 2 ( x ) ) = ∑ i = 1 10 ( y i − f 2 ( x i ) ) 2 = 0.79 L(y, f_2(x)) = \sum_{i=1}^{10}(y_i - f_2(x_i))^2 = 0.79 L(y,f2(x))=i=110(yif2(xi))2=0.79

重复以上步骤,求得:

T 3 ( x ) = { 0.15 ,     x &lt; 6.5 − 0.22 , x ⩾ 6.5 T_3(x)=\begin{cases} 0.15, \ \ \ \quad x &lt; 6.5 \\ -0.22, \quad x \geqslant 6.5 \end{cases} T3(x)={0.15,   x<6.50.22,x6.5
L ( y , f 3 ( x ) ) = 0.47 L(y, f_3(x)) = 0.47 L(y,f3(x))=0.47


T 4 ( x ) = { − 0.16 , x &lt; 4.5 0.11 ,     x ⩾ 4.5 T_4(x)=\begin{cases} -0.16, \quad x &lt; 4.5 \\ 0.11, \ \ \ \quad x \geqslant 4.5 \end{cases} T4(x)={0.16,x<4.50.11,   x4.5
L ( y , f 4 ( x ) ) = 0.30 L(y, f_4(x)) = 0.30 L(y,f4(x))=0.30


T 5 ( x ) = { 0.07 ,     x &lt; 6.5 − 0.11 , x ⩾ 6.5 T_5(x)=\begin{cases} 0.07, \ \ \ \quad x &lt; 6.5 \\ -0.11, \quad x \geqslant 6.5 \end{cases} T5(x)={0.07,   x<6.50.11,x6.5
L ( y , f 5 ( x ) ) = 0.23 L(y, f_5(x)) = 0.23 L(y,f5(x))=0.23


T 6 ( x ) = { − 0.15 , x &lt; 2.5 0.04 ,     x ⩾ 2.5 T_6(x)=\begin{cases} -0.15, \quad x &lt; 2.5 \\ 0.04, \ \ \ \quad x \geqslant 2.5 \end{cases} T6(x)={0.15,x<2.50.04,   x2.5
f 6 ( x ) = f 5 ( x ) + T 6 ( x ) = T 1 ( x ) + T 2 ( x ) + T 3 ( x ) + T 4 ( x ) + T 5 ( x ) + T 6 ( x ) f_6(x) = f_5(x) + T_6(x) = T_1(x)+T_2(x)+T_3(x)+T_4(x)+T_5(x)+T_6(x) f6(x)=f5(x)+T6(x)=T1(x)+T2(x)+T3(x)+T4(x)+T5(x)+T6(x)
f 6 ( x ) = { 5.63 , x &lt; 2.5 5.82 , 2.5 ⩽ x &lt; 3.5 6.56 , 3.5 ⩽ x &lt; 4.5 6.83 , 4.5 ⩽ x &lt; 6.5 8.95 , x ⩾ 6.5 f_6(x)= \begin{cases} 5.63, \quad x&lt;2.5 \\ 5.82, \quad 2.5 \leqslant x &lt; 3.5 \\ 6.56, \quad 3.5 \leqslant x &lt; 4.5 \\ 6.83, \quad 4.5 \leqslant x &lt; 6.5 \\ 8.95, \quad x \geqslant 6.5 \end{cases} f6(x)=5.63,x<2.55.82,2.5x<3.56.56,3.5x<4.56.83,4.5x<6.58.95,x6.5
L ( y , f 3 ( x ) ) = 0.17 L(y, f_3(x)) = 0.17 L(y,f3(x))=0.17

假设此时已经满足误差要求,那么 f ( x ) = f 6 ( x ) f(x) = f_6(x) f(x)=f6(x) 即为所求提升树。

二、GBDT(Gradient Boosting Decison Tree)(梯度提升迭代决策树)

别名:GBT(Gradient Boosting Tree)GTB(Gradient Tree Boosting)GBRT(Gradient Boosting Regression Tree)MART(Multiple Additive Regression Tree)

1、 GBDTAdaBoost 的区别:
  • AdaBoost算法是利用前一轮的弱学习器的误差来更新样本权重值,然后一轮一轮的迭代;
  • GBDT也是迭代,但是GBDT要求弱学习器必须是CART模型,而且GBDT在模型训练的时候,是要求模型预测的样本损失尽可能的小。
2、直观理解

在这里插入图片描述

  • 如图,此过程便是上面提到的提升树。假设我们有训练集 ( x 1 , x 2 , x 3 , 30 ) (x_1,x_2,x_3,30) (x1,x2,x3,30) ,x为特征,30为年龄;
  • 第一次训练的弱分类器预测为20,然后我们用真实值-第一个弱分类器的预测值=残差,作为第二个弱分类器的训练数据 ( x 1 , x 2 , x 3 , 10 ) (x_1,x_2,x_3,10) (x1,x2,x3,10)
  • 第二次训练的弱分类器预测为6,同样计算残差作为第三个弱分类器的训练数据, ( x 1 , x 2 , x 3 , 4 ) (x_1,x_2,x_3,4) (x1,x2,x3,4)
  • 第三次训练的弱分类器预测为4,同样计算残差作为第四个弱分类器的训练数据, ( x 1 , x 2 , x 3 , 1 ) (x_1,x_2,x_3,1) (x1,x2,x3,1)
  • 第四次训练的弱分类器预测为1,此时残差为0,训练结束

假设有个新的待预测数据,按构建子树的顺序进行预测,然后将每个子树的预测结果累加便是预测结果。

3、简单实例

假设训练集如下:

样本编号购物金额上网时长上网时段对百度知道的使用方式年龄
A0.5k0.5h晚上上网提问14
B0.8k1.5h晚上上网回答16
C1.5k3.0h全天上网提问24
D2.0k3.0h晚上上网回答26
  1. 如果按传统的决策树构建,可如下图:

在这里插入图片描述

对于训练集,此决策树的准确率为100%;
我们知道在构建决策树的时候,为了尽可能正确分类训练样本,节点划分过程不断重复,有时候就会导致决策树节点过多,造成模型过拟合;

  • 假设待预测数据为:购物金额0.5k,上网时长1.5h,晚上上网,提问,14岁
  • 传统决策树会预测为16岁
  1. 如果使用GBDT来训练

由于数据比较少,我们限定2棵子树,每个子树深度为1,训练结果如下图:

在这里插入图片描述

图中,上面一棵树还是按有收入是否划分,下面一棵树以前面一个数的残差作为训练样本,当新的预测值与残差相等(也就第二次计算的残差中为0的),则只需把第二棵树的结论累加到第一棵树上就能得到真实年龄;第二棵树的残差都为0,说明所有样本都正确预测了

  • A:0.5k;0.5h;晚上上网;提问;预测年龄:(-1)+15=14
  • B:0.8k;1.5h;晚上上网;回答;预测年龄:1+15=16
  • C:1.5k;3.0h;全天上网;提问;预测年龄:(-1)+25=24
  • D:2.0k;3.0h;晚上上网;回答;预测年龄:1+25=26

其实,我们发现两个方法的准确率都是100%,那么为什么要用GBDT呢?

原因就是,传统的决策树容易过拟合,假设有个新数据待预测:购物金额0.5k,上网时长1.5h,晚上上网,提问,14岁;

  • 传统决策树预测结果为16岁;
  • GBDT 预测为:(-1)+15=14岁;

现在,我们回头来看看上图,由20变为0,变化比较大,容易造成过拟合;
可以给定步长 step,在构建下一棵树的时候使用step * 残差值作为输入,这样可以避免过拟合。

三、GBDT 算法推导

GBDT由三部分构成:DT(Regression Decistion Tree)GB(Gradient Boosting)Shrinkage(衰减)

1、DT(Regression Decistion Tree)——回归决策树

GBDT 中的决策树都是回归树,不是分类树:

  • 回归树:用于预测实数值,比如温度、年龄等;
  • 分类树:用于分类标签,比如:性别、晴天/阴天、是否等;

我们知道GBDT的思想使用了集成学习,也就是将每棵决策树(弱学习器)的结果累加,得到最终结果:

  • 如果我们将每棵回归树的预测结果相加,比如年龄:20岁+6岁+3岁+1岁=30岁 是有意的;
  • 但是如果我们将分类树的预测结果相加,比如性别:男+女 = ? 显然无意义。

因此 GBDT 中决策树只能回归树。

2、GB(Gradient Boosting)——梯度提升

\quad\quad 本篇一开始介绍了提升树利用加法模型与前向分步算法实现学习的优化过程。提升树使用平方误差损失和指数损失函数时,每一步优化都可以如上面的步骤简单实现。但是对于一般损失函数而言,往往每一步优化并不那么容易,针对这个问题,Freidman提出了梯度提升算法,这是利用最速下降法的近似方法,其关键是利用损失函数的负梯度在当前模型的值。

假设 F ( X ) F(X) F(X) 是一组最优基函数 f i ( X ) f_i(X) fi(X)的线性组合:
F ( X ) = ∑ i = 0 M f i ( X ) F(X) = \sum_{i=0}^Mf_i(X) F(X)=i=0Mfi(X)
损失函数为:
l o s s = L ( y , F ( X ) ) loss = L(y,F(X)) loss=L(y,F(X))
最优解为:
F ∗ ( X ) = a r g min ⁡ F L ( y , F ( X ) ) F^*(X) = arg \min_F L(y,F(X)) F(X)=argFminL(y,F(X))

(1)假设第m-1轮强学习器为:
F m − 1 ( X ) = ∑ i = 1 m − 1 f i ( X ) F_{m-1}(X) = \sum_{i=1}^{m-1}f_i(X) Fm1(X)=i=1m1fi(X)
损失函数为:
l o s s = L ( y , F m − 1 ( X ) ) loss = L\Big(y,F_{m-1}(X)\Big) loss=L(y,Fm1(X))
(2)第m轮强学习器为:
F m ( X ) = ∑ i = 1 m f i ( X ) = F m − 1 ( X ) + f m ( X ) F_{m}(X) = \sum_{i=1}^{m}f_i(X)=F_{m-1}(X) + f_m(X) Fm(X)=i=1mfi(X)=Fm1(X)+fm(X)

损失函数为:
l o s s = L ( y , ( F m − 1 ( X ) + f m ( X ) ) ) loss = L\Big(y, (F_{m-1}(X)+f_m(X))\Big) loss=L(y,(Fm1(X)+fm(X)))

(3)求解本轮的最优 F m ∗ ( X ) F_m^*(X) Fm(X)
F m ∗ ( X ) = F m − 1 ( X ) + L ( y , ( F m − 1 ( X ) + f m ( X ) ) ) F_m^*(X) = F_{m-1}(X) + L\Big(y, (F_{m-1}(X)+f_m(X))\Big) Fm(X)=Fm1(X)+L(y,(Fm1(X)+fm(X)))
= F m − 1 ( X ) + a r g min ⁡ f ∑ i = 1 n L ( y i , ( F m − 1 ( x i ) + f m ( x i ) ) ) = F_{m-1}(X) +arg \min_f\sum_{i=1}^nL\Big(y_i,\big(F_{m-1}(x_i) + f_m(x_i)\big)\Big) =Fm1(X)+argfmini=1nL(yi,(Fm1(xi)+fm(xi)))

其中, n n n 为样本数

以上在每次选择最优基函数 f m ( X ) f_m(X) fm(X)时比较困难,可以使用梯度下降的方法近似计算:

给定常数 f 0 ( X ) = F 0 ( X ) f_0(X) = F_0(X) f0(X)=F0(X)
f 0 ( X ) = F 0 ( X ) = a r g min ⁡ c ∑ i = 1 n L ( y i , c ) f_0(X) =F_0(X) = arg \min_c \sum_{i=1}^n L(y_i,c) f0(X)=F0(X)=argcmini=1nL(yi,c)
根据梯度下降计算学习率:
α i m = [ ∂ L ( y i , F ( x i ) ) ∂ F ( x i ) ] F ( x i ) = F m − 1 ( x i ) \alpha_{im} = \Big[\frac{\partial L(y_i,F(x_i))}{\partial F(x_i)}\Big]_{F(x_i) = F_{m-1}(x_i)} αim=[F(xi)L(yi,F(xi))]F(xi)=Fm1(xi)
使用数据 ( x i , α i m ) , i = 1 , 2 , . . . , n (x_i,\alpha_{im}),\quad i = 1,2,...,n (xi,αim),i=1,2,...,n计算拟合残差找到一个CART回归树,得到第m棵树:
c m j = a r g min ⁡ c ∑ x i ∈ l e a f j L ( y i , ( f m − 1 ( x i ) + c ) ) c_{mj} = arg \min_c \sum_{x_i \in leaf_j} L\Big(y_i, \big(f_{m-1}(x_i)+c\big)\Big) cmj=argcminxileafjL(yi,(fm1(xi)+c))
h m ( x ) = ∑ j = 1 ∣ l e a f ∣ m c m j I ( x ∈ l e a f m j ) h_m(x)=\sum_{j=1}^{|leaf|_m}c_{mj} I(x \in leaf_{mj}) hm(x)=j=1leafmcmjI(xleafmj)
更新模型:
F m ( X ) = F m − 1 ( X ) + ∑ j = 1 ∣ l e a f ∣ m c m j I ( x ∈ l e a f m j ) F_m(X) = F_{m-1}(X) + \sum_{j=1}^{|leaf|_m}c_{mj} I(x \in leaf_{mj}) Fm(X)=Fm1(X)+j=1leafmcmjI(xleafmj)
F ( X ) = f 0 ( X ) + ∑ m = 1 M ∑ j = 1 ∣ l e a f ∣ m c m j I ( x ∈ l e a f m j ) F(X) = f_0(X) + \sum_{m=1}^M\sum_{j=1}^{|leaf|_m}c_{mj} I(x \in leaf_{mj}) F(X)=f0(X)+m=1Mj=1leafmcmjI(xleafmj)

训练弱学习器: h t ( x ) h_t(x) ht(x)使:
f t − 1 ( x ) → f t ( x ) f_{t-1}(x) \rightarrow f_t(x) ft1(x)ft(x)
L ( y , f t − 1 ( x ) ) → L ( y , ( f t − 1 ( x ) + h t ( x ) ) ) L(y,f_{t-1}(x)) \rightarrow L\Big(y,\big(f_{t-1}(x)+h_t(x)\big)\Big) L(y,ft1(x))L(y,(ft1(x)+ht(x)))

3、Shrinkage(衰减)
  • 基本思想就是:

\quad\quad 每次走一小步逐渐逼近结果的效果,要比每次迈一大步很快逼近结果的方式更容易避免过拟合。换句话说缩减思想不完全信任每一个棵残差树,它认为每棵树只学到了真理的一小部分,累加的时候只累加一小部分,只有通过多学几棵树才能弥补不足。

Shrinkage仍然以残差作为学习目标,但由于它采用的是逐步逼近目标的方式,导致各个树的残差是渐变的而不是陡变的。之所以这样做也是基于模型过拟合的考虑。

四、GBDT 案例

sklearnensemble.GradientBoostingRegressor 类API:

sklearn.ensemble.GradientBoostingRegressor(loss=’ls’, learning_rate=0.1, 
	n_estimators=100, subsample=1.0, criterion=’friedman_mse’, min_samples_split=2, 
	min_samples_leaf=1, min_weight_fraction_leaf=0.0, max_depth=3, 
	min_impurity_decrease=0.0, min_impurity_split=None, init=None, random_state=None, 
	max_features=None, alpha=0.9, verbose=0, max_leaf_nodes=None, warm_start=False, 
	presort=’auto’, validation_fraction=0.1, n_iter_no_change=None, tol=0.0001)

常用参数说明:

参数描述
loss: {‘ls’,‘lad’,‘huber’,‘quantile’},可选(默认值=‘ls’)损失函数。'ls’指的是最小二乘回归;‘lad’(最小绝对偏差)是一种高度鲁棒的损失函数,仅基于输入变量的顺序信息;'huber’是两者的结合;'quantile’允许分位数回归(使用alpha来指定分位数)。
learning_rate : float,optional(默认值= 0.1)学习率通过learning_rate缩小每棵树的贡献。在learning_rate和n_estimators之间进行权衡。
n_estimators : int(默认值= 100)决策树数目,较大数目通常会产生更好的性能
max_depth : int,optional(默认= 3)每个决策树的深度
alpha : float(默认值= 0.9)huber损失函数和分位数损失函数的α分位数。只有当loss='huber’或loss=‘quantile’

其他参数,有些在之前都有遇到过,也可参考官方文档

1、GBDT 集成线性回归

本案例使用波士顿房屋租赁数据实现线性回归和GBDT预测,并对结果进行比较:

线性回归结果:
训练集上R^2:0.77301
测试集上R^2:0.58922
GBDT结果:
训练集上R^2:0.76730
测试集上R^2:0.64739

可以发现,在测试集上效果有所提升

代码可见:07_GBDT.py

五、XGBoost

1、简介

XGBoostGBDT 的升级版,前面介绍到,GBDT 是一种基于 Boosting 集成思想的学习器,并采用梯度提升的方法进行每一轮的迭代最终组合出强学习器,这样的话算法的运行往往要生成一定数量的树才能达到令我们满意的准确率。当数据集大且较为复杂时,运行一次极有可能需要几千次的迭代运算,这将对我们使用算法造成巨大的计算瓶颈。

针对这一问题,华盛顿大学的陈天奇博士开发出了 XGBoostXGBoost 最大的特点在于它能够自动利用CPU的多线程进行并行计算,同时在算法上加以改进,极大地提升了模型训练速度和预测精度。

2、目标函数

XGBoost 算法中,目标函数的形式为:
O b j ( θ ) = L ( θ ) + Ω ( Θ ) Obj(\theta) = L(\theta) +Ω(Θ) Obj(θ)=L(θ)+Ω(Θ)

其中, L ( θ ) L(\theta) L(θ)为损失函数,常用损失函数有:

  • 平方损失: L ( θ ) = ∑ i ( y i − y ^ i ) 2 L(\theta) = \sum_i(y_i - \hat{y}_i)^2 L(θ)=i(yiy^i)2
  • Logistic损失: L ( θ ) = ∑ i [ y i l n ( 1 + e − y i ^ ) + ( 1 − y i ) l n ( 1 + e y ^ i ) ] L(\theta) = \sum_i [y_iln(1+e^{-\hat{y_i}}) + (1-y_i)ln(1 + e^{\hat{y}_i})] L(θ)=i[yiln(1+eyi^)+(1yi)ln(1+ey^i)]

Ω ( Θ ) Ω(Θ) Ω(Θ):正则化项

  • 引入正则化项是因为我们的目标是希望生成的模型的泛化性能比较好,能够很好的预测新数据,而不是简单的拟合训练集的结果(这样会导致过拟合);
  • 需要在保证模型“简单”的基础上最小化训练误差,这样得到的参数才具有好的泛化性能;
  • 正则项就是用于惩罚复杂模型,避免预测模型过分拟合训练数据,常用的正则有 L 1 L_1 L1 正则与 L 2 L_2 L2 正则。

已知目标函数:
O b j ( θ ) = L ( θ ) + Ω ( Θ ) Obj(\theta) = L(\theta) +Ω(Θ) Obj(θ)=L(θ)+Ω(Θ)

  • 如果目标函数中的损失函数权重过高,那么模型的预测精度则不尽人意;
  • 反之如果正则项的权重过高,所生成的模型则会出现过拟合情况,难以对新的数据集做出有效预测;
  • 只有平衡好两者之间的关系,控制好模型复杂度,并在此基础上对参数进行求解,生成的模型才会“简单有效”。
3、XGBoost 推导过程

假设某次迭代后集成的模型表示为:
y i ^ = ∑ k = 1 K f k ( X ) , f k ∈ F \hat{y_i} = \sum_{k=1}^Kf_k(X),f_k \in F yi^=k=1Kfk(X)fkF
其中, y i ^ \hat{y_i} yi^也就是前文的 f m ( X ) f_m(X) fm(X)
相对应的目标函数:
O b j = ∑ i n L ( y i , y i ^ ) + ∑ k = 1 K Ω ( f k ) Obj = \sum_i^nL(y_i,\hat{y_i}) + \sum_{k=1}^KΩ(f_k) Obj=inL(yi,yi^)+k=1KΩ(fk)

接下来,我们按之前介绍GBDT的方式来介绍

这里先给出一些数据,以便接下来使用;假设有如下数据,判断谁愿意去玩游戏:

编号是否玩电脑性别年龄
A12
B14
C25
D26
E27

在这里插入图片描述

图中权重表示该人愿意去玩游戏的得分,得分越大越愿意;得分为负,表示不愿意
最终A的得分为2.9,B的得分为-0.8,C的得分为-0.1,D的得分为-1.9,E的得分为-1.9;

  1. 目标函数构建

(1)第 t − 1 t-1 t1 轮的模型可表示为:
y i ^ ( t − 1 ) = ∑ k = 1 t − 1 f k ( X ) \hat{y_i}^{(t-1)} = \sum_{k=1}^{t-1} f_k(X) yi^(t1)=k=1t1fk(X)
损失函数为:
O b j ( t − 1 ) = ∑ i n L ( y i , y i ^ ( t − 1 ) ) + ∑ k = 1 t − 1 Ω ( f k ) Obj^{(t-1)}= \sum_i^nL(y_i,\hat{y_i}^{(t-1)}) + \sum_{k=1}^{t-1}Ω(f_k) Obj(t1)=inL(yi,yi^(t1))+k=1t1Ω(fk)
(2)第 t t t 轮的模型可表示为:
y i ^ ( t ) = ∑ k = 1 t f k ( X ) = y i ^ ( t − 1 ) + f t ( X ) \hat{y_i}^{(t)} = \sum_{k=1}^{t} f_k(X)=\hat{y_i}^{(t-1)} + f_t(X) yi^(t)=k=1tfk(X)=yi^(t1)+ft(X)
目标函数为:
O b j ( t ) = ∑ i n L ( y i , ( y i ^ ( t − 1 ) + f t ( X ) ) ) + ∑ k = 1 t Ω ( f t ) Obj^{(t)} = \sum_i^nL\Big(y_i,\big(\hat{y_i}^{(t-1)} + f_t(X)\big)\Big) + \sum_{k=1}^{t}Ω(f_t) Obj(t)=inL(yi,(yi^(t1)+ft(X)))+k=1tΩ(ft)
= ∑ i n L ( y i , ( y i ^ ( t − 1 ) + f t ( X ) ) ) + Ω ( f t ) + c o n s t a n t = \sum_i^nL\Big(y_i,\big(\hat{y_i}^{(t-1)} + f_t(X)\big)\Big) +Ω(f_t) + constant =inL(yi,(yi^(t1)+ft(X)))+Ω(ft)+constant

(3)考虑使用平方误差作为损失函数,目标函数可写为:
O b j ( t ) = ∑ i n ( y i − ( y i ^ ( t − 1 ) + f t ( x i ) ) ) 2 + Ω ( f t ) + c o n s t a n t Obj^{(t)} = \sum_i^n\Big(y_i - \big(\hat{y_i}^{(t-1)} + f_t(x_i)\big)\Big)^2 +Ω(f_t) + constant Obj(t)=in(yi(yi^(t1)+ft(xi)))2+Ω(ft)+constant
= ∑ i n [ 2 y i ( y i ^ ( t − 1 ) + f t ( x i ) ) + f t 2 ( x i ) ] + Ω ( f t ) + c o n s t a n t = \sum_i^n\Big[2y_i \big(\hat{y_i}^{(t-1)}+ f_t(x_i)\big) + f_t^2(x_i)\Big] +Ω(f_t) + constant =in[2yi(yi^(t1)+ft(xi))+ft2(xi)]+Ω(ft)+constant

如果使用其他损失函数,可以采用泰勒展开近似来定义一个近似的目标函数,方便我们进行进一步的计算
泰勒展开: f ( x + Δ x ) ≈ f ( x ) + f ′ ( x ) Δ x + 1 2 f ′ ′ ( x ) Δ 2 x f(x+\Delta x) \approx f(x) + f&#x27;(x)\Delta x + \frac{1}{2}f&#x27;&#x27;(x)\Delta^2x f(x+Δx)f(x)+f(x)Δx+21f(x)Δ2x

(4)按泰勒展开目标函数又可写为:
O b j ( t ) = ∑ i = 1 n [ L ( y i , y i ^ ( t − 1 ) ) + g i f t ( x i ) + 1 2 h i f t 2 ( x i ) ] + Ω ( f t ) + c o n s t a n t Obj^{(t)} =\sum_{i=1}^n\Big[L(y_i,\hat{y_i}^{(t-1) }) + g_if_t(x_i) + \frac{1}{2}h_if^2_t(x_i)\Big]+Ω(f_t) + constant Obj(t)=i=1n[L(yi,yi^(t1))+gift(xi)+21hift2(xi)]+Ω(ft)+constant

其中,
g i = ∂ L ( y i , y i ^ ( t − 1 ) ) ∂ y i ^ ( t − 1 ) g_i = \frac{\partial L(y_i,\hat{y_i}^{(t-1) })}{\partial \hat{y_i}^{(t-1)}} gi=yi^(t1)L(yi,yi^(t1))
h i = ∂ 2 L ( y i , y i ^ ( t − 1 ) ) ∂ y i ^ ( t − 1 ) h_i = \frac{\partial^2 L(y_i,\hat{y_i}^{(t-1) })}{\partial \hat{y_i}^{(t-1)}} hi=yi^(t1)2L(yi,yi^(t1))

(5)移除常数项目标函数写为:

O b j ( t ) = ∑ i = 1 n [ g i f t ( x i ) + 1 2 h i f t 2 ( x i ) ] + Ω ( f t ) Obj^{(t)} = \sum_{i=1}^n\Big[ g_if_t(x_i) + \frac{1}{2}h_if^2_t(x_i)\Big]+Ω(f_t) Obj(t)=i=1n[gift(xi)+21hift2(xi)]+Ω(ft)

  1. 定义 Ω ( f ) Ω(f) Ω(f)

Ω ( f ) = γ T + 1 2 λ ∑ j = 1 T w j 2 Ω(f) = \gamma T + \frac{1}{2}\lambda\sum_{j=1}^Tw_j^2 Ω(f)=γT+21λj=1Twj2

上式包含了一棵树里面节点的个数(左侧),以及每个树叶子节点上面输出分数的 L 2 L_2 L2 模平方(右侧)

  • T T T :叶子的个数
  • w w w:叶子节点的权重
  • γ \gamma γ 作为叶子节点的系数,使 XGBoost 在优化目标函数的同时相当于做了预剪枝;
  • λ \lambda λ 作为 L 2 L_2 L2 平方模的系数也是要起到防止过拟合的作用

具体计算如下图:

在这里插入图片描述

其中, γ , λ \gamma,\lambda γλ由人为给定

  1. 目标函数最小化

O b j ( t ) ≈ ∑ i = 1 n [ g i f t ( x i ) + 1 2 h i f t 2 ( x i ) ] + γ T + 1 2 λ ∑ j = 1 T w j 2 Obj^{(t)} \approx \sum_{i=1}^n\Big[ g_if_t(x_i) + \frac{1}{2}h_if^2_t(x_i)\Big] +\gamma T + \frac{1}{2}\lambda\sum_{j=1}^Tw_j^2 Obj(t)i=1n[gift(xi)+21hift2(xi)]+γT+21λj=1Twj2
f t ( x i ) = w q ( x ) f_t(x_i) = w_{q(x)} ft(xi)=wq(x)

  • 树的结构函数 q q q表示把输入x映射到对应叶子节点上
  • w w w 给定了每个叶子节点对应的分数,即权重

因此,目标函数可以写为:
O b j ( t ) ≈ ∑ i = 1 n [ g i w q ( x i ) + 1 2 h i w q ( x i ) 2 ] + γ T + 1 2 λ ∑ j = 1 T w j 2 Obj^{(t)} \approx \sum_{i=1}^n\Big[ g_iw_{q(x_i)}+ \frac{1}{2}h_iw^2_{q(x_i)}\Big] +\gamma T + \frac{1}{2}\lambda\sum_{j=1}^Tw_j^2 Obj(t)i=1n[giwq(xi)+21hiwq(xi)2]+γT+21λj=1Twj2
= ∑ j = 1 T [ ( ∑ i ∈ I j g i ) w j + 1 2 ( ∑ i ∈ I j h i + λ ) w j 2 ] + γ T =\sum_{j=1}^T\Big[(\sum_{i \in I_j}g_i)w_j + \frac{1}{2}(\sum_{i \in I_j}h_i + \lambda)w_j^2\Big]+\gamma T =j=1T[(iIjgi)wj+21(iIjhi+λ)wj2]+γT

记: G j = ∑ i ∈ I j g i , H i = ∑ i ∈ I j h i G_j=\sum_{i \in I_j}g_i,H_i = \sum_{i \in I_j}h_i Gj=iIjgiHi=iIjhi

上式化简为:
O b j ( t ) = ∑ j = 1 T [ G j w j + 1 2 ( H j + λ ) w j 2 ] + γ T Obj^{(t)}=\sum_{j=1}^T\Big[G_jw_j + \frac{1}{2}(H_j + \lambda)w_j^2\Big]+\gamma T Obj(t)=j=1T[Gjwj+21(Hj+λ)wj2]+γT

将上式看作一个一元二次方程求最小值问题(变量为 w j w_j wj),处于对称轴处:
f ( x ) = a x 2 + b x + c , a &gt; 0 f(x) = ax^2+bx+c ,a&gt;0 f(x)=ax2+bx+ca>0;最小值为: f ( − b 2 a ) f(-\frac{b}{2a}) f(2ab)

故:
w j ∗ = − G j H j + λ w_j^* = -\frac{G_j}{H_j + \lambda} wj=Hj+λGj
O b j ∗ = − 1 2 ∑ j = 1 T G j 2 H j + λ + γ T Obj^* = -\frac{1}{2}\sum_{j=1}^T\frac{G_j^2}{H_j + \lambda} + \gamma T Obj=21j=1THj+λGj2+γT

在这里插入图片描述

  • 如果树的结构函数 q q q确定了,那么相应的目标函数就能够根据上式计算出来。那么树的生成问题也就转换为找到一个最优的树结构 q q q,使得它具有最小的目标函数;
  • 计算求得的 O b j Obj Obj 代表了当指定一个树的结构的时候,目标函数上面最多减少多少。所有我们可以把它叫做结构分数
  1. 枚举树的结构

\quad\quad 当寻找到最优的树结构时,我们可以不断地枚举不同树的结构,利用这个打分函数来寻找出一个最优结构的树,加入到我们的模型中,然后再重复这样的操作;不过枚举所有树结构这个操作不太可行,在这里 XGBoost 采用了常用的贪心法,即每一次尝试去对已有的叶子加入一个分割。对于一个具体的分割方案,我们可以获得的增益可以由如下公式计算得到:
G a i n = 1 2 [ G L 2 H L + λ + G R 2 H R + λ − ( G L + G R ) 2 H L + H R + λ ] − γ Gain = \frac{1}{2}\Big[\frac{G_L^2}{H_L+\lambda}+\frac{G_R^2}{H_R+\lambda}-\frac{(G_L+G_R)^2}{H_L+H_R+\lambda}\Big] - \gamma Gain=21[HL+λGL2+HR+λGR2HL+HR+λ(GL+GR)2]γ

其中:
G L 2 H L + λ , G R 2 H R + λ , ( G L + G R ) 2 H L + H R + λ \frac{G_L^2}{H_L+\lambda},\frac{G_R^2}{H_R+\lambda},\frac{(G_L+G_R)^2}{H_L+H_R+\lambda} HL+λGL2HR+λGR2HL+HR+λ(GL+GR)2
分别代表左子树、右子树和不分割时可以获得的分数, γ \gamma γ代表加入新叶子节点引入的代价

遍历所有分割,选择变化最大的作为最合适的分割;类似决策树中信息增益的作用;

六、XGBoost 案例

需要先安装依赖:pip install xgboost

官方文档:XGBoost
官方: Github

实现步骤如下:

  • 加载数据
  • 数据处理
  • 划分数据(X,Y)
  • 数据分割(训练集和测试集)
  • 数据转换(XGBoost将数据转换为XGBoost可用的数据类型)
  • XGBoost模型构建(参数构建、模型训练、模型保存)
  • XGBoost模型预测
  • 加载模型、预测
  • 画图、找出最重要的特征
    在这里插入图片描述

在这里插入图片描述

代码可见:08_使用XGBoost算法实现波士顿房价预测.py

八、集成学习Stacking思想

\quad\quad 集成学习除了BaggingBoosting思想,还有Stacking,此处只提一下,不做具体介绍,因为现在基本不使用了。

\quad\quad Stacking是指训练一个模型用于组合(combine)其它模型(基模型/基学习器)的技术。即首先训练出多个不同的模型,然后再以之前训练的各个模型的输出作为输入来新训练一个新的模型,从而得到一个最终的模型。一般情况下使用单层的Logistic回归作为组合模型。

Stacking 跟现在比较火的深度学习很相似,所以现在一般不使用Stacking

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值