XGBoost: 从决策树说起
学习笔记,可能有些谬误,请批判性阅读。
决策树用来进行分类或回归都是可以的。
一棵决策树构成的分类器,从根节点开始,依循划分标准,向左或向右走下去。这样递归地进行,直到叶子节点为止。叶子节点的类别或值,就是分类或回归的预测结果。
一棵平平无奇的决策树,是怎么生成的
信息熵
用来衡量事件的确切性程度,或样本的同一性。
如果样本全部属于同一类,信息熵为0;
如果样本等分为不同类别,信息熵为1。
公式长这样:
其中,指entropy,这里是指信息熵;
是某个分布。
信息增益
增益,是一个相对值,划分后相对划分前,信息熵的变化值,就是信息增益。
其中,是划分前的树,
是该划分使用的特征。
构造决策树就是找到信息增益最大的分裂方法(或者说用什么特征什么阈值划分,即纯度最高的分支)。这个思路很直观,实际也很暴力。遍历每个特征的每个可能的分裂值,信息增益最高的,就是最佳分裂。
总结
信息熵和信息增益,是生成决策树的核心依据。具体的生成过程,在文章最后有补充说明。
决策树有一个缺点,容易过拟合。特别是对树的规模没有限制的时候,决策树甚至可以为训练集中的每个uniq样本,生成一条路径。这显然是矫枉过正,遇到没见过的样本,这棵决策树肯定歇菜了。
一般用剪枝来解决这个问题。剪枝的思想是,信息增益低于阈值的分裂(预剪枝,直接不分裂)/子树(后剪枝,已经生成子树),可以不进行分裂/或者用子树的叶子节点的众数进行替代。
集成学习(Boosting)
一棵树或者说单个分类/回归模型的力量是有限的,但我们可以集思广益,多个分类/回归模型共同预测(投票/均值/etc)一件事情。集成学习的单个模型并不局限于决策树,但在决策树中表现的尤为明显。
随机森林
听着还蛮高大上的名字。中心思想是,随机抽取样本子集,构建一棵决策树;这样重复,随机构建多棵决策树;再来,对每个样本,每棵树的预测结果进行投票,就得到了最终预测结果。
随机抽取子集这个思想,就大大降低了过拟合的概率。
梯度增强(Gradient Boosting)
这个就是大名鼎鼎的GBDT(Gradient Boosting Decesion Tree)了。GBDT也是多棵树,但多棵树不是相互独立,而是共同协作的,其中的纽带就是残差。
残差,就是当前状态(预测过程中的某一步),预测值离真实值还有多远。在模型生成/调整的过程中,不断地减小当前残差,使之趋近于0,这样来使模型趋近完美。(我一度十分怀疑Resnet借鉴了GBDT。)
具象一点。
首先,生成了一棵平平无奇的决策树,此时,
的预测值与真实值的差距为
。
然后,我们再生成一棵平平无奇的决策树,此时
的预测目标就是尽可能接近
。
然鹅,天不遂人愿,的预测值与真实值的差距还有
,不抛弃不放弃,继续生成
,
,……
最终,由于残差到0还是过于理想,达到给定阈值就可以了,这样结束了模型生成/调整。
相比随机森林内部比稿,梯度增强还是更团结一些,一起朝着目标进发。
XGBoost推导
XGBoost的X,是指extremely,卓越的GB。
XGBoost在最原始的GBDT基础上,添加了对树结构的惩罚,也就是希望模型尽可能简单,树少一点,每棵树的深度、节点都少一点。
下面给出XGBoost的目标函数的推导过程。
1、假设当前已经生成了
棵决策树
那么样本当前预测值为:
2、损失函数
这里的是样本
的真实值,也就是一个常数。
3、目标函数是在损失函数的基础上,加上了对模型复杂度的惩罚。
展开来,以棵树构成的分类模型的损失函数,就是
这里取值,是因为当构造第
棵树时,前
棵树已经固定下来,模型复杂度已经是个常数。实际上这里也是一个归纳法。
4、接下来,借助神奇的泰勒展开。
泰勒展开是一个极限逼近原理,二阶展开式为:
其中,
,是
的一阶导数;
,是
的二阶导数。
在目标函数中,就是
(第t棵树的预测结果),
则是前
棵树构成的模型的损失函数
。
将目标函数转换为:
其中,,
与上述类似。
然后去掉目标函数中的常数项:
5、然后回归到树结构。
假设第棵树的叶子节点个数为
,定义这棵树的复杂度:
其中,表示叶子节点
对应的值向量。
然后,定义集合,这里的
表示样本
被第
棵树预测到叶子节点
,这个集合表示所有被第
棵树预测到叶子节点
的样本的集合。这样,样本集合的分布,就可以转换为叶子节点的分布了。
这样,当,
。
目标函数被转换为:
合并同类项:
令:
(,
是怎么计算的?或者说
,
是怎么计算的?由定义来看,
是loss函数的一阶导数,例如常见的均方误差,同理可得
。)
这样,目标函数被化简为:
取极小值时,的一阶导数为0,也就是:
此时,,这个式子是叶子节点赋值的依据。
代入目标函数,最终可得:
这个,奏是XGBoost的目标函数了。
生成一棵新的决策树
需要补充说明的是,XGBoost是如何生成一棵新的决策树呢?采用的是贪心策略。
第一步,计算每个特征的最大收益。(从根节点开始)
其中,收益是指分列前的,减去分裂后左右两子树的
之和,差值越大,分类越好。
对每个特征,将走到当前节点的所有样本的该特征值有序排列,枚举所有取值作为阈值,选取最大收益,作为该特征的收益,记下此时的阈值。
第二步,选择收益最大的特征为分裂特征,以收益最大的阈值进行分裂。
然后,对于当前节点分裂出来的左右节点,分别循环第一步&第二步,直到满足停止条件为止。
参考
[1] https://cloud.tencent.com/developer/article/1005611
[2] http://baijiahao.baidu.com/s?id=1641541736640596344&wfr=spider&for=pc