分享

GBDT(Gradient Boosting Decision Tree)基本原理

 脑系科数据科学 2019-03-20

GBDT相对于经典的决策树,算是一种比较成熟而且可以实际应用的决策树算法了。我们想要理解GBDT这种决策树,得先从感性上理解这棵树的工作方式。
首先我们要了解到,DBDT是一种回归树(Regression Decision tree)。回归树与分类树的差距请看我的文章《经典的回归树算法》
我们知道,分类树在每一次分支的时候,穷举每一个特征的每一个阈值,然后按照大于或者小于阈值的方式将其相互分开。这就是分类树的算法。
回归树也十分类似,但是在每个节点都会得到一个预测值。

以年龄为例,该预测值等于属于这个节点的所有人年龄的平均值。分枝时穷举每一个feature的每个阈值找最好的分割点,但衡量最好的标准不再是最大熵,而是最小化均方差--即(每个人的年龄-预测年龄)^2 的总和 / N,或者说是每个人的预测误差平方和 除以 N。这很好理解,被预测出错的人数越多,错的越离谱,均方差就越大,通过最小化均方差能够找到最靠谱的分枝依据。分枝直到每个叶子节点上人的年龄都唯一(这太难了)或者达到预设的终止条件(如叶子个数上限),若最终叶子节点上人的年龄不唯一,则以该节点上所有人的平均年龄做为该叶子节点的预测年龄。

BDT(Boosting Decision Tree 提升决策树)

这其实是一个很好的思维方式。
Boosting,提升。这涉及到机器学习中的集成学习。原理就是通过多个特征生成多个树,来决策一件事情。也就是“三个臭皮匠,顶一个诸葛亮”的原理。这是如何实现的呢?我们举一个简单的例子。BDT的核心就在于,每一棵树学的是之前所有树结论和的残差,这个残差就是一个加预测值后能得真实值的累加量。比如A的真实年龄是18岁,我们训练的时候,第一棵树的拟合过后预测年龄是12岁,我们与真实数据比对差了6岁,即残差为6岁。那么在第二棵树里我们把A的年龄设为6岁去拟合学习,如果第二棵树真的能把A分到6岁的叶子节点,那累加两棵树的结论就是A的真实年龄;如果第二棵树的结论是5岁,则A仍然存在1岁的残差,第三棵树里A的年龄就变成1岁,继续学。
如果还有疑问,请看下面这个例子:
还是年龄预测,简单起见训练集只有4个人,A,B,C,D,他们的年龄分别是14,16,24,26。其中A、B分别是高一和高三学生;C,D分别是应届毕业生和工作两年的员工。如果是用一棵传统的回归决策树来训练,会得到如下图1所示结果:

传统回归树模型(图片来自网络)传统回归树模型(图片来自网络)

这是一棵普通的回归树,我们可以看到,我们通过年龄平均值将少年和青年分开
,再用上网时长将每个分支继续细分到不能分割或者达到要求为止。
接下来看BDT实现:

BDT模型(图片来自网络)BDT模型(图片来自网络)

在第一棵树分枝和图1一样,由于A,B年龄较为相近,C,D年龄较为相近,他们被分为两拨,每拨用平均年龄作为预测值。此时计算残差(残差的意思就是: A的预测值 + A的残差 = A的实际值),所以A的残差就是16-15=1(注意,A的预测值是指前面所有树累加的和,这里前面只有一棵树所以直接是15,如果还有树则需要都累加起来作为A的预测值)。进而得到A,B,C,D的残差分别为-1,1,-1,1。然后我们拿残差替代A,B,C,D的原值,到第二棵树去学习,如果我们的预测值和它们的残差相等,则只需把第二棵树的结论累加到第一棵树上就能得到真实年龄了。这里的数据显然是我可以做的,第二棵树只有两个值1和-1,直接分成两个节点。此时所有人的残差都是0,即每个人都得到了真实的预测值。

换句话说,现在A,B,C,D的预测值都和真实年龄一致了:

  1. 14岁高一学生,购物较少,经常问学长问题;预测年龄A = 15 – 1 = 14

  2. 16岁高三学生;购物较少,经常被学弟问问题;预测年龄B = 15 + 1 = 16

  3. 24岁应届毕业生;购物较多,经常问师兄问题;预测年龄C = 25 – 1 = 24

  4. 26岁工作两年员工;购物较多,经常被师弟问问题;预测年龄D = 25 + 1 = 26

GBDT核心思想就是这样,但是既然普通的树和GBDT结果一样,那为什么还需要GBDT呢?
原因就是过拟合。过拟合就是模型在训练数据集上表现的过于好,分的过于细。以致于容错能力很低,也可以称作”泛化能力“低。这就会导致在实际测试数据中表现明显差很多。我们发现图1为了达到100%精度使用了3个feature(上网时长、时段、网购金额),其中分枝“上网时长>1.1h” 很显然已经过拟合了,这个数据集上A,B也许恰好A每天上网1.09h, B上网1.05小时,但用上网时间是不是>1.1小时来判断所有人的年龄很显然是有悖常识的;
相对来说图2的boosting虽然用了两棵树 ,但其实只用了2个feature就搞定了,后一个feature是问答比例,显然图2的依据更靠谱(这是杜撰的数据,为了显示效果夸张的一下,实际有实验证明以上论点)。

GB(Gradient Boosting 梯度提升)

我们前面一直都在讨论GBDT的基本原理,是从宏观上对于这种算法有个感性的认识。但是我们要想进一步理解GBDT,就得知道负梯度拟合,或者我们也叫梯度提升。
我们都知道,在机器学习算法中,为了降低误差函数,我们会有一个方法叫做梯度下降法。其做法是误差函数中,每一步都走当前的梯度方向,也就是下降最快的方向进行下降,这样多次迭代步长之后,误差函数就会降到一个局部最低点(凸函数中也是全局最低点),也就得到了最小的误差函数。
我们尝试使用这种方法去训练一棵回归树,或者更精确的说,是一棵CART,如有朋友不太熟悉CART,请看我之前的文章《CART》。正如前面所提到,我们GBDT每次训练的时候都是拟合上一棵树的残差,那么我们使用损失函数来拟合这棵树:

损失函数拟合一棵决策树损失函数拟合一棵决策树

使用损失函数的负梯度来拟合它的残差:

这样将所有的负梯度加起来之后就会得到一个整体的梯度下降。使得整个系统的误差函数最小。
我贴出梯度提升算法以辅助理解,内容来自李航的《统计学习方法》:

梯度提升算法过程梯度提升算法过程

我们来看看这梯度提升算法的流程:

  1. 我们先初始化第一棵回归树,使这个分界点让整体误差最小。具体细节上为什么初始化成这种形式,请看我之前写过的文章《CART》;

  2. 我们每生成一棵树之后,就将这棵树的每一条数据的损失函数的梯度求出来;损失函数我们一般写作是均方误差,每个数据与切分点之间的均方差就是损失函数;

  3. 求出每个数据的负梯度之后,我们依据已有数据和每个数据的负梯度,生成一个新树出来,我们先将每个数据的负梯度当作新的数据的yi,这样就得到了一组新数据,也确定了新数据的空间划分。然后再计算每一条数据的误差函数,取误差函数最小的那个点做为下一个分支切分点,这也就生成了一颗新树;

  4. 我们将新树加到原来那棵树上;

  5. 最后总和得到一棵树;

如果不够理解,请将这个负梯度拟合的残差直接带入之前文章《CART》例子中的残差数据中去,这样就有一个例子可供参考辅助理解。

作者:香橙云子
链接:https:///post/5a1624d9f265da43310d79d5
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多