梯度提升树GBDT
一、Boosting 算法
Boosting 是一族可将弱学习器提升为强学习器的算法.这族算法的工作机制类似:先从初始训练集训练出一个基学习器,再根据基学习器的表现对训练样本分布进行调整,使得先前基学习器做错的训练样本在后续受到更多关注,然后基于调整后的样本分布来训练下一个基学习器;如此重复进行,直至基学习器数目达到事先指定的值 T , 最终将这 T 个基学习器进行加权结合.
二、前向分步算法
引入加法模型:
f
(
x
)
=
∑
m
=
1
M
β
m
b
(
x
;
γ
m
)
f(x)=\sum_{m=1}^{M} \beta_{m} b\left(x ; \gamma_{m}\right)
f(x)=m=1∑Mβmb(x;γm)
在给定了训练数据和损失函数
L
(
y
,
f
(
x
)
)
L(y,f(x))
L(y,f(x)) 的条件下,可以通过损失函数最小化来学习加法模型:
min
β
n
,
γ
n
∑
i
=
1
N
L
(
y
i
,
∑
m
=
1
M
β
m
b
(
x
i
;
γ
m
)
)
\min _{\beta_{n}, \gamma_{n}} \sum_{i=1}^{N} L\left(y_{i}, \sum_{m=1}^{M} \beta_{m} b\left(x_{i} ; \gamma_{m}\right)\right)
βn,γnmini=1∑NL(yi,m=1∑Mβmb(xi;γm))
然而对于这个问题是个很复杂的优化问题,而且要训练的参数非常的多,前向分布算法的提出就是为了解决模型的优化问题,其核心思想是因为加法模型是由多各模型相加在一起的,而且在Boosting中模型之间又是有先后顺序的,因此可以在执行每一步加法的时候对模型进行优化,那么每一步只需要学习一个模型和一个参数,通过这种方式来逐步逼近全局最优,每一步优化的损失函数:
min
β
,
γ
∑
i
=
1
N
L
(
y
i
,
β
b
(
x
i
;
γ
)
)
\min _{\beta, \gamma} \sum_{i=1}^{N} L\left(y_{i}, \beta b\left(x_{i} ; \gamma\right)\right)
β,γmini=1∑NL(yi,βb(xi;γ))
具体做法如下:
1、初始化
f
0
(
x
)
=
0
f_0(x)=0
f0(x)=0
2、第m次迭代时,极小化损失函数:
(
β
m
,
γ
m
)
=
arg
min
β
,
y
∑
i
=
1
N
L
(
y
i
,
f
m
−
1
(
x
i
)
+
β
b
(
x
i
;
γ
)
)
\left(\beta_{m}, \gamma_{m}\right)=\arg \min _{\beta, y} \sum_{i=1}^{N} L\left(y_{i}, f_{m-1}\left(x_{i}\right)+\beta b\left(x_{i} ; \gamma\right)\right)
(βm,γm)=argβ,ymini=1∑NL(yi,fm−1(xi)+βb(xi;γ))
3、更新模型,则
f
m
(
x
)
f_m(x)
fm(x):
f
m
(
x
)
=
f
m
−
1
(
x
)
+
β
m
b
(
x
;
γ
m
)
f_m(x)=f_{m-1}(x)+{\beta}_mb(x;{\gamma}_m)
fm(x)=fm−1(x)+βmb(x;γm)
4、得到最终的加法模型
f
(
x
)
=
∑
m
=
1
M
β
m
b
(
x
;
γ
m
)
f(x)=\sum_{m=1}^{M} \beta_{m} b\left(x ; \gamma_{m}\right)
f(x)=m=1∑Mβmb(x;γm)
Adaboost算法也可以用前向分布算法来描述,在这里输入的数据集是带有权重分布的数据集,损失函数是指数损失函数。
三、GBDT算法
GBDT是梯度提升决策树(Gradient Boosting Decision Tree)的简称,GBDT可以说是最好的机器学习算法之一。GBDT分类和回归时的基学习器都是CART回归树,因为是拟合残差的。GBDT和Adaboost一样可以用前向分布算法来描述,不同之处在于Adaboost算法每次拟合基学习器时,输入的样本数据是不一样的(每一轮迭代时的样本权重不一致),因为Adaboost旨在重点关注上一轮分类错误的样本,GBDT算法在每一步迭代时是输出的值不一样,本轮要拟合的输出值是之前的加法模型的预测值和真实值的差值(模型的残差,也称为损失)。用于一个简单的例子来说明GBDT,假如某人的年龄为30岁,第一次用20岁去拟合,发现损失还有10岁,第二次用6岁去拟合10岁,发现损失还有4岁,第三次用3岁去拟合4岁,依次下去直到损失在我们可接受范围内。
假设训练集中有4个人,ABCD,年龄分别为14、16、24、26,通过购物金额、上网时长、经常到百度知道提问或回答等属性,来预测其年龄。利用传统回归树来训练,得到下图结果:
我们利用GBDT来做这件事,由于数据较少,我们限定叶子结点最多有两个,即每棵树都只有一个分支,限定只学两棵树,可得下图结果:
在左侧树中,AB样本被预测为15岁,实际分别为14、16岁,因而可得残差-1、+1,同理,CD残差为-1、+1岁。有了这个残差,我们将其代替ABCD的年龄,在第二棵树中进行训练,也就是利用x(样本)和y_residual(y的残差)进行训练,得到右侧树。因此,来一个新样本,比如说把训练数据中的A拿过来,14岁,在左侧训练完为15岁,在右侧训练完为-1岁,将其累加,可得预测值14岁。基本思路大概如此。
上述为一个简单的提升树(Boosting Tree)的思路,不断基于模型的残差学习新的回归树,最后将所有回归树累加,得到提升树的模型。
以平方误差损失函数的回归问题为例,来看看以损失来拟合是个什么样子,采用前向分布算法:
在第m次迭代时,我们要优化的损失函数:
此时我们采用平方误差损失函数为例:
问题就成了对残差r的拟合了
然而对于大多数损失函数,却没那么容易直接获得模型的残差,针对该问题,大神Freidman提出了用损失函数的负梯度来拟合本轮损失的近似值,拟合一个回归树
GBDT算法提供了众多的可选择的损失函数,通过选择不同的损失函数可以用来处理分类、回归问题,比如用对数似然损失函数就可以处理分类问题。大概的总结下常用的损失函数:
1)对于分类问题可以选用指数损失函数、对数损失函数。
2)对于回归问题可以选用均方差损失函数、绝对损失函数。
3)另外还有huber损失函数和分位数损失函数,也是用于回归问题,可以增加回归问题的健壮性,可以减少异常点对损失函数的影响。
GBDT的正则化
在Adaboost中我们会对每个模型乘上一个弱化系数(正则化系数),减小每个模型对提升的贡献(注意:这个系数和模型的权重不一样,是在权重上又乘以一个0,1之间的小数),在GBDT中我们采用同样的策略,**对于每个模型乘以一个系数λ (0 < λ ≤ 1),降低每个模型对拟合损失的贡献,**这种方法也意味着我们需要更多的基学习器。
第二种是每次通过按比例(推荐[0.5, 0.8] 之间)随机抽取部分样本来训练模型,这种方法有点类似Bagging,可以减小方差,但同样会增加模型的偏差,可采用交叉验证选取,这种方式称为子采样。采用子采样的GBDT有时也称为随机梯度提升树(SGBT)。
第三种就是控制基学习器CART树的复杂度,可以采用剪枝正则化。
GBDT的优缺点
GBDT的主要优点:
1)可以灵活的处理各种类型的数据
2)预测的准确率高
3)使用了一些健壮的损失函数,如huber,可以很好的处理异常值
GBDT的缺点:
1)由于基学习器之间的依赖关系,难以并行化处理,不过可以通过子采样的SGBT来实现部分并行。