【三部曲03】从XGBoost到LightGBM

参考文献引用来源:

1.lightgbm论文翻译
2.lightgbm论文翻译解读
3.LightGBM——提升机器算法(图解+理论+安装方法+python代码)
4.论文原文下载


Question1. LightGBM提出的原因或者说背景是什么?

概括:面对稀疏、大数据场景,计算方式过于耗时

我们知道在LightGBM出现之前,已经有了例如 XGBoost 这样的优化很细致的工程实现。但是尽管在这些实现中已经采用了许多工程优化,当面对维度高,数据量大的问题时,其特征的效率和可扩展性仍然不尽人意。其中一个主要原因是对于每个特征,他们需要遍历所有的数据实例来估计所有可能的分割点的信息增益,这非常耗时。


Question2. 那么LightGBM是怎么针对性解决这一问题的?

LightGBM提出了两种新颖的技术:

1.基于梯度的单面采样(GOSS)

使用GOSS排除了很大比例的小梯度数据实例,只用剩下的来估计信息收益。
文中证明,由于具有较大梯度的数据实例发挥作用在信息获取计算中起更重要的作用,GOSS可以获得用更小的数据量对信息增益进行相当准确的估计。

尽管GBDT中的数据实例没有自具权重,但我们注意到具有不同梯度的数据实例在计算信息增益时扮演不同的角色。 具体而言,根据信息增益的定义,具有较大梯度的那些实例(即训练不足的实例)将对信息增益做出更多贡献。 因此,在对数据实例进行下采样时,为了保持信息增益估计的准确性,我们应该更好地保留那些具有较大梯度(例如,大于预先定义的阈值或者最高百分位数)的实例,并且只能随机地删除这些具有较小梯度值的实例。 我们证明,这种处理可以导致比均匀随机采样更准确的增益估计,具有相同的目标采样率,特别是当信息增益值的范围较大时。

2.互补特征压缩(EFB)

借助EFB,可以将相互排斥的特征压缩在一起(即它们很少同时取非零值),以减少特征的数量。
文中证明这一发现互补特征的最佳匹配是NP难度,但是却可以与贪婪算法一样可以达到相当好的近似比率(因而可以有效地减少许多不影响分割点确定的准确性)。

通常在实际应用中,虽然有大量的特征,但特征空间相当稀疏,这为我们设计几乎无损的方法来减少有效特征的数量提供了可能性。 特别地,在稀疏特征空间中,许多特征是(几乎)排他性的,即它们很少同时取非零值。 独热编码的特征就是一个典型示例。 我们可以安全地压缩这些独特特征。 为此,我们设计了一种有效的算法,通过将最优压缩问题简化为图着色问题(通过将特征作为顶点,并且如果两个特征不相互排斥,则为每两个特征添加边),然后用贪心算法 恒定近似比。


Question3. 这两个技术是通过怎样的分析得出的?

从发展过程来看,我们知道:GBDT的主要成本在于学习决策树,学习决策树中最耗时的部分是找出最佳的分割点。

阶段1: 找到分割点的最流行的算法之一是预先排序的算法。该算法枚举了预先排序的特征值上所有可能的分割点。 这个算法很简单,可以找到最优的分割点,但是它在训练速度和内存消耗方面都是不够的。

阶段2: 另一种流行的算法是基于直方图的算法,比如XGBoost。这类算法不是在已排序的特征值上找到分割点,而是基于直方图的算法将连续的特征值抽象成离散的区域,并使用这些区域在训练过程中构建特征直方图。

阶段3: 由于基于直方图的算法在内存消耗和训练速度方面都更加高效,因此我们将在其基础上开展工作。

再具体分析:基于直方图的算法根据特征直方图找出最佳分割点。 它用于构建直方图的O(#data×#特征)和用于分割点的O(#bin×#特征)。由于 #bin 通常比 #data 小得多,因此直方图构建将主导计算复杂性。如果我们能够减少#data或 #feature,我们将能够大幅加速GBDT的训练。

上面这一段针对计算量的具体分析,反映出两条针对直方图构建的优化思路:

①合理减少样本的数目;
②合理减少特征的维度;

之前的工作对这两个方向都有所尝试:比如通过下采样减少样本的数目,以及通过PCA等方法进行特征降维,但是这些方法都基于“特征包含重要冗余”这一假设,因此都不是很适用。

考虑到实际场景中,大规模数据集都是非常稀疏的。采用预排序的GBDT算法可以通过忽略具有零值的特征来降低训练成本;但是采用直方图的GBDT算法却没有有效的稀疏优化解决方案,原因在于基于直方图的GBDT算法无论特征值是否为0,都需要为每一个数据实例检索特征仓值。

这启发我们,基于直方图的GBDT算法,应当想办法有效利用数据的稀疏性,对算法加以改进,因此本文从减少样本数目和降低特征维度这两条思路出发,提出了GOSS和EFB。


Question4. GOSS和EFB的具体原理

1.基于梯度的单面采样(Gradient-based One-Side Sampling, GOSS)

我们知道,在AdaBoost中,样本权重是数据实例重要性的良好指标。 但是在GBDT中,不存在本地样本权重,因此针对AdaBoost提出的抽样方法不能直接应用。
幸运的是,我们注意到GBDT中每个数据实例的梯度为我们提供了有用的数据采样信息。也就是说,如果一个实例与一个小梯度相关联,则此实例的训练错误很小,并且它已经受过良好训练。
一个简单的想法是放弃那些具有小梯度的数据实例。但是这样做会改变数据分布以及损害学习模型的准确性。为了避免这个问题,本文提出了一种叫做基于梯度的单面采样(GOSS)的新方法。
在这里插入图片描述
算法思路:
GOSS保留所有具有大梯度的实例,并对具有小梯度的实例执行随机采样。
为了补偿对数据分布的影响,在计算信息增益时,GOSS为具有小梯度的数据实例引入了一个常数乘数。

算法具体步骤:
step1. GOSS首先根据梯度的绝对值对数据实例进行排序,并选择最高的a×100%实例;
step2. 然后从其余数据中随机抽样b×100%的实例;
step3. 之后,当计算信息增益时,GOSS以小的梯度以恒定的1-a/b放大采样数据;
通过这样做,我们将更多的重点放在训练有素的实例上,而不用多次改变原始数据分布。

附:
GOSS的做法优于随机采样的结果,当然,随机采样也可以视为GOSS在a=0时的特例;

GOSS的潜在好处在于:采样将会增加基学习器的差异性,这会潜在地提升算法的性能;

2.互补特征压缩(Exclusive Feature Bundling, EFB)

动机:(实际上就是特征的合并)
在实际场景中,高维数据通常是非常稀疏的。特征空间的稀疏性为我们提供了可能性,来设计几乎无损的方法来减少特征的数量。通过观察可知,特别是在稀疏特征空间中,许多特征是相互排斥的,即它们几乎从不同时取非零值。我们可以安全地将专有特征捆绑到一个特征(我们称之为专用特征包)。通过精心设计的特征扫描算法,我们可以从特征捆绑中构建与单个特征相同的特征直方图。这样,直方图构建的复杂度从O(#data×#feature)改为O(#data×#bundle),而 #bundle << #feature。那么我们可以在不损害准确性的情况下显着加快GBDT的培训速度。

那么问题来了:

【1】怎么确定哪些特征应该捆绑在一起?
【2】如何构建捆绑?

复杂度分析:通过将图染色问题推广到我们的问题,可以得出找到最优捆绑策略是NP难的。这意味着在多项式时间内是无法找到精确解的。

问题1

那么为了找到一个好的近似算法,我们首先将最优捆绑问题归结为图染色问题。我们将特征视为图中结点,并在两个非互斥的结点间添加连边,这样我们就可以使用贪婪算法,通过求解图染色问题,进而获得一个相当好的效果。此外,我们注意到通常有很多特征,虽然不是100%互斥,但也很少同时使用非零值。如果我们的算法可以允许一小部分冲突,我们可以得到更少数量的特征捆绑并进一步提高计算效率。通过简单的计算,随机污染一小部分特征值将至多影响训练的准确性O([(1-γ)n] -2/3),其中 γ 是每个捆绑包中的最大冲突。所以如果我们选择一个相对较小的 γ ,我们将能够在精度和效率之间取得很好的平衡。
在这里插入图片描述
基于以上讨论,我们设计了一个特征捆绑算法,如算法3所示:
step1. 首先,我们构造一个加权边的图,其权重对应于特征之间的总冲突;
step2. 其次,我们基于图中特征节点度数的降序对特征进行排序;
step3. 最后,我们检查有序列表中的每个特征,并将其分配给一个具有小冲突(由γ控制)的现有捆绑包,或者创建一个新的捆绑包。

算法3的时间复杂性是O(#特征2),训练前仅处理一次。当特征数量不是很大时,这种复杂性是可以接受的,但是如果有数百万个特征可能仍会受到影响。
为了进一步提高效率,我们提出了一个更有效的排序策略,不需要构建图表:按非零值计数排序,这类似于按节点度数排序,因为更多的非零值通常会导致更高的冲突概率。因为我们只改变算法3中的排序策略,新算法的细节被省略以避免重复。

问题2

对于第二个问题,我们需要一种合并同一捆绑中的特征的好方法,以减少相应的训练复杂度。
关键是要确保可以从特征包中识别出原始特征的值。

由于基于直方图的算法存储离散仓而不是特征的连续值,我们可以通过让唯一的特征位于不同仓中,来构建特征捆绑。 这可以通过向特征的原始值添加偏移来完成。
例如,假设我们在一个特征包中有两个特征。最初,特征A从 [0,10) 中取值,特征B从 [0,20) 中取值。对特征B的值进行一个加10的偏移,以使得精化特征取 [10,30) 中的值。之后,合并特征A和B并使用范围为[0,30]的特征捆绑包来替换原始特征A和B是安全的。详细的算法在算法4中显示:

EFB算法可以将许多独有的特征进行捆绑,以得到数目少得多的密集特征,这可以有效地避免对零特征值进行不必要的计算。
在这里插入图片描述

额外方法:

实际上,我们也可以通过使用表来记录每个特征实例的非零值的数目,通过基于这个表来优化基本的基于直方图的算法来忽略零特征值。通过扫描此表中的数据,特征的直方图构建成本将从O(#data)降为O(#non_zero_data)。

但是这种方法需要额外的记忆和计算费用来维护整个树形成过程中的特征表。

我们在LightGBM中实现了这种优化作为基本功能。 请注意,此优化并不会与EFB冲突,因为我们仍然可以在捆绑稀疏时使用它。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值