Datawhale | 高级算法(3)——XGBoost

1. 算法原理

  • XGBoost是boosting算法的其中一种。Boosting算法的思想是将许多弱分类器集成在一起形成一个强分类器。因为XGBoost是一种提升树模型,所以它是将许多树模型集成在一起,形成一个很强的分类器。而所用到的树模型则是CART回归树模型.
  • XGBoost 算法思想就是不断地添加树,不断地进行特征分裂来生长一棵树,每次添加一个树,其实是学习一个新函数,去拟合上次预测的残差。当我们训练完成得到k棵树,我们要预测一个样本的分数,其实就是根据这个样本的特征,在每棵树中会落到对应的一个叶子节点,每个叶子节点就对应一个分数,最后只需要将每棵树对应的分数加起来就是该样本的预测值。
    在这里插入图片描述

w q ( x ) w_{q(x)} 为叶子节点q的分数,f(x)为其中一棵回归树

2. 损失函数

XGBoost 目标函数定义为:
在这里插入图片描述
目标函数由两部分构成,第一部分用来衡量预测分数和真实分数的差距,另一部分则是正则化项。正则化项同样包含两部分,T表示叶子结点的个数,w表示叶子节点的分数。γ可以控制叶子结点的个数,λ可以控制叶子节点的分数不会过大,防止过拟合。
正如上文所说,新生成的树是要拟合上次预测的残差的,即当生成t棵树后,预测分数可以写成:
在这里插入图片描述
很明显,我们接下来就是要去找到一个f_t能够最小化目标函数。XGBoost的想法是利用其在f_t=0处的泰勒二阶展开近似它。所以,目标函数近似为:
在这里插入图片描述
由于前t-1棵树的预测分数与y的残差对目标函数优化不影响,可以直接去掉。简化目标函数为:
在这里插入图片描述

3.分裂结点算法

在上面的推导中,我们知道了如果我们一棵树的结构确定了,如何求得每个叶子结点的分数。但我们还没介绍如何确定树结构,即每次特征分裂怎么寻找最佳特征,怎么寻找最佳分裂点。

正如上文说到,基于空间切分去构造一颗决策树是一个NP难问题,我们不可能去遍历所有树结构,因此,XGBoost使用了和CART回归树一样的想法,利用贪婪算法,遍历所有特征的所有特征划分点,不同的是使用上式目标函数值作为评价函数。具体做法就是分裂后的目标函数值比单子叶子节点的目标函数的增益,同时为了限制树生长过深,还加了个阈值,只有当增益大于该阈值才进行分裂。
在这里插入图片描述
同时可以设置树的最大深度、当样本权重和小于设定阈值时停止生长去防止过拟合。

4.正则化

正则化的目的是为了预防模型过拟合,一般思路是防止模型参数太多,即,模型太复杂。在本模型中,复杂度包括树的结构以及叶子节点的个数。
首先定义,一棵树有T个叶子节点,这T个叶子节点的值组成了一个T维向量w,q(x)是一个映射,用来将样本映射成1到T的某个值。q(x)其实是CART树的结构, w q ( x ) w_{q(x)} 是这棵树对样本x的预测值。
有了这个定义,xgboost就可以使用如下的正则化项
在这里插入图片描述
这里的λ 和γ 越大,越希望获得结构简单的树,因此对于相对叶子节点较多的树的惩罚越大。

5.对缺失值的处理

  • 通常情况下,人为处理缺失值的时候大多会选用中位数、均值或二者的融合来对数值型特征进行填补,使用出现次数多的类别来填补缺失的类别特征。
  • 在xgboost模型中允许缺失值存在。
  • 原始论文中关于缺失值的处理将其看与稀疏矩阵的处理看作一样。在寻找split point的时候,不会对该特征为missing的样本进行遍历统计**,只对该列特征值为non-missing的样本上对应的特征值进行遍历**,通过这个技巧来减少了为稀疏离散特征寻找split point的时间开销。在逻辑实现上,为了保证完备性****,会分别处理将missing该特征值的样本分配到左叶子结点和右叶子结点的两种情形,计算增益后选择增益大的方向进行分裂即可。可以为缺失值或者指定的值指定分支的默认方向,这能大大提升算法的效率。如果在训练中没有缺失值而在预测中出现缺失,那么会自动将缺失值的划分方向放到右子树。

6.优缺点

6.1优点:

(1)xgBoosting支持线性分类器,相当于引入L1和L2正则化项的逻辑回归(分类问题)和线性回归(回归问题);
(2)xgBoosting对代价函数做了二阶Talor展开,引入了一阶导数和二阶导数;
(3)当样本存在缺失值是,xgBoosting能自动学习分裂方向;
(4)xgBoosting借鉴RF的做法,支持列抽样,这样不仅能防止过拟合,还能降低计算;
(5)xgBoosting的代价函数引入正则化项,控制了模型的复杂度,正则化项包含全部叶子节点的个数,每个叶子节点输出的score的L2模的平方和。从贝叶斯方差角度考虑,正则项降低了模型的方差,防止模型过拟合;
(6)xgBoosting在每次迭代之后,为叶子结点分配学习速率,降低每棵树的权重,减少每棵树的影响,为后面提供更好的学习空间;
(7)xgBoosting工具支持并行,但并不是tree粒度上的,而是特征粒度,决策树最耗时的步骤是对特征的值排序,xgBoosting在迭代之前,先进行预排序,存为block结构,每次迭代,重复使用该结构,降低了模型的计算;block结构也为模型提供了并行可能,在进行结点的分裂时,计算每个特征的增益,选增益最大的特征进行下一步分裂,那么各个特征的增益可以开多线程进行;
(8)可并行的近似直方图算法,树结点在进行分裂时,需要计算每个节点的增益,若数据量较大,对所有节点的特征进行排序,遍历的得到最优分割点,这种贪心法异常耗时,这时引进近似直方图算法,用于生成高效的分割点,即用分裂后的某种值减去分裂前的某种值,获得增益,为了限制树的增长,引入阈值,当增益大于阈值时,进行分裂;

6.2缺点:

(1)xgBoosting采用预排序,在迭代之前,对结点的特征做预排序,遍历选择最优分割点,数据量大时,贪心法耗时,LightGBM方法采用histogram算法,占用的内存低,数据分割的复杂度更低;
(2)xgBoosting采用level-wise生成决策树,同时分裂同一层的叶子,从而进行多线程优化,不容易过拟合,但很多叶子节点的分裂增益较低,没必要进行跟进一步的分裂,这就带来了不必要的开销;LightGBM采用深度优化,leaf-wise生长策略,每次从当前叶子中选择增益最大的结点进行分裂,循环迭代,但会生长出更深的决策树,产生过拟合,因此引入了一个阈值进行限制,防止过拟合.

https://www.cnblogs.com/Sugar-Chl/p/10168838.html

7.应用场景

XGBoost适用于Linux,Windows,MacOS。从项目描述来看,它旨在提供一个“可扩展,便携式和分布式的梯度提升(GBM,GBRT,GBDT)库”。 除了在一台机器上运行,它还支持分布式处理框架Apache Hadoop,Apache Spark和Apache Flink。

猜你喜欢

转载自blog.csdn.net/orient928/article/details/89196398