【机器学习】LightGBM 解读 (集成学习_Boosting_GBM)
文章目录
- 【机器学习】LightGBM 解读 (集成学习_Boosting_GBM)
- 1. 介绍
- 2. 数据预处理
- 2.1 基于梯度的单边采样(GOSS)
- 2.2 互斥特征捆绑(EFB)
- 3. 决策树学习
- 3.1 寻找连续特征最优分裂点
- 3.2 寻找类别特征最优分裂点
- 3.3 按叶子生长策略学习树结构
- 4. 多机并行优化
- 4.1 特征并行
- 4.1 数据并行
- 4.3 选举并行
- 参考
1. 介绍
GBDT (Gradient Boosting Decision Tree) 是机器学习中一个长盛不衰的模型,其主要思想是利用弱分类器(决策树)迭代训练以得到最优模型,该模型具有训练效果好、不易过拟合等优点。GBDT不仅在工业界应用广泛,通常被用于多分类、点击率预测、搜索排序等任务;在各种数据挖掘竞赛中也是致命武器,据统计Kaggle上的比赛有一半以上的冠军方案都是基于GBDT。
而 LightGBM(Light Gradient Boosting Machine)也是一种 GBDT,LightGBM 可以说是在 XGBoost 上做的优化。它使用决策树作为基学习器。LightGBM 为高效并行计算而生,它的 Light 体现在以下几个点上:
- 更快的训练速度
- 更低的内存使用
- 支持单机多线程,多机并行计算,以及 GPU 训练
- 能够处理大规模数据
2. 数据预处理
大数据的大体现在两方面:样本多和特征多。 LightGBM 针对在数据预处理阶段对这两个问题进行了解决。
- 针对样本多的问题,提出了基于梯度的单边采样算法(Gradient-based One-Side Sampling,GOSS);
- 针对特征多的问题,提出了互斥特征捆绑算法(Exclusive Feature Bundling,EFB)。
2.1 基于梯度的单边采样(GOSS)
样本多,可以删。 LightGBM 利用求得的梯度对样本进行筛选。
- 按常识来看,梯度越大应该是越欠学习。如果大梯度样本能够预测正确,对增益的贡献将会更大,所以希望节点分裂时能够准确地划分大梯度样本,小梯度样本可以有错误。
- 既然如此,筛选样本的时候,就保留大梯度样本,只删除一部分小梯度样本。这就是 GOSS 思路,具体过程如下:
1)先对梯度绝对值降序排列,便于筛选
2)设个比例阈值 a,排序后的样本前 a * 100% 叫大梯度样本,全部保留
3)后
(
1
−
a
)
∗
100
(1-a) * 100%
(1−a)∗100 的样本叫小梯度样本,随机抽样,抽样比例为
b
∗
100
b * 100%
b∗100
4)由于随机抽样不是针对全部样本,所以会改变原始数据分布。为了尽量保持数据分布,需要给抽样出来的样本乘个系数,让他们保持原分布。这个系数是:
解释下算法名字 ——基于梯度的单边采样。
- 基于梯度体现在按照梯度顺序排序;
- 单边采样体现在只在小梯度样本这边采样。
作者在五个数据集上进行了测试,如下表,表中数值为训练单棵决策树需要的秒数。这里只需要关注红框中的两列,
- 其中 EFB_only 这列是只使用了 EFB(互斥特征捆绑)的 LightGBM 方法,
- 另一列是完整的 LightGBM 算法。
所以这两列差别在于左边的没用 GOSS,右边的用了,因此可以用于对比 GOSS 效果。很明显,GOSS 平均能提速一倍左右。
2.2 互斥特征捆绑(EFB)
特征多,可降维。 LightGBM 利用稀疏性,对特征进行无损合并。
- 从特征角度来看,稀疏特征会包含很多 0 元素;
- 从样本角度来看,一个样本的多个稀疏特征经常同时为 0。
EFB 基于这种想法,对互斥特征进行了捆绑,整体过程有点类似于 One-Hot 逆过程,以下图为例详细介绍。
1)先看第一个表格,这个是没做 EFB 的原表格。表格里有 6 个样本,每个样本有 5 个特征,前 3 个特征稀疏,后 2 个特征稠密。稠密特征不管,只看稀疏特征,目标是把这三个稀疏特征合并成一个新特征,并把这个新特征叫做 Bundle。
- 当一行样本的 3 个稀疏特征中只有 1 个非零元素时,可以忽略 0 元素,只保留非零元素,这样就实现了 3 -> 1 的降维。
- 但是显然这样没办法实现 1 -> 3 的还原,因为不清楚合并后得到的非零元素是哪个原始特征的,这就说明我们在合并时损失了一些信息。
- 可以通过数据分布范围内涵地表示合并后元素所属原特征。假设三个特征分布范围都为 1~10,第一个特征不动,第二个特征错开第一个分布,全体元素在坐标轴上向右偏移 10,第三个特征错开前两个特征,全体元素向右偏移 20。这样就形成了箭头下方的第二个表格,每个元素可以根据大小范围判断属于哪个原特征。这个分布错开的过程如下动图:
2)注意到,样本 3 在合并的时候,有两个非零元素,不符合要求。LightGBM 把这种情况定义为冲突。如果完全拒绝这种情况,那其实可以合并的特征会很少,所以没办法只能适当容忍冲突。
当几个特征冲突比例小(源码给的阈值是 1/10000 )的时候,影响不大,忽略冲突,把这几个特征叫做互斥特征;当冲突比例大的时候,不能忽略,EFB 不适用。那么对于样本 3 这种冲突情况,以最后参与合并的特征为准,所以表格里是 20+8 而不是 10+3。
但是我们该如何找出这些互斥特征组合呢?尝试每种组合,是 NP 难问题,现有算力做不到。所以只能采用贪心算法找。具体过程如下:
- 遍历特征,先把第一个特征拿出来作为一个组合
- 第二个特征往这个组合里放,冲突比例小就放进去合并成一个特征,冲突比例大就单拿出来作为另一个组合
- 第三个特征继续往已有的组合里放,能放就放,不能放就单成一个新组合
- 以此类推对所有特征做同样的操作。
对于这里的特征遍历,作者给出了两种遍历顺序,一种是根据互斥性建图,按节点度的降序顺序遍历;另一种是统计特征非零值的个数,按非零值个数的降序顺序遍历。源码里面弱化了排序的作用,有兴趣可以阅读原文和源码。
作者在五个数据集上进行了测试,如下表,表中数值为训练单棵决策树需要的秒数,这里只需要关注红框中的两列,其中 lgb_baseline 这列是使用了普通稀疏优化的 LightGBM 方法,EFB_only 是使用了 EFB 的 LightGBM 方法,EFB 让速度提升了 8 倍左右。
速度提升主要来源于两点:
- 普通的稀疏优化要保存非零值表,用了互斥特征捆绑后,多个稀疏特征捆绑成稠密特征,不用非零值表,节省了内存和维护耗时;
- 在多个稀疏特征间依次遍历时,每次特征切换都存在缓存命中率低(cache miss)的问题,合为一个特征后,不用切换特征,也就没有缓存命中率低的问题了。
3. 决策树学习
决策树的学习过程分为两部分:
- 节点层面:寻找一个叶子节点的最优分裂点(特征的值)
- 树结构层面:选择让哪个叶子节点进行分裂(特征)
3.1 寻找连续特征最优分裂点
对于连续特征,可以用预排序方法计算增益,但每个分裂点都要尝试,计算增益的次数会很多。为了降低算量,LightGBM 对连续特征做等距离离散化,也就是直方图统计,只在直方图每个箱子处计算一次增益。这样对于单个特征来说,计算增益的时间复杂度从不同特征值数量
O
(
n
d
i
s
t
i
n
c
t
_
v
a
l
u
e
)
O(n_{distinct\_value})
O(ndistinct_value) 降低到直方图箱数量
O
(
n
b
i
n
)
O(n_{bin})
O(nbin),箱数量会控制在 256 以下。因为
n
d
i
s
t
i
n
c
t
_
v
a
l
u
e
>
>
n
b
i
n
n_{distinct\_value}>>n_{bin}
ndistinct_value>>nbin ,所以速度提升会很明显。下图对比了预排序和直方图这两种方法:
采用直方图算法,除了速度上的提升,内存消耗也会降低。
- 对于预排序算法,每个样本的每个特征要保存一个 32 位浮点数的特征值,和一个指向样本的有序索引,一个索引也占 32 位;
- 而对于直方图算法,每个样本的每个特征只要保存一个 bin 位置即可,因为 n b i n n_{bin} nbin 会限制在 256 以内,所以 8 位整数就够。因此,直方图内存占用能够降低到预排序的 1 / 8 1/8 1/8。
直方图算法计算增益的位置少了,相比于预排序算法,可能会错过最佳分裂位置。
- 作者说这样其实也避免了过拟合,能够提高泛化能力,同时这点误差能够在梯度提升中被消除。
除此之外,LightGBM 在节点分裂时还采用了直方图做差加速。
- 对于选中的分裂特征,它的直方图在分裂点一刀切开就好了,但对于没被选中的特征,还要按照选中特征的分裂规则,重新构建左、右节点的子直方图。
这里就可以用直方图做差加速的方法,加速这一过程。当父节点分裂时,它的直方图是已知的,只要求出一个叶子节点的直方图,另一个叶子节点的就可以做差得到,减少了算量。这个过程还可以继续优化,在求叶子节点直方图的时候,可以选择样本少的叶子,样本大的叶子通过做差来求,这样进一步缩小了计算量。直方图做差加速能让耗时降低到原先的
1
/
2
1/2
1/2。
3.2 寻找类别特征最优分裂点
对于类别特征,一般是 One-Hot 编码,然后输入到决策树里。这样决策树在学习节点分裂时,是一种 one-vs-rest 模式,每次只能根据一个类别做分类,如下图。这种模式效率比较低,而且不利于决策树学习。
- LightGBM 对此进行了优化,采用 many-vs-many 模式分裂节点,如下图。
LightGBM 基于这篇文章《On Grouping for Maximum Homogeneity》,对类别特征按照每类的
G
H
=
∑
g
r
a
d
i
e
n
t
h
e
s
s
i
a
n
\frac{G}{H} = \frac{\sum gradient}{hessian}
HG=hessian∑gradient进行排序,然后按照这个顺序构造直方图,寻找最优分裂点。
- 这里有一个机器学习常识问题:为什么连续特征可以直接构建直方图,但类别特征要按照
G
H
\frac{G}{H}
HG 的顺序构建直方图,而不能按照特征值顺序构建?
- 因为连续特征中的数值具有大小关系,但类别特征中数值没有大小关系,只是代表某类,比如橘子和苹果这两类,它们不分伯仲。而基于直方图的节点分裂,要求特征中数值具有大小关系,所以类别特征要按 G H \frac{G}{H} HG 排个序,引入大小关系,之后再构建直方图。
3.3 按叶子生长策略学习树结构
树结构的生长有两种方式,如下图:
- 一种是大多数 GBDT 算法使用的按层生长策略;
- 另一种是 LightGBM 使用的按叶子生长策略。
- 对于按层生长,一层的节点囊括了所有训练数据,只要遍历一次全部数据,就可以分裂这一层的所有节点,简单方便。
- 然而这种生长方式带来了很多不必要的分裂,同一层中有些节点分裂带来的增益很小,这种节点应该避免分裂,减小计算开销。
- LightGBM 采用 按叶子生长 策略,来优化这个问题。具体规则是:
- 在每次分裂时,选择能够带来最大增益的叶子进行分裂。
- 在同等分裂次数的情况下,显然按叶子生长能够把损失函数降低更多。
4. 多机并行优化
一台机器不够用,那就几台机器一起跑。多机并行存在通信成本问题,机器之间发送的数据信息不能太多,否则会产生大量的额外开销。
之前的并行方法主要有两种:1)特征并行;2)数据并行。他们都是针对寻找最优分裂点这个过程,进行并行计算,各有缺点。
LightGBM 在数据并行的基础上进行了优化,提出选举并行。
下面分别介绍这三种方法。
4.1 特征并行
每个 worker 拥有全部样本的部分特征,它们各自输出自己的局部最优分裂点和增益。在把所有的结果汇总后,比较增益大小,选出全局最优分裂点(特征+阈值)。所有 worker 要根据全局最优进行节点分裂。
但是被选中的全局最优的特征只存储在一个 worker 里,其他 worker 没有这个特征,也就没法根据阈值判断哪个样本分到左叶子,哪个分到右叶子。如何解决?只能让存储了这个特征的 worker 把每个样本的划分结果告诉其他 worker。因为只有左、右两种划分可能,所以可以用一个 bit 存储单个样本的划分结果。这样的话通信量是 O ( n s a m p l e ) O(n_{sample}) O(nsample) ,非常大。
除了通信量比较大的问题外,仔细分析会发现有两个过程没法并行:
- 节点分裂:每个 worker 都要自行分裂一遍,不分裂自己就没有新节点,时间复杂度为
- 梯度计算:每个 worker 都要自行计算一遍梯度,不计算自己就没有,时间复杂度为
所以特征并行还有很大的优化空间。
4.1 数据并行
每个 worker 拥有一部分数据的全部特征,它们输出各自的局部直方图,然后汇总成全局直方图,在全局直方图上找出最优分裂点。
数据并行没有特征并行的那些问题,但他的缺点也很明显。它要发送全部的直方图,通信代价是
O
(
n
b
i
n
×
n
f
e
a
t
u
r
e
)
O(n_{bin} \times n_{feature})
O(nbin×nfeature),当特征数量到成百上千万时,这个通信代价没办法接受。
4.3 选举并行
因此,LightGBM 没有用这两种方法,而是采用了选举并行,这是一种在数据并行基础上改进的算法,是 LightGBM 作者在另一篇文章中提出的。
-
当特征数量很大时,数据并行会有巨大的通信代价,但是如果能够降低需要通信的特征数量,数据并行将是一个非常好的方法。选举并行就是基于这种想法设计的,具体方法如下:
- 让每个 worker 根据增益选出 k 个最有潜力竞争全局最优的特征,叫做局部最优特征
- 把这些局部最优特征对应的增益和用来计算增益的数据量 n s a m p l e n_{sample} nsample 进行汇总
- 考虑到样本少的增益不可靠,所以把 n s a m p l e m a x ( n s a m p l e ) \frac{n_{sample}}{max(n_{sample})} max(nsample)nsample 作为权重,对增益进行加权
- 不同 worker 可能选出了相同的增益,这种情况直接把它们的加权增益加一起就好
- 根据加权增益排序,再一次选出 k 个最有潜力竞争全局最优的特征,叫做全局最优特征
- 各个 worker 只发送 k 个全局最优特征直方图,汇总后找出最优分裂点
因为每个 worker 只发送 k 个直方图,所以选举并行的通信量是 O ( n b i n × k ) O(n_{bin} \times k) O(nbin×k),通过调整 k k k ,可以控制通信量的大小,极大地降低通信耗时。LightGBM 的并行速度接近线性增长。
作者选取了排序学习和点击率预测两个任务,用来对以上三种并行方法进行耗时测试,单位为小时,结果如下表。选举并行耗时最短。
结合任务数据集分析下结果,数据集相关信息如下表。排序学习用的数据集样本量偏少,特征偏多,所以特征并行耗时会比数据并行少很多;而点击率预测用的数据集样本数量多,特征偏少,所以数据并行耗时比特征并行耗时少很多。选举并行不讲武德,两个任务耗时都最短,而且速度接近线性增长。
LightGBM 在梯度提升这块儿,使用的方法和 XGBoost 一致,也是带正则项的二阶泰勒展开求解方式。并且在融合新模型的时候也采取了缩减(shrinkage)技巧。整体来看,LightGBM 的改进体现在速度更快、内存占用更低这两方面,是一个很有潜力的算法,对于后续工作有很大的借鉴意义。
参考
【1】https://zhuanlan.zhihu.com/p/366952043
【2】梯度提升决策树(GBDT)并行学习算法研究,柯国霖 https://d.wanfangdata.com.cn/thesis/Y3025839
【3】A Communication-Efficient Parallel Algorithm for Decision Tree https://papers.nips.cc/paper/2016/file/10a5ab2db37feedfdeaab192ead4ac0e-Paper.pdf
【4】LightGBM: A Highly Efficient Gradient Boosting Decision Tree https://papers.nips.cc/paper/2017/file/6449f44a102fde848669bdd9eb6b76fa-Paper.pdf