久前微软 DMTK (分布式机器学习工具包)团队在 GitHub 上开源了性能超越其他 boosting 工具的 LightGBM

知乎上有近千人关注“如何看待微软开源的 LightGBM?”问题,被评价为“速度惊人”,“非常有启发”,“支持分布式”,“代码清晰易懂”,“占用内存小”等。

GBDT :

GBDT (Gradient Boosting Decision Tree) 是机器学习中一个长盛不衰的模型,其主要思想是利用弱分类器(决策树)迭代训练以得到最优模型,该模型具有训练效果好、不易过拟合等优点。GBDT 在工业界应用广泛,通常被用于点击率预测,搜索排序等任务。GBDT 也是各种数据挖掘竞赛的致命武器,据统计 Kaggle 上的比赛有一半以上的冠军方案都是基于 GBDT。

LightGBM (Light Gradient Boosting Machine)(请点击 https://github.com/Microsoft/LightGBM)是一个实现 GBDT 算法的框架,支持高效率的并行训练,并且具有以下优点:

更快的训练速度

更低的内存消耗

更好的准确率

分布式支持,可以快速处理海量数据

中文参考:http://lightgbm.apachecn.org/cn/latest/Quick-Start.html

从 LightGBM 的 GitHub 主页上可以直接看到实验结果:

从下图实验数据可以看出,在 Higgs 数据集上 LightGBM 比 XGBoost 快将近 10 倍,内存占用率大约为 XGBoost 的1/6,并且准确率也有提升。在其他数据集上也可以观察到相似的结论。

训练速度方面

内存消耗方面

准确率方面

(我们只和 xgboost 进行对比,因为 xgboost 号称比其他的 boosting 工具都要好,从他们的实验结果来看也是如此。) XGBoost 与其他方法在 Higgs-1M 数据的比较:

XGBoost 与其他方法在 Yahoo LTR 数据的比较:

看完这些惊人的实验结果以后,对下面两个问题产生了疑惑:

Xgboost 已经十分完美了,为什么还要追求速度更快、内存使用更小的模型?

对 GBDT 算法进行改进和提升的技术细节是什么?

提出 LightGBM 的动机

常用的机器学习算法,例如神经网络等算法,都可以以 mini-batch 的方式训练,训练数据的大小不会受到内存限制。

而 GBDT 在每一次迭代的时候,都需要遍历整个训练数据多次。如果把整个训练数据装进内存则会限制训练数据的大小;如果不装进内存,反复地读写训练数据又会消耗非常大的时间。尤其面对工业级海量的数据,普通的 GBDT 算法是不能满足其需求的。

LightGBM 提出的主要原因就是为了解决 GBDT 在海量数据遇到的问题,让 GBDT 可以更好更快地用于工业实践。

改进的细节

1. Xgboost 是如何工作的?

目前已有的 GBDT 工具基本都是基于预排序的方法(pre-sorted)的决策树算法(如 xgboost)。这种构建决策树的算法基本思想是:

首先,对所有特征都按照特征的数值进行预排序。

其次,在遍历分割点的时候用O(#data)的代价找到一个特征上的最好分割点。

最后,找到一个特征的分割点后,将数据分裂成左右子节点。

这样的预排序算法的优点是能精确地找到分割点。

缺点也很明显:

首先,空间消耗大。这样的算法需要保存数据的特征值,还保存了特征排序的结果(例如排序后的索引,为了后续快速的计算分割点),这里需要消耗训练数据两倍的内存。

其次,时间上也有较大的开销,在遍历每一个分割点的时候,都需要进行分裂增益的计算,消耗的代价大。

最后,对 cache 优化不友好。在预排序后,特征对梯度的访问是一种随机访问,并且不同的特征访问的顺序不一样,无法对 cache 进行优化。同时,在每一层长树的时候,需要随机访问一个行索引到叶子索引的数组,并且不同特征访问的顺序也不一样,也会造成较大的 cache miss。

2. LightGBM 在哪些地方进行了优化?

基于 Histogram 的决策树算法带深度限制的 Leaf-wise 的叶子生长策略直方图做差加速直接支持类别特征(Categorical Feature) Cache 命中率优化基于直方图的稀疏特征优化多线程优化下面主要介绍 Histogram 算法、带深度限制的 Leaf-wise 的叶子生长策略和直方图做差加速。

Histogram 算法

直方图算法的基本思想是先把连续的浮点特征值离散化成k个整数,同时构造一个宽度为k的直方图。在遍历数据的时候,根据离散化后的值作为索引在直方图中累积统计量,当遍历一次数据后,直方图累积了需要的统计量,然后根据直方图的离散值,遍历寻找最优的分割点。

使用直方图算法有很多优点。首先,最明显就是内存消耗的降低,直方图算法不仅不需要额外存储预排序的结果,而且可以只保存特征离散化后的值,而这个值一般用 8 位整型存储就足够了,内存消耗可以降低为原来的1/8。

然后在计算上的代价也大幅降低,预排序算法每遍历一个特征值就需要计算一次分裂的增益,而直方图算法只需要计算k次(k可以认为是常数),时间复杂度从O(#data*#feature)优化到O(k*#features)。

当然,Histogram 算法并不是完美的。由于特征被离散化后,找到的并不是很精确的分割点,所以会对结果产生影响。但在不同的数据集上的结果表明,离散化的分割点对最终的精度影响并不是很大,甚至有时候会更好一点。原因是决策树本来就是弱模型,分割点是不是精确并不是太重要;较粗的分割点也有正则化的效果,可以有效地防止过拟合;即使单棵树的训练误差比精确分割的算法稍大,但在梯度提升(Gradient Boosting)的框架下没有太大的影响。

带深度限制的 Leaf-wise 的叶子生长策略

在 Histogram 算法之上,LightGBM 进行进一步的优化。首先它抛弃了大多数 GBDT 工具使用的按层生长 (level-wise) 的决策树生长策略,而使用了带有深度限制的按叶子生长 (leaf-wise) 算法。Level-wise 过一次数据可以同时分裂同一层的叶子,容易进行多线程优化,也好控制模型复杂度,不容易过拟合。但实际上 Level-wise 是一种低效的算法,因为它不加区分的对待同一层的叶子,带来了很多没必要的开销,因为实际上很多叶子的分裂增益较低,没必要进行搜索和分裂。

Leaf-wise 则是一种更为高效的策略,每次从当前所有叶子中,找到分裂增益最大的一个叶子,然后分裂,如此循环。因此同 Level-wise 相比,在分裂次数相同的情况下,Leaf-wise 可以降低更多的误差,得到更好的精度。Leaf-wise 的缺点是可能会长出比较深的决策树,产生过拟合。因此 LightGBM 在 Leaf-wise 之上增加了一个最大深度的限制,在保证高效率的同时防止过拟合。

直方图差加速

LightGBM 另一个优化是 Histogram(直方图)做差加速。一个容易观察到的现象:一个叶子的直方图可以由它的父亲节点的直方图与它兄弟的直方图做差得到。通常构造直方图,需要遍历该叶子上的所有数据,但直方图做差仅需遍历直方图的k个桶。利用这个方法,LightGBM 可以在构造一个叶子的直方图后,可以用非常微小的代价得到它兄弟叶子的直方图,在速度上可以提升一倍。

直接支持类别特征

实际上大多数机器学习工具都无法直接支持类别特征,一般需要把类别特征,转化到多维的0/1 特征,降低了空间和时间的效率。而类别特征的使用是在实践中很常用的。基于这个考虑,LightGBM 优化了对类别特征的支持,可以直接输入类别特征,不需要额外的0/1 展开。并在决策树算法上增加了类别特征的决策规则。在 Expo 数据集上的实验,相比0/1 展开的方法,训练速度可以加速 8 倍,并且精度一致。据我们所知,LightGBM 是第一个直接支持类别特征的 GBDT 工具。

LightGBM 的单机版本还有很多其他细节上的优化,比如 cache 访问优化,多线程优化,稀疏特征优化等等,更多的细节可以查阅 Github Wiki (https://github.com/Microsoft/LightGBM/wiki)上的文档说明。优化汇总对比表:

在探寻了 LightGBM 的优化之后,发现 LightGBM 还具有支持高效并行的优点。LightGBM 原生支持并行学习,目前支持特征并行和数据并行的两种。特征并行的主要思想是在不同机器在不同的特征集合上分别寻找最优的分割点,然后在机器间同步最优的分割点。数据并行则是让不同的机器先在本地构造直方图,然后进行全局的合并,最后在合并的直方图上面寻找最优分割点。LightGBM 针对这两种并行方法都做了优化,在特征并行算法中,通过在本地保存全部数据避免对数据切分结果的通信;在数据并行中使用分散规约 (Reduce scatter) 把直方图合并的任务分摊到不同的机器,降低通信和计算,并利用直方图做差,进一步减少了一半的通信量。基于投票的数据并行则进一步优化数据并行中的通信代价,使通信代价变成常数级别。在数据量很大的时候,使用投票并行可以得到非常好的加速效果。更具体的内容可以看我们在 NIPS2016 的文章[1]。

LightGBM 的工作还在持续进行,近期将会增加更多的新功能,如:R, Julia 等语言支持(目前已原生支持 python,R语言正在开发中)

更多平台(如 Hadoop 和 Spark)的支持

GPU 加速1234

此外,LightGBM 开发人员呼吁大家在 Github 上对 LightGBM 贡献自己的代码和建议,一起让 LightGBM 变得更好。DMTK 也会继续开源更多优秀的机器学习工具,敬请期待。

lightGBM调参

(1)num_leaves

LightGBM使用的是leaf-wise的算法,因此在调节树的复杂程度时,使用的是num_leaves而不是max_depth。

大致换算关系:num_leaves = 2^(max_depth)

(2)样本分布非平衡数据集:可以param[‘is_unbalance’]=’true’

(3)Bagging参数:bagging_fraction+bagging_freq(必须同时设置)、feature_fraction

(4)min_data_in_leaf、min_sum_hessian_in_leaf// 01. train set and test settrain_data = lgb.Dataset(dtrain[predictors],label=dtrain[target],feature_name=list(dtrain[predictors].columns), categorical_feature=dummies)

test_data = lgb.Dataset(dtest[predictors],label=dtest[target],feature_name=list(dtest[predictors].columns), categorical_feature=dummies)// 02. parametersparam = {    'max_depth':6,    'num_leaves':64,    'learning_rate':0.03,    'scale_pos_weight':1,    'num_threads':40,    'objective':'binary',    'bagging_fraction':0.7,    'bagging_freq':1,    'min_sum_hessian_in_leaf':100}param['is_unbalance']='true'param['metric'] = 'auc'// 03. cv and trainbst=lgb.cv(param,train_data, num_boost_round=1000, nfold=3, early_stopping_rounds=30)

estimators = lgb.train(param,train_data,num_boost_round=len(bst['auc-mean']))// 04. test predictypred = estimators.predict(dtest[predictors])12345678910111213141516171819202122232425262728

[1] Meng, Qi, Guolin Ke, Taifeng Wang, Wei Chen, Qiwei Ye, Zhi-Ming Ma, and Tieyan Liu. “A Communication-Efficient Parallel Algorithm for Decision Tree.” In Advances In Neural Information Processing Systems, pp. 1271-1279. 2016.

参数参考:http://lightgbm.readthedocs.io/en/latest/Python-API.html

中文文档:http://lightgbm.apachecn.org/cn/latest/index.html

参考资料:文章中众多连接,算法很深,欢迎留言讨论!

lightgbm java_开源|LightGBM基本原理,以及调用形式相关推荐

  1. Swift2.0语言教程之函数嵌套调用形式

    Swift2.0语言教程之函数嵌套调用形式 Swift2.0语言函数嵌套调用形式 在Swift中,在函数中还可以调用函数,从而形成嵌套调用.嵌套调用的形式往往有两种:一种是在一个函数中调用其他函数:另 ...

  2. c语言函数fread的调用形式,C语言的问题,fread和fgets的区别是什么?

    fgets函数用来从文件中读入字符串.fgets函数的调用形式如下:fgets(str,n,fp):此处,fp是文件指针:str是存放在字符串的起始地址:n是一个int类型变量.函数的功能是从fp所指 ...

  3. c语言fwrite函数结构体,fwrite函数的一般调用形式是什么?

    fwrite函数的一般调用形式是"fwrite(buffer,size,count,fp);":其中,buffer是准备输出的数据块的起始地址,size是每个数据块的字节数,cou ...

  4. lightgbm java_如何在C++程序中调用lightgbm (How to use lightgbm in C++ program)

    本文作者为tieying zhang,有任何问题请联系zhangtiey@gmail.com Lightgbm以轻量著称,所以在实际的C++程序中,常常需要使用.但是官方文档并没有介绍如何在C++中调 ...

  5. 开源|LightGBM:三天内收获GitHub 1000+ 星

    原创 2017-01-05 LightGBM 微软研究院AI头条 [导读]不久前微软DMTK(分布式机器学习工具包)团队在GitHub上开源了性能超越其他boosting工具的LightGBM,在三天 ...

  6. python scikit learn 关闭开源_慕课|Python调用scikit-learn实现机器学习(一)

    一.机器学习介绍及其原理 1.什么是人工智能? 机器对人的思维信息过程的模拟,让它能相认一样思考. a.输入 b.处理 c.输出 根据输入信息进行模型建构.权重更新,实现最终优化. 特点:信息处理.自 ...

  7. lightGBM中的lightgbm.train

    文章目录 1. lightgbm.train 2.返回 lightgbm.Booster methods 代码 1. lightgbm.train lightgbm.train(params, tra ...

  8. Github系列之二:开源 一行代码实现多形式多动画的推送小红点WZLBadge(iOS)

    更新日志 V1.2 2015.09.25 1.UITabBarItem badge is supproted; 2.Enable change badge properties when badge ...

  9. 文科思维Java_开源之Processing:这好玩的编程语言是为文科生艺术家准备的

    说起编程语言,我们很多时候第一反应就是很难,都是理工科计算机相关行业的人才学的,都是为理科生掉头发准备的.的确,计算机的严谨,注定要求开发应用的人有缜密的理工科的理性逻辑思维,然而一人客从另一方面讲, ...

最新文章

  1. sudo apt-get 和dpkg命令大全
  2. oracle坏块 戴明明,云和恩墨:基于PCIE 闪存卡的 Oracle 数据
  3. kaggle(03)-自行车租赁预测问题(基础版)
  4. oracle11g arm,想知道ARM11架构?这篇介绍告诉你
  5. MySQL DQL语言的笔记
  6. c语言中怎样变大输出的字符串,C语言。要输入一个超大数比如 111111111111111111111111111111111111111 怎样用字符串数组求各位的和呢?...
  7. C++ Primer 第五版 第6章 6.1——函数及函数定义及调用习题答案
  8. inno setup 中文乱码问题_解决Inno Setup制作中文安装包在非中文系统上显示乱码的问题...
  9. 在QtCreator中手动添加signal和slot
  10. vnc 序列号在哪输入_VNC Viewer Plus 1.2.3 注册机
  11. 5万成员丨CSDN 大数据领域网红社区!
  12. 光子晶体matlab,Matlab光子晶体程序讨论
  13. hive自定义函数过滤emoj表情符
  14. 计算机桌面有什么,电脑桌面是什么
  15. Gooowild隐私政策
  16. 【软考软件评测师】2013综合知识历年真题
  17. arm芯片 安装linux,linux操作系统 arm
  18. 纽约大学深度学习PyTorch课程笔记(自用)Week3
  19. linux运行不存在的命令报错
  20. 企业AAA信用等级认证 发展一路“亮红灯

热门文章

  1. realme取得6000万销量,小米或已失去国产手机老大位置
  2. 论技术领域学好英文的重要性
  3. 【java】学生成绩分级ABCDE(起点闭关计划)
  4. CMS 中 三色标记概述
  5. java连不上sql表,Java SQL“错误:关系”表_Name“不存在”
  6. 高完整性系统 (2):Requirement 与 Design 阶段的风险控制——Hazards, HAZOP, Fault Tree
  7. 软件下载站点提交的一点经验.
  8. PyCharm 出现 Shadows name ‘xxx‘ from outer scope 提示
  9. Redis常见数据结构以及使用场景(微博)分析
  10. 如何在Word中划横线