读了陈天奇的XGBoost:A Scalable Tree Boosting System ,写一下阅读笔记。恳请各位斧正。
1. Gradient Tree Boosting
tree boost的思想是利用一颗一颗学习能力都不是很强的DT(这里用了CART),最终得到一个很强大的模型。每一棵树有自己的结构和叶子权重w(也就是得分score)
带有规则项的目标函数有如下形式:
由于上式第二项是包含了参数的函数,所以目标函数不能用欧式空间中的优化方法进行优化。因此考虑利用一种additive的方式去训练模型,即基于上一轮的预测添加一个小的增量,这个小的增量能使目标函数变小。这里就体现了Adaboost思想,即更加关注分错的样本。
作者在这里直接给出了优化方法,是对上述把目标函数进行了二阶泰勒展开。这与原始的GB是不一样的,原始的GB只进行了一阶泰勒展开,如下
将公式(2)代入式子,求解最优w
该公式(6)可作为树结构好坏的评价标准,这个值越小,树的结构越好。
2. Split Finding Algorithm
通过不断地枚举不同树的结构,再利用这个打分函数来寻找出一个最优结构的树,加入到模型中,再重复这样的操作。但实际枚举所有是不可行的,xgboost中利用贪心的办法,一次只加入一个叶子的分割。树结点分裂时采用的公式如下:
观察这个目标函数可知,引入分割并不一定是的情况变好,当引入分割后的得分Lsplit小于某个阈值(gamma)时,就不进行分割,而这一项由公式(2)可知是叶子节点个数T的系数,所以xgboost在优化目标函数的同时完成了预剪枝的过程。此外公式中的lambda也是公式(2)中第二项系数,对Leaf score做了平滑处理,也起到了防止过拟合的作用。
scikitlearn中的gbdt是针对连续值采用暴力枚举法寻找分割点的,而xgboost中采用了一种近似方法寻找分割点,并且可以处理离散特征。具体算法如下
3. 其他技巧
1. 通过shrinkage和列采样防止过拟合。前者在每一次tree boosting后对weight做一个衰减,减少当前已学习到的树对模型的影响,同时也为后面的待学习的树留有一定生长空间;后者的基本思想和RF中一样,对特征进行采样,加快并行计算的速度
2.可以处理特征值缺失的情况,把缺失值加到一个默认的结点,可以自动学习他们的方向。