XGBoost 和 LightGBM 对比

Ref:20道XGBoost面试题  https://mp.weixin.qq.com/s?__biz=MzI1MzY0MzE4Mg==&mid=2247485159&idx=1&sn=d429aac8370ca5127e1e786995d4e8ec&chksm=e9d01626dea79f30043ab80652c4a859760c1ebc0d602e58e13490bf525ad7608a9610495b3d&scene=21#wechat_redirect

深入理解LightGBM  https://blog.csdn.net/program_developer/article/details/103838846

LightGBM 的介绍:

记忆宝典:43(3) 原则:  lgb 不是要解决海量数据吗,(3)所以采用goss算法减少样本,(4)采用互斥特征捆绑较少特征,以便于计算,(1)先是树的生长策略level/leaf wise;(2)然后节点分裂的算法-直方图算法/预排序算法;  工程上的优化:(1)支持类别特征(2)高效并行:特征并行 、数据并行、投票并行(3)cache命中率有化

 

XGBoost和LightGBM的区别

记忆宝典:

(1)树生长策略:XGB采用level-wise的分裂策略,LGB采用leaf-wise的分裂策略。XGB对每一层所有节点做无差别分裂,但是可能有些节点增益非常小,对结果影响不大,带来不必要的开销。Leaf-wise是在所有叶子节点中选取分裂收益最大的节点进行的,但是很容易出现过拟合问题,所以需要对最大深度做限制 。

(2)分割点查找算法:XGB使用特征预排序算法,LGB使用基于直方图的切分点算法,其优势如下:

  • 减少内存占用,比如离散为256个bin时,只需要用8位整形就可以保存一个样本被映射为哪个bin(这个bin可以说就是转换后的特征),对比预排序的exact greedy算法来说(用int_32来存储索引+ 用float_32保存特征值),可以节省7/8的空间。

  • 计算效率提高,预排序的Exact greedy对每个特征都需要遍历一遍数据,并计算增益,复杂度为𝑂(#𝑓𝑒𝑎𝑡𝑢𝑟𝑒×#𝑑𝑎𝑡𝑎)。而直方图算法在建立完直方图后,只需要对每个特征遍历直方图即可,复杂度为𝑂(#𝑓𝑒𝑎𝑡𝑢𝑟𝑒×#𝑏𝑖𝑛𝑠)。

  • LGB还可以使用直方图做差加速,一个节点的直方图可以通过父节点的直方图减去兄弟节点的直方图得到,从而加速计算

实际上xgboost的近似直方图算法也类似于lightgbm这里的直方图算法,为什么xgboost的近似算法比lightgbm还是慢很多呢?

xgboost在每一层都动态构建直方图, 因为xgboost的直方图算法不是针对某个特定的feature,而是所有feature共享一个直方图(每个样本的权重是二阶导),所以每一层都要重新构建直方图。比如local策略下,根节点有data个样本,对n个特征创建n个直方图,直方图的划分是根据样本的2阶梯度作为权重得到的,每次分裂后,样本的2阶梯度就会发生变化,就需要重新计算更新直方图。

有点疑问:XGB应该也是针对每个特征都分别构建一个直方图,分桶的依据是样本的二级梯度;完成一次分裂后,样本的二阶梯度发生变化,就需要重新计算,重新构建每个特征的直方图。

lightgbm中对每个特征都有一个直方图,所以构建一次直方图就够了。(1)根节点包含所有样本data,对n个特征,构建n个直方图,(2)根节点分裂为左右两个子节点,可以先对右节点创建n个直方图,右节点的样本数量为data/2,再用根节点的对应的n个直方图减去右节点的n个直方图,就得到左节点的n个直方图,(3)如果一棵树有m层深,则就需要构建m次直方图,对应的样本量分别为data,data/2,data/4....

(3)支持离散变量:无法直接输入类别型变量,因此需要事先对类别型变量进行编码(例如独热编码),而LightGBM可以直接处理类别型变量。

(4)缓存命中率:XGB使用Block结构的一个缺点是取梯度的时候,是通过索引来获取的,而这些梯度的获取顺序是按照特征的大小顺序的,这将导致非连续的内存访问,可能使得CPU cache缓存命中率低,从而影响算法效率。而LGB是基于直方图分裂特征的,梯度信息都存储在一个个bin中,所以访问梯度是连续的,缓存命中率高。

(5)LightGBM 与 XGboost 的并行策略不同:

  • 特征并行 :LGB特征并行的前提是每个worker留有一份完整的数据集,但是每个worker仅在特征子集上进行最佳切分点的寻找;worker之间需要相互通信,通过比对损失来确定最佳切分点;然后将这个最佳切分点的位置进行全局广播,每个worker进行切分即可。XGB的特征并行与LGB的最大不同在于XGB每个worker节点中仅有部分的列数据,也就是垂直切分,每个worker寻找局部最佳切分点,worker之间相互通信,然后在具有最佳切分点的worker上进行节点分裂,再由这个节点广播一下被切分到左右节点的样本索引号,其他worker才能开始分裂。二者的区别就导致了LGB中worker间通信成本明显降低,只需通信一个特征分裂点即可,而XGB中要广播样本索引。

  • 数据并行 :传统的数据并行策略主要为水平划分数据,让不同的机器先在本地构造直方图,然后进行全局的合并,最后在合并的直方图上面寻找最优分割点。这种数据划分有一个很大的缺点:通讯开销过大。如果使用点对点通信,一台机器的通讯开销大约为 O(#machine∗#feature∗#bin)O(\#machine * \#feature *\#bin )O(#machine∗#feature∗#bin) ;如果使用集成的通信,则通讯开销为 O(2∗#feature∗#bin)O(2 * \#feature *\#bin )O(2∗#feature∗#bin) 。

    LightGBM在数据并行中使用分散规约 (Reduce scatter) 把直方图合并的任务分摊到不同的机器,降低通信和计算; 在节点分裂时利用直方图做差,进一步减少了一半的通信量。

     

  • 投票并行(LGB):基于投票的数据并行则进一步优化数据并行中的通信代价,使通信代价变成常数级别。在数据量很大的时候,使用投票并行的方式只合并部分特征的直方图从而达到降低通信量的目的,可以得到非常好的加速效果。具体过程如下图所示。大致步骤为两步:

    (1)本地找出 Top K 特征,并基于投票筛选出可能是最优分割点的特征;
    (2)合并时只合并每个机器选出来的特征。
     

©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页