XGBoost和LightGBM的比较

目录

 

1.XGBoost

sgboost中树节点分裂时所采用的公式:

xgboost的分裂步骤:

xgboost总结

LightGBM:基于决策树算法的分布式梯度提升框架

LightGBM在模型的训练速度和内存方面的优化

LightGBM的leaf-wise 的生长策略

LightGBM支持类别型特征

xgboost与LightGBM的区别


1.XGBoost

XGBoost能自动利用CPU的多线程,而且适当改进了gradient boosting,加了剪枝,控制了模型复杂度

  • 传统GBDT以CART作为基分类器,特指梯度提升决策树算法,而XGBoost还支持线性分类器(gblinear),这个时候XGBoost就相当于带L1正则和L2正则项的logistics回归(分类问题)或者线性回归(回归问题)
  • 传统的GBDT只用到一阶导数信息,xgboost则对代价函数进行了二阶泰勒展开,同时用到了一阶和二阶导数。
  • xgboost在代价函数里加入了正则项,用于控制模型的复杂度。正则项里包含了树的叶子节点个数、每个叶子节点上输出的score的L2模的平方和。从Bias variance tradeoff角度来讲,正则项降低了模型的variance,使学习出来的模型更加简单,防止过拟合,这也是xgboost优于传统的GBDT的一个特性

xgboost中树节点分裂时所采用的公式:

  • Shrinkage(缩减),相当于学习速率(xgboost中的eta)。xgboost在进行完一次迭代后,会将叶子节点的权重乘上该系数,主要是为了削减每棵树的影响,让后面有更大的学习空间。实际应用中,一般把eta设置得小一点,然后迭代次数设置得大一点(传统gbdt的实现也有学习速率)
  • 列抽样(column subsampling)。xgboost借鉴随机森林的做法,支持列抽样,不仅能降低过拟合,还能减少计算,这也是xgboost不同于gbdt的一个特性
  • 对缺失值的处理。对于特征的值有缺失的样本,xgboost可以自动学习出它的分裂方向
  • xgboost工具支持并行。注意:xgboost的并行不是tree粒度的并行,xgboost也是一次迭代完才能进行下一次迭代的(第t次迭代的代价函数里包含了前面t-1次迭代的预测值)。xgboost的并行是在特征粒度上的。决策树的学习最耗时的一个步骤就是对特征的值进行排序(因为要确定最佳分割点),xgboost在训练之前,预先对数据进行了排序,然后保存为block结构,后面的迭代中重复地使用这个结构,大大减少计算量。这个block结构也使得并行成为了可能,在进行节点的分裂时,需要计算每个特征的增益,最终选择增益最大的那个特征去做分裂,那么各个特征的增益计算就可以开多线程进行。(特征粒度上的并行,block结构,预排序)

       XGBoost和LightGBM的比较_第1张图片

  • 上面这个公式形式上跟ID3算法、CART算法是一致的,都是用分裂后的某种值减去分裂前的某种值,从而得到增益。为了限制树的生长,我们可以加入阈值,当增益大于阈值时才让节点分裂,上式中的gamma即阈值,它是正则项里叶子节点数T的系数,所以xgboost在优化目标函数的同时相当于做了预剪枝。另外上式中还有一个系数lambda,是正则项里leaf score的L2模平方的系数,对leaf score做了平滑,也起到了防止过拟合的作用,这个是传统gbdt里不具备的特性。

xgboost的分裂步骤:

  1. 首先,对所有特征按数值进行预排序
  2. 其次,在每次的样本分割时,用O(#data)的代价找到每个特征的最优分割点
  3. 最后,找到最后的特征以及分割点,将数据分割成左右两个子节点。
  4. 优点:这种pre-sorting算法能够准确找到分裂点,但是在空间和时间上有很大的开销;
  5. 缺点:1:需要对特征进行预排序,且需要保存排序后的索引值(为了后续快速的计算分裂点),因此内存需要训练数据的两倍
  6. 缺点:2:在遍历每一个分裂点的时候,都需要进行分裂增益的计算,消耗的代价大。

xgboost总结

  • 显式地将树模型的复杂度作为正则项加在优化目标
  • 公式推导中用到了二阶导数信息,而gbdt只用到一阶导数
  • 允许使用列抽样(column subsampling)来防止过拟合,借鉴了random forest的思想,
  • 实现了一种分裂节点寻找的近似算法,用于加速和减小内存消耗
  • 节点分裂算法能自动利用特征的稀疏性
  • 样本数据事先排好序并以block的形式存储,利于并行计算
  • penalty function Omega 主要是对树的叶子节点数和叶子分数做惩罚,这点确保了树的简单性
  • 支持分布式计算,可以运行在MPI,YARN上,得益于底层支持容错的分布式通信框架rabit

LightGBM:基于决策树算法的分布式梯度提升框架

LightGBM在模型的训练速度和内存方面的优化

  1. 基于树模型的boosting算法,很多算法比如xgboost都是用预排序(pre-sorting)算法进行特征的选择和分裂
  2. LightGBM采用HistoGram算法,其思想是将连续的浮点特征离散成k个离散值,并构造宽度为k的Histogram。然后遍历训练数据,计算每个离散值在直方图中的累计统计量。在进行特征选择时,只需要根据直方图的离散值,遍历寻找最优的分割点。

LightGBM的leaf-wise 的生长策略

  • 它摒弃了现在大部分gbdt使用的按层生长(level-wise)的决策树生长策略,使用带有深度限制的按叶子生长(leaf-wise)策略。level-wise过一次的数据可以同时分裂同一层 的叶子,容易进行多线程优化,也好控制模型复杂度,不容易过拟合。但实际上level-wise是一种低效的算法,因为它不加区分的对待同一层的叶子,带来了很多没必要的开销,因为实际上很多叶子的分裂增益较低,没必要进行搜索和分裂。

       XGBoost和LightGBM的比较_第2张图片

  • leaf-wise则是一种更为高效的策略,每次从当前所有叶子中,找到分裂增益最大的一个叶子,然后分裂,如此循环。因此同level-wise相比,在分裂次数相同的情况下,leaf-wise可以降低更多的误差,得到更好的精度。leaf-wise的缺点是可能会长出比较深的决策树,产生过拟合。因此LightGBM在leaf-wise之上增加了一个最大深度的限制,在保证高效率的同时防止过拟合。

      XGBoost和LightGBM的比较_第3张图片

LightGBM支持类别型特征

实际上大多数机器学习工具都无法直接支持类别型特征,一般需要把类别特征转化为one-hotting特征,降低空间和时间的效率。而类别特征的使用是在实践中很常用的。基于这个考虑LightGBM优化了对类别特征的支持,可以直接输入类别特征,不需要额外的0/1展开。并在决策树算法上增加了类别特征的决策规则:

  1. Histogram算法并不是完美的。由于特征被离散化后,找到的并不是很精确的分割点,所以会对结果产生影响。但在实际的数据集上表明,离散的分割点对最终的精度影响并不大,甚至会更好一点。原因在于decision tree本身就是一个弱学习器,采用Histogram算法会起到正则化的效果,能有效的防止过拟合
  2. 时间上的开销由原来的O(#data*#features)将到O(#k*#features)。由于离散化,#bin远小于#data,因此时间上有很大的提升。
  3. Histogram算法还可以进一步加速。一个叶子节点的Histogram可以直接由父节点的Histogram和兄弟节点的Histogram做差得到。一般情况线下构造Histogram需要遍历该叶子上的所有数据,通过该方法,只需要遍历Histogram的k个桶。速度提升了一倍。

       XGBoost和LightGBM的比较_第4张图片

xgboost与LightGBM的区别

  1. 切分算法(切分点的选取)
  2. 占用的内存更低,只保存特征离散化后的值,而这个值一般用8位整型存储就足够了,内存消耗可以降低为原来的1/8
  3. LightGBM直接支持类别特征
  4. 决策树生长策略不同

       XGBoost采用的是带深度限制的level-wise生长策略。level-wise过一次数据可以能够同时分裂同一层的叶子,容易进行多线程优化,不容易过拟合;但不加区分的对待同一层叶子,带来了很多没必要的开销(实际上很多叶子的分裂增益较低,没必要进行搜索和分裂)

       LightGBM采用leaf-wise生长策略,每次从当前所有叶子中找到分裂增益最大(数据量最大)的一个叶子,进行分裂,如此循环;但会生长出比较深的决策树,产生过拟合(因此LightGBM在leaf-wise之上增加了一个最大深度的限制,在保证高效率的同时防止过拟合)

        XGBoost和LightGBM的比较_第5张图片

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(machineLearning)