lightGBM使用教程

最近在参加腾讯2018 广告大赛时,遇到到的知识点做一个分享!

LightGBM(Light Gradient Boosting Machine)是一个基于梯度 boosting 框架, 使用决策树为其学习算法. 它是分布式的, 高效的。它属于Microsoft 的DMTK(http://github.com/microsoft/dmtk)项目。

速度和内存使用的优化

许多提升工具对于决策树的学习使用基于 pre-sorted 的算法 [1, 2] (例如,在xgboost中默认的算法) ,这是一个简单的解决方案,但是不易于优化。

LightGBM 利用基于 histogram 的算法 [3, 4, 5],通过将连续特征(属性)值分段为 discrete bins 来加快训练的速度并减少内存的使用。 如下的是基于 histogram 算法的优点:

  • 减少分割增益的计算量

Pre-sorted 算法需要 O(#data) 次的计算

Histogram 算法只需要计算 O(#bins) 次, 并且 #bins 远少于 #data

这个仍然需要 O(#data) 次来构建直方图, 而这仅仅包含总结操作

  • 通过直方图的相减来进行进一步的加速

在二叉树中可以通过利用叶节点的父节点和相邻节点的直方图的相减来获得该叶节点的直方图
所以仅仅需要为一个叶节点建立直方图 (其 #data 小于它的相邻节点)就可以通过直方图的相减来获得相邻节点的直方图,而这花费的代价(O(#bins))很小。

  • 减少内存的使用 

可以将连续的值替换为 discrete bins。 如果 #bins 较小, 可以利用较小的数据类型来存储训练数据, 如 uint8_t
无需为 pre-sorting 特征值存储额外的信息

  • 减少并行学习的通信代价化

稀疏优化

对于稀疏的特征仅仅需要 O(2 * #non_zero_data) 来建立直方图

准确率的优化

Leaf-wise (Best-first) 的决策树生长策略
大部分决策树的学习算法通过 level(depth)-wise 策略生长树,如下图:

LightGBM 通过 leaf-wise (best-first)[6] 策略来生长树。它将选取具有最大 delta loss 的叶节点来生长。 当生长相同的 #leaf,leaf-wise 算法可以比 level-wise 算法减少更多的损失。


当 #data 较小的时候,leaf-wise 可能会造成过拟合。 所以,LightGBM 可以利用额外的参数 max_depth 来限制树的深度并避免过拟合(树的生长仍然通过 leaf-wise 策略)。

xgboost 通过 max_depth 对建树进行深度限制与模型复杂度控制 。

LightGBM 通过 num_leaves 执行带深度限制的 leaf-wise 叶子生长策略与模型复杂度控制。

因此我们无法设置完全相同的模型进行比较。为了相对权衡, 我们在xgboost中设置 max_depth=8 以使叶子数量达到最大数量 255 与 LightGBM 中设置 num_leves=255 进行比较。

类别特征值的最优分割

我们通常将类别特征转化为 one-hot coding。 然而,对于学习树来说这不是个好的解决方案。 原因是,对于一个基数较大的类别特征,学习树会生长的非常不平衡,并且需要非常深的深度才能来达到较好的准确率。
 

事实上,最好的解决方案是将类别特征划分为两个子集,总共有 2^(k-1) - 1 种可能的划分, 但是对于回归树 [7] 有个有效的解决方案。为了寻找最优的划分需要大约 k * log(k) .

基本的思想是根据训练目标的相关性对类别进行重排序。 更具体的说,根据累加值(sum_gradient / sum_hessian)重新对(类别特征的)直方图进行排序,然后在排好序的直方图中寻找最好的分割点。

网络通信的优化

LightGBM 中的并行学习,仅仅需要使用一些聚合通信算法,例如 “All reduce”, “All gather” 和 “Reduce scatter”. LightGBM 实现了 state-of-art 算法 [8] . 这些聚合通信算法可以提供比点对点通信更好的性能

并行学习的优化

特征并行

传统的特征并行算法旨在于在并行化决策树中的“ Find Best Split.主要流程如下:
 

  1. 垂直划分数据(不同的机器有不同的特征集)
  2. 在本地特征集寻找最佳划分点 {特征, 阈值}
  3. 本地进行各个划分的通信整合并得到最佳划分
  4. 以最佳划分方法对数据进行划分,并将数据划分结果传递给其他线程
  5. 其他线程对接受到的数据进一步划分

传统的特征并行方法主要不足:
 

  1. 存在计算上的局限,传统特征并行无法加速 “split”(时间复杂度为 “O(#data)”)。 因此,当数据量很大的时候,难以加速。
  2. 需要对划分的结果进行通信整合,其额外的时间复杂度约为 “O(#data/8)”(一个数据一个字节)

 

LightGBM 中的特征并行

既然在数据量很大时,传统数据并行方法无法有效地加速,我们做了一些改变:不再垂直划分数据,即每个线程都持有全部数据。 因此,LighetGBM中没有因数据划分而增加网络之间通信的开销,各个线程都知道如何划分数据。 而且,“#data” 不会变得更大,所以,每个机器都持有全部数据是合理的。

LightGBM 中特征并行的流程如下:
 

  1. 每个线程都在本地数据集上寻找最佳划分点{特征, 阈值}
  2. 本地进行各个划分的通信整合并得到最佳划分
  3. 执行最佳划分

然而,该特征并行算法在数据量很大时仍然存在计算上的局限。因此,建议在数据量很大时使用数据并行

数据并行

  • 传统算法

数据并行旨在于并行化整个决策学习过程。数据并行的主要流程如下:

  1. 水平划分数据
  2. 线程以本地数据构建本地直方图
  3. 将本地直方图整合成全局整合图
  4. 在全局直方图中寻找最佳划分,然后执行此划分
  • 传统数据划分的不足:

高通讯开销。 点对点的通讯算法,一个机器的通讯开销大约为 “O(#machine * #feature * #bin)” 。 

集成的通讯算法(例如,“All Reduce”等),通讯开销大约为 “O(2 * #feature * #bin)”[8] 。

 

  • LightGBM中的数据并行

LightGBM 中采用以下方法较少数据并行中的通讯开销:

  1. 不同于“整合所有本地直方图以形成全局直方图”的方式,LightGBM 使用分散规约(Reduce scatter)的方式对不同线程的不同特征(不重叠的)进行整合。 然后线程从本地整合直方图中寻找最佳划分并同步到全局的最佳划分中。
  2. LightGBM 通过直方图做差法加速训练。 基于此,我们可以进行单叶子的直方图通讯,并且在相邻直方图上使用做差法。

通讯开销:LightGBM 将数据并行中的通讯开销减少到 “O(0.5 * #feature * #bin)”。

投票并行

投票并行将致力于将“数据并行”中的通讯开销减少至常数级别。 其将会通过两阶段的投票过程,减小特征直方图的通讯开销 [9] .

GPU 支持可处理大规模数据

应用和度量

支持以下应用:

  • 回归,目标函数为 L2 loss
  • 二分类, 目标函数为 logloss(对数损失)
  • 多分类
  • lambdarank, 目标函数为基于 NDCG 的 lambdarank

源代码可参考:https://github.com/Microsoft/LightGBM

猜你喜欢

转载自blog.csdn.net/u010899985/article/details/81056935