集成学习-10-前向分步算法与梯度提升决策树
前言
回看Adaboost的算法内容,我们需要通过计算M个基本分类器,每个分类器的错误率、样本权重以及模型权重。我们可以认为:Adaboost每次学习单一分类器以及单一分类器的参数(权重)。接下来,我们抽象出Adaboost算法的整体框架逻辑,构建集成学习的一个非常重要的框架----前向分步算法,有了这个框架,我们不仅可以解决分类问题,也可以解决回归问题。
1. 加法模型
具体到在Adaboost模型中,我们把每个基本分类器合成一个复杂分类器的方法是每个基本分类器的加权和
其中,
b
(
x
;
γ
m
)
b(x;γ_m)
b(x;γm)为即基本分类器,
γ
m
γ_m
γm 为基本分类器的参数,
β
m
β_m
βm为基本分类器的权重。在给定训练数据以及损失函数
L
(
y
,
f
(
x
)
)
L(y,f(x))
L(y,f(x))的条件下,学习加法模型就是
f
(
x
)
f(x)
f(x)成为经验风险极小化(即损失函数极小化)问题:
即同时考虑N个样本在整个线性模型组中的损失函数的极小值,通常这是一个十分复杂的优化问题(求极值问题),想要一步到位求出最优解特别困难。前向分步算法(forward stagewise algorithm)求解这一优化问题的思想是:因为学习的是加法模型(线性模型),如果能够从前向后,每一步只学习一个基函数及其系数,逐步逼近目标函数,那么就可以降低优化的复杂度。具体而言,每一步只需要优化:
有一点要注意,前向分步的思想和贝叶斯估计有类似的地方 :它们都假设每一步之间的基函数和系数是独立不相关的(在贝叶斯估计中这叫独立同分布),也因为这一假设才可以把原始的全局最优解求解等价为分步的子项求解过程。但是这种假设会丢失一部分精确度,即每一步之间的依赖关联会被丢弃
2. 前向分步算法
给定数据集
T
=
(
x
1
,
y
1
)
,
(
x
2
,
y
2
)
,
⋯
,
(
x
N
,
y
N
)
T={(x1,y1),(x2,y2),⋯,(xN,yN)}
T=(x1,y1),(x2,y2),⋯,(xN,yN) ,
x
i
∈
X
⊆
R
n
xi∈X⊆R^n
xi∈X⊆Rn,$yi∈Y={+1,−1} $。损失函数
L
(
y
,
f
(
x
)
)
L(y,f(x))
L(y,f(x)),基函数集合
b
(
x
;
γ
)
{b(x;γ)}
b(x;γ) ,我们需要输出加法模型
f
(
x
)
f(x)
f(x) 。
这样,前向分步算法将同时求解从m=1到M所有参数的
β
m
,
γ
m
β_m, γ_m
βm,γm全局最优解问题,简化为逐次求解各个
β
m
,
γ
m
β_m, γ_m
βm,γm的局部最优化问题。
3. 梯度提升决策树(GBDT)
先问3个问题后面会给解答
1.决策树体现在哪里呢?
2.梯度体现在哪里呢?
3.提升什么呢?
按照我的理解来说梯度提升决策树是使用加法模型+前向分步算法的框架实现回归问题。GBDT模型定义如下:
其中我们约定
f
t
(
x
)
f_t(x)
ft(x)表示第t轮的模型,
h
t
h_t
ht(x)表示第t颗决策树,模型提升树采用前向分步算法,将其更改成前向分布算法的形式可以写成第t步的模型由第t-1步的模型获得
损失函数如下:
虽然整体思路都挺清晰的,但是怎么确定第t步该加上一颗什么样的树确是个大问题。这个回归树的构建需要通过获得每轮的残差,而残差这个问题, Freidman提出了用损失函数的负梯度来拟合本轮损失的近似值。 即每次需要拟合的是模型的负梯度。第t轮的第i个样本的损失函数的负梯度表示为:
利用
(
x
i
,
r
t
i
)
(
i
=
1
,
2
,
.
.
.
m
)
(x_i, r_ti) (i=1,2,...m)
(xi,rti)(i=1,2,...m),我们可以拟合一颗CART回归树,得到了第t颗回归树,其对应的叶节点区域Rtj, j=1,2,…,J。其中J为叶子节点的个数。
针对每一个叶子节点里的样本,我们求出使损失函数最小,也就是拟合叶子节点最好的的输出值ctj如下(注意这里的yi是真实值,不是残差):
在这里叶子样本节点的构建也采用了前向分布算法,求出每个叶子节点。
此时本轮的决策树拟合函数就得到了:
回归树生成具体参考这篇文章 https://zhuanlan.zhihu.com/p/45145899.
然后本轮的强学习器也就得到了:
1.决策树体现在哪里呢?决策树是用来干什么的?
首先回答第一个问题:需要首先确定框架内使用的基函数是什么,在这里我们使用决策树分类器。决策树用拟合的是模型的负梯度。
2。梯度体现在哪里呢?
基函数确定了以后,我们需要确定每次提升的标准是什么。模仿在Adaboost算法分类错误率,我们用每个样本的残差表示每次使用基函数预测时没有解决的那部分问题。而残差这个问题, Freidman提出了用**损失函数的负梯度来拟合本轮损失的近似值。**即每次需要拟合的是模型的负梯度。
3.提升什么呢?
个人认为每棵树都在拟合前面一棵树的残差,最终提升的是每轮数据的残差,使得残差逐渐减小。在残差缩减的过程会采取Shrinkage(缩减)。该思想认为,每次走一小步逐渐逼近结果的效果,要比每次迈一大步很快逼近结果的方式更容易避免过拟合。即它不完全信任每一个棵残差树,它认为每棵树只学到了真理的一小部分,累加的时候只累加一小部分,通过多学几棵树弥补不足。Shrinkage仍然以残差作为学习目标,但对于残差学习出来的结果,只累加一小部分(step*残差)逐步逼近目标,step一般都比较小,如0.01~0.001(注意该step非gradient的step),导致各个树的残差是渐变的而不是陡变的。直觉上这也很好理解,不像直接用残差一步修复误差,而是只修复一点点,其实就是把大步切成了很多小步。本质上,Shrinkage为每棵树设置了一个weight,累加时要乘以这个weight,但和Gradient并没有关系。这个weight就是step。
详细的过程
输入是训练集样本D={(x_{1},y_{1}),(x_{2},y_{2}),…,(x_{n},y_{n})}, 最大迭代次数T, 损失函数L。输出是强学习器f(x)
1 初始化弱学习器(这里初始化一个c的值,通常为所有样本点的平均值)
2对迭代轮数 t=1,2,…,T 有:
a)对样本 i=1,2,…,n,计算负梯度
b)利用(x_{i},r_{ti}) (i=1,2,…,n),拟合一颗CART回归树,得到第 t 颗回归树,其对应的叶子节点区域为R_{tj}, j=1,2,…,J。其中J为回归树 t 的叶子节点的个数。
c) 对叶子区域j =1,2,3,…,J,计算最佳拟合值
d) 更新强学习器
3 得到强学习器f(x)的表达式
参考链接:
[1] https://zhuanlan.zhihu.com/p/45145899.
[2] https://blog.csdn.net/suranxu007/article/details/49910323.
[3] https://blog.csdn.net/zpalyq110/article/details/79527653.
[4] https://github.com/datawhalechina/team-learning-data-mining/tree/master/EnsembleLearning..