美文网首页
论文笔记 | NIPS2017 | LightGBM: A Hi

论文笔记 | NIPS2017 | LightGBM: A Hi

作者: ktulu7 | 来源:发表于2020-06-14 21:05 被阅读0次
    lightgbm-title.jpg

    论文地址:https://papers.nips.cc/paper/6907-lightgbm-a-highly-efficient-gradient-boosting-decision-tree

    官方代码:https://github.com/microsoft/LightGBM

    一 为什么读这篇

    搜索这边大量用到了lightGBM,最近做的实验也是基于lightGBM的,看完xgboost论文接着看这个,没毛病

    二 相关背景介绍

    出自微软,中了17年的NIPS,一作柯国霖没有xgboost的陈天奇那么有名,不过还是非常屌的,厦大的硕士,在微软工作的第一年就搞出了lightGBM,作者在硕士期间研究的就是GBDT,有很好的积累,网上有个硕士论文的前16页:《梯度提升决策树(GBDT)并行学习算法研究》https://core.ac.uk/download/pdf/84991871.pdf。截止阅读时这篇论文的引用次数为966,和xgboost还是有一定差距的。

    三 关键词及主要贡献

    关键词:gbdt,lightgbm

    1 比xgboost还要快

    四 详细解读

    0 摘要

    即使有XGBoost和pGBRT这样屌的系统,当特征维度很高,数据很大时仍然无法满足需求。一个主要原因就是对于每个特征,需要扫描所有的样本,从所有可能的分割点中预测信息增益,这一步非常耗时。为了解决这个问题,本文提出两个新技术:基于梯度的单边采样(Gradient-based One-Side Sampling GOSS)和独占特征绑定(Exclusive Feature Bundling EFB)。通过GOSS,可以排除掉很大一部分梯度较小的数据样本,只用剩下的样本来预测信息增益。通过EFB,将互斥特征绑定在一起,以此来减少特征的数量。本文将基于GOSS和EFB的GBDT实现算法称之为LightGBM。

    1 介绍

    传统的GBDT算法实现的计算复杂度与特征的数量和样本的数量是成比例的。因此当处理大数据时这种实现就非常耗时。很直接的一个想法就是减少样本数量和特征数量就行了,然而实践证明这并不容易。举个栗子,尚不清楚如何对GBDT进行数据采样,GBDT里压根没有样本权重。本文提出的两个新技术可以解这个问题。

    GOSS。虽然GBDT的样本中没有原生的权重,本文发现不同梯度的样本在计算信息增益时扮演的角色是不同的。特别是,根据信息增益的定义,那些有更大梯度的(例如训练不足的样本)样本将贡献更多的信息增益。因此,对数据进行下采样时,为了维持信息增益预估的准确性,应当保留有大梯度的(大于一定阈值或在top百分比中)那些样本,仅仅随机丢弃掉小梯度的样本。本文证明了这种方式比均匀随机采样有更准确的增益预估。

    EFB。现实应用中的特征空间都相当稀疏,这为设计几乎无损的方法来减少特征带来了可能。具体来说,在一个稀疏特征空间,许多特征几乎都是独占的,它们很少同时取非零值。例如one-hot特征。可以安全的将这种独占特征绑定在一起。为此,本文设计了一种有效的算法,将最优绑定问题转化为图着色问题(将特征视为点,如果两个特征非互斥就给它们增加边),通过一个带常数近似率的贪婪算法来解决它。

    2 预备阶段

    2.1 GBDT及其复杂度分析

    GBDT的主要代价在于学习决策树,最耗时的部分在于发现最优分割点。最流行的算法之一是用预排序算法来发现分割点。另一种流行的算法是基于直方图的算法,如算法1所示:

    lightgbm-alg1.jpg

    基于直方图的算法将连续特征变为离散化的桶,在训练时用这些桶来构建特征直方图。本文工作也是基于该方法。如算法1所示,基于直方图的算法通过特征直方图来找到最优分割点。构建直方图的复杂度为O(\# \text { data } \times \# \text { feature }),发现分割点的复杂度为O(\# \text { bin } \times \# \text { feature })。因为#bin通常远小于#data,因此计算复杂度上构建直方图占主导。如果我们能减少#data和#feature,实质上就能加速训练GBDT。

    2.2 相关工作

    Scikit-learn和gbm in R实现了预排序算法,pGBRT实现了基于直方图的算法。XGBoost两种都支持。

    基于预排序的GBDT算法可以通过忽略有零值的特征来减少训练代价(XGBoost)。然而,基于直方图的GBDT算法没有有效的稀疏优化方案。原因是对每个样本基于直方图的算法需要获取其特征分桶值,而不管它的特征值是否为0。当基于直方图算法的GBDT能够有效地利用这种稀疏属性,则是非常可取的。

    3 基于梯度的单边采样

    3.1 算法描述

    AdaBoost算法中,样本权重对于数据样本的重要性是个非常好的指标。然而在GBDT中,没有原生的样本权重。幸运的是,本文发现GBDT中的每条样本的梯度可以为数据采样提供有用的信息。也就是说,如果一个样本关联一个小梯度,则这条样本的训练误差也会很小,说明它已经是well-trained过的。一个直接的想法就是抛弃这些有小梯度的样本,然而,这样做会改变数据分布,而这又会造成学习模型准确率的损失。为了避免这个问题,本文提出GOSS。

    GOSS保留所有大梯度的样本,在小梯度样本上执行随机采样。为了补偿数据分布的影响,当计算信息增益时,GOSS对小梯度样本乘上一个常数。如算法2所示:

    lightgbm-alg2.jpg

    展开来讲,GOSS首先根据样本梯度的绝对值对样本进行排序,并选择百分之top a的样本。之后从剩下的数据中随机采样百分之b的样本。再之后,当计算信息增益时,给小梯度样本乘上常数\frac{1-a}{b}来放大影响。这样做以后,就可以在不改变原始数据分布很多的情况下聚焦于欠训练样本。

    3.2 理论分析

    GBDT使用决策树来学习从输入空间\mathcal{X}^{s}到梯度空间\mathcal{G}的函数。假设训练集\left\{x_{1}, \cdots, x_{n}\right\}是有n个独立同分布的样本。其中每个x_{i}是在特征空间\mathcal{X}^{s}中维度为s的向量。在每个梯度渐进的迭代中,模型损失函数输出的负梯度表示为\left\{g_{1}, \cdots, g_{n}\right\}。决策树模型用最有信息量的特征来分割每个节点。

    以下是硬核的理论分析部分。。

    4 独占特征绑定

    可以安全的把独占特征绑定为单一特征(称之为独占特征绑定)。通过仔细设计的特征扫描算法,可以从绑定的特征中构建同样的特征直方图。通过这种方式,直方图构建的复杂度从O(\# \text { data } \times \# \text { feature })降为O(\# \text { data } \times \# \text { bundle }),当#bundle远小于#feature时。

    有两个问题需要解决。第一个是选择哪些特征做绑定,第二个是如何构建绑定。

    理论4.1 将特征划分为最小数量的独占绑定的问题是NP-hard。

    证明:将图着色问题简化为本文的问题。

    对于第一个问题,可见算法3:

    lightgbm-alg3.jpg

    对于第二个问题,关键就是一个offset的概念,例如特征A的范围是[0, 10),特征B的范围是[0, 20),给B增加10个offset,则其新的范围是[10, 30),这样就把A和B合并在范围[0, 30],用于表示原始的特征A和B,详情可见算法4:

    lightgbm-alg4.jpg

    5 实验

    lightgbm-table1.jpg

    5.1 整体比较

    lightgbm-table2.jpg lightgbm-table3.jpg lightgbm-fig1.jpg

    5.2 GOSS分析

    lightgbm-table4.jpg

    5.3 EFB分析

    五 小结

    我草,这个论文好多重复的地方。一模一样的句子到处写。另外作者本人在知乎上回答的优化点和论文主要的创新点似乎不太一样。。

    素质四连

    要解决什么问题

    如何比xgb还要快

    用了什么方法解决

    基于直方图算法找分割点。

    数据采样

    特征缩减

    效果如何

    速度大幅增加的同时精读并未有很大损失

    还存在什么问题

    算法背后的模式和原理

    六 补充

    如何看待微软新开源的LightGBM? 知乎上这个问题有作者本人和陈天奇的回复。

    无痛看懂LightGBM原文

    相关文章

      网友评论

          本文标题:论文笔记 | NIPS2017 | LightGBM: A Hi

          本文链接:https://www.haomeiwen.com/subject/zlvfxktx.html