决策树相关算法——XGBoost原理分析及实例实现(一)

917 阅读7分钟

1.前言

本篇博客主要叙述的是提升方法中的XGBoost,而XGBoost本身包含的技术点及算法优化太多,且网上已经有很多原理性的相关介绍了,但是笔者还是希望自己亲身走一遍XGBoost的原理理解过程,以此来更熟练的使用XGBoost。话不多说,此篇主要叙述基于CART决策树的XGBoost的代价函数的优化过程(即该模型的参数求解过程)。
前篇博客决策树相关算法——Boosting之Adaboost&GBDT详细分析与实现中的GBDT的代价函数优化的过程使用的是前向分步算法————迭代求解出每一步的基函数的模型参数。而具体的每一步m求解基函数的模型参数是使用决策树去拟合前一步(m-1)中的负梯度值的方式来进行的。至于为什么使用该方式会使代价函数减少的解释是通过画总的代价函数L(y,y')和加法模型函数f(x)之间的关系图的方式。具体解释可以查看前篇博客。本篇博客将从数学公式的角度进行解释————对GBDT的代价函数进行一阶泰勒展开,从而引出XGBoost的代价函数的优化过程。

2.优化前的分析

分析1: 对于XGBoost中的提升树也是加法模型:
图1
图10
分析2: XGBoost中改进的代价函数:
图2
说明1: 公式1中输出的y是模型最后预测的值。q表示每棵树的结构,它会将一个训练样本实例映射到相对应的叶子索引上。T是树中的叶子数。w的维度是TWi表示q对应的树结构上的第i个叶子结点的权重。fk是由一颗独立的树结构q(x)和其叶子结点对应的权重W组成,其中q(x)W的下标。fk与正常的分类回归树不同的地方在于正常的分类回归树包含了在每个叶子上的一个连续分值,而XGBoost的回归树使用wi来表示第i个叶子上的分值。
说明2: 公式2是XGBoost中改进的提升树的代价函数,主要改进的地方是在GBDT的代价函数上加了正则项,从而使得每步迭代的树结构更不容易过拟合.从图中可以看出正则项由叶子结点数T和每个叶子结点的权重W的L2范式相加组成.T是惩罚树结构的复杂度,W的L2范式是惩罚树模型的参数的复杂度。
说明3: 观察到XBGoost中的提升树模型也属于加法模型,可考虑使用前向分步算法,迭代求解出该加法模型中所有的参数,但是需要对上述改进的代价函数进行优化化简。这个时候,XGBoost的创作者陈天奇巧妙的对改进的代价函数进行了泰勒展开,从而将代价函数进行了近似的化简。

3.泰勒公式的复习及初步理解

泰勒公式 是一个用函数(多项式函数)在某点的信息描述其(原复杂函数)附近取值的公式。可以理解为在某个点x0附近,用多项式函数来近似其他复杂的函数。为什么是用多项式去近似呢?因为多项式具有好计算,易求导,且好积分等一系列的优良性质。 公式如下:
图11
其中R_ n(x)是泰勒公式的余项且是(x-a)^n的高阶无穷小:
图12
利用到上述这一点我们可以相继写出一阶和二阶泰勒展开式如下:
图13
泰勒展开心得: 要灵活的使用泰勒展开式就需要记住两点:1.定位好这个特殊点x0(它是在多项式函数这边的)和原来要化简的复杂函数f(x),2.根据现实的情况,确定你的泰勒展开式是需要几阶,阶越高,多项式函数的值和原复杂函数的值就越高。

4.XGBoost代价函数的优化

Step 1展示出要优化的代价函数
图2
Step 2前向分步算法中第t步迭代时的代价函数
图14
图3
Step 3将代价函数L分别进行一阶和二阶展开
使用之前的泰勒展开心得进行分析:t步的代价函数L是如此的复杂,它是仅关于f_t(x)变化的复杂函数,是需要进行泰勒展开的。某点附近可以用多项式函数近似复杂函数,其中这个某点x0t-1时的模型f_(t-1)(x)的值.
图15
Step 4泰勒的二阶展开后的式子
图4
插入的GBDT解释: 此时GBDT的第t步需要拟合拟合前一步(t-1)中的负梯度值的方式来进行的解释为泰勒的一阶展开:
图16
继续进行XGBoost提升树的代价函数的化简,因为上面红框中的数为常数,泰勒二阶展开后的代价函数需要减小的化简式如下:
图5
Step 5最终化简
将代价函数的正则项展开,并定义Ij={i|q(xi)=j}是叶子j的实例(样本)集合。该式转换的过程是一开始是对所有样本的代价值进行累加得到代价函数,后面的是对每个叶子结点上的每个样本集合的代价值的累加。于是最终我们的代价函数就是式四。
图6
其中W是我们要求的第t步的决策树的模型参数。后面的T及它的系数γ,是变化后的正则项,也就是整个树的复杂程度的惩罚。可以看到该式是一个一元二次方程,为使得最后的L极小.可以推出下式:
图7
这样的话,便可以求出第t步的XGBoost的决策树的每个叶子j的权重Wj.接下来就是怎么构造这颗XGBoost的决策树的树结构,首先是需要寻找某个特征的某个特征值作为切分点。遵循使得第t步代价函数最小的原则,经过式5我们可以计算出该树的具体的代价函数的值为,将式5带入式4得:
图8
式6是可以用样本数据获取的,所以寻找q的切分点便以此为基准进行,将切分前的与切分后的进行做差对比,假设ILIR是一次划分(split)后的左节点和右节点所对应的实例集合。I=IL⋃IR
图9

5.XGBoost树结构的切分点贪心查找算法

此处有点类似于CART回归树的树结构构造过程,遍历特征和特征取值,比较切分前后的平方误差的大小,获得最佳切分点,算法图:
图17
理解过程: 从树的深度为0开始,每一节点都遍历所有的特征。对于某个特征,先按照该特征里的值进行排序,然后线性扫描该特征来决定最好的分割点,最后在所有特征里选择分割后,选择L_spilt最高的那个特征和该特征对应的取值。如此切分下去,此时需要考虑的问题是,当最好的情况下,L_spilt为负值时,树的生长停止。此种效率最高也最简单。但是这也可能错过L_spilt先为负后慢慢变大的情况.所以此时需要设置一个树的最大深度,最后来修剪掉L_spilt为负的切分。

6.XGBoost防止过拟合的两大trick

Shrinkage and Column Subsampling
陈天奇的论文中提到XGBoost除了在代价函数后面添加正则项用于防止过拟合后,还引入了Shrinkage and Column Subsampling两个trick。Shrinkage会在XGBoost每一步迭代求解决策树的时候会将新加入的W通过一个因子η进行缩放即乘以η。与随机优化中的learning rate相类似,对于用于提升模型的新增树(future trees),shrinkage可以减少每棵单独的树、以及叶子空间(leaves space)的影响。第二个技术是列特征子抽样(column feature subsampling)。该技术在RandomForest中使用,使用列子抽样可以阻止overfitting。列子抽样的使用可以加速并行算法的计算,在随机森林中也介绍过为什么列抽样会让模型不易过拟合。原因参考决策树相关算法——Bagging之基于CART的随机森林详细说明与实现

7总结XGBoost的提升树算法过程

参考网上资源的
图23

参考链接

XGBoost: A Scalable Tree Boosting System