文章最前: 我是Octopus,这个名字来源于我的中文名–章鱼;我热爱编程、热爱算法、热爱开源。所有源码在我的个人github ;这博客是记录我学习的点点滴滴,如果您对 Python、Java、AI、算法有兴趣,可以关注我的动态,一起学习,共同进步。
论文地址:《LightGBM: A Highly Efficient Gradient Boosting Decision Tree》:https://proceedings.neurips.cc/paper_files/paper/2017/file/6449f44a102fde848669bdd9eb6b76fa-Paper.pdf
LightGBM算法速度
从 LightGBM 名字我们可以看出其是轻量级(Light)的梯度提升机(GBM),其相对 XGBoost 具有训练速度快、内存占用低的特点。下图分别显示了 XGBoost、XGBoost_hist(利用梯度直方图的 XGBoost) 和 LightGBM 三者之间针对不同数据集情况下的内存和训练时间的对比:
那么 LightGBM 到底如何做到更快的训练速度和更低的内存使用的呢?
我们刚刚分析了 XGBoost 的缺点,LightGBM 为了解决这些问题提出了以下几点解决方案:
- 单边梯度抽样算法;
- 直方图算法;
- 互斥特征捆绑算法;
- 基于最大深度的 Leaf-wise 的垂直生长算法;
- 类别特征最优分割;
- 特征并行和数据并行;
- 缓存优化。
2.1 单边梯度抽样算法
GBDT 算法的梯度大小可以反应样本的权重,梯度越小说明模型拟合的越好,单边梯度抽样算法(Gradient-based One-Side Sampling, GOSS)利用这一信息对样本进行抽样,减少了大量梯度小的样本,在接下来的计算锅中只需关注梯度高的样本,极大的减少了计算量。
GOSS 算法保留了梯度大的样本,并对梯度小的样本进行随机抽样,为了不改变样本的数据分布,在计算增益时为梯度小的样本引入一个常数进行平衡。具体算法如下所示:
我们可以看到 GOSS 事先基于梯度的绝对值对样本进行排序(无需保存排序后结果),然后拿到前 a% 的梯度大的样本,和剩下样本的 b%,在计算增益时,通过乘上