效率和内存上的提升

1) 在训练决策树计算切分点的增益时,xgboost采用预排序,即需要对每个样本的切分位置都要计算一遍,所以时间复杂度是O(#data)。

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

Histogram 算法的优缺点:

  1. Histogram算法并不是完美的。由于特征被离散化后,找到的并不是很精确的分割点,所以会对结果产生影响。但在实际的数据集上表明,离散化的分裂点对最终的精度影响并不大,甚至会好一些。原因在于decision tree本身就是一个弱学习器,采用Histogram算法会起到正则化的效果,有效地防止模型的过拟合。
  2. 时间上的开销由原来的O(#data * #features)降到O(k * #features)。由于离散化,#bin远小于#data,因此时间上有很大的提升。
  3. Histogram算法还可以进一步加速。一个叶子节点的Histogram可以直接由父节点的Histogram和兄弟节点的Histogram做差得到。一般情况下,构造Histogram需要遍历该叶子上的所有数据,通过该方法,只需要遍历Histogram的k个捅。速度提升了一倍。

这样再计算分裂点增益时只需要根据直方图切割位置计算即可,时间复杂度缩减为O(#bins),比如原始数据是100条,需要进行100次切割计算,如果分成10个直方图之后,只需要进行10次分割计算即可,时间效率上大大提高了。直方图算法是一种牺牲了一定的切分准确性而换取训练速度以及节省内存空间消耗的算法。(初始构造直方图是需要一次O(#data)的时间复杂度,不过这里只涉及到加和操作)

2)直方图做差进一步提高效率,计算某一节点的叶节点的直方图可以通过将该节点的直方图与另一子节点的直方图做差得到,所以每次分裂只需计算分裂后样本数较少的子节点的直方图然后通过做差的方式获得另一个子节点的直方图,进一步提高效率

3)节省内存

  • 将连续数据离散化为直方图的形式,对于数据量较小的情形可以使用小型的数据类型来保存训练数据
  • 不必像预排序一样保留额外的对特征值进行预排序的信息

稀疏特征优化

对稀疏特征构建直方图时的时间复杂度为O(2*#非零数据)

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

Level-wise过一次数据可以同时分裂同一层的叶子,容易进行多线程优化,也好控制模型复杂度,不容易过拟合。但实际上Level-wise是一种低效的算法,因为它不加区分的对待同一层的叶子,带来了很多没必要的开销,因为实际上很多叶子的分裂增益较低,没必要进行搜索和分裂。

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

直接支持类别特征

lightGBM可以直接用类别特征进行训练,不必预先进行独热编码,速度会提升不少,参数设置categorical_feature来指定数据中的类别特征列。

对于类别类型特征我们原始的做法是进行独热编码,但是这种做法对于基于树的模型而言不是很好,对于基数较大的类别特征,可能会生成非常不平衡的树并且需要一颗很深的树才能达到较好的准确率;比较好的做法是将类别特征划分为两个子集,直接划分方法众多(2^(k-1)-1),对于回归树而言有一种较高效的方法只需要O(klogk)的时间复杂度,基本思想是对类别按照与目标标签的相关性进行重排序,具体一点是对于保存了类别特征的直方图根据其累计值(sum_gradient/sum_hessian)重排序,在排序好的直方图上选取最佳切分位置。

特征并行减少通信传输代价

特征并行是为了将寻找决策树的最佳切分点这一过程并行化

  • 传统做法

    • 对数据列采样,即不同的机器上保留不同的特征子集
    • 各个机器上的worker根据所分配的特征子集寻找到局部的最优切分点(特征、阈值)
    • 互相通信来从局部最佳切分点里得到最佳切分点
    • 拥有最佳切分点的worker执行切分操作,然后将切分结果传送给其他的worker
    • 其他的worker根据接收到的数据来切分数据
    • 传统做法的缺点
      • 计算量太大,并没有提升切分的效率,时间复杂度为O(#data)(因为每个worker持有所有行,需要处理全部的记录),当数据量较大时特征并行并不能提升速度
      • 切分结果的通信代价,大约为O(#data/8)(若一个数据样本为1bit)
  • LightGBM的做法
    让每个机器保留整个完整的数据集(并不是经过列采样的数据),这样就不必在切分后传输切分结果数据,因为每个机器已经持有完整的数据集
    • 各个机器上的worker根据所分配的特征子集寻找到局部的最优切分点(特征、阈值)
    • 互相通信来从局部最佳切分点里得到最佳切分点
    • 执行最优切分操作

Notes:典型的空间换时间,差别就是减少了传输切分结果的步骤,节省了这里的通信消耗

数据并行

上述特征并行的方法并没有根本解决寻找切分点的计算效率问题,当记录数过大时需要考虑数据并行的方法

  • 传统做法

    • 行采样,对数据进行横向切分
    • worker使用分配到的局部数据构建局部的直方图
    • 合并局部直方图得到全局的直方图
    • 对全局直方图寻找最优切分点,然后进行切分
    • 缺点:通信代价过高,若使用point-to-point的通信算法,每个机器的通信代价时间复杂度为O(#machine*#feature*#bin),若使用collective通信算法则通信代价为O(2*#feature*#bin)
  • LightGBM的做法(依然是降低通信代价)
    • 不同于合并所有的局部直方图获得全局的直方图,LightGBM通过Reduce Scatter方法来合并不同worker的无交叉的不同特征的直方图,这样找到该直方图的局部最优切分点,最后同步到全局最优切分点
    • 基于直方图做差的方法,在通信的过程中可以只传输某一叶节点的直方图,而对于其邻居可通过做差的方式得到
    • 通信的时间复杂度为O(0.5*#feature*#bin)

LightGBM优势总结的更多相关文章

  1. LightGBM大战XGBoost,谁将夺得桂冠?

    引 言 如果你是一个机器学习社区的活跃成员,你一定知道 提升机器(Boosting Machine)以及它们的能力.提升机器从AdaBoost发展到目前最流行的XGBoost.XGBoost实际上已经 ...

  2. LightGBM总结

    一.LightGBM介绍 LightGBM是一个梯度Boosting框架,使用基于决策树的学习算法.它可以说是分布式的,高效的,有以下优势: 1)更快的训练效率 2)低内存使用 3)更高的准确率 4) ...

  3. Lightgbm 随笔

    lightGBM LightGBM 是一个梯度 boosting 框架,使用基于学习算法的决策树.它可以说是分布式的,高效的,有以下优势: 更快的训练效率 低内存使用 更高的准确率 支持并行化学习 可 ...

  4. LightGBM介绍及参数调优

    1.LightGBM简介 LightGBM是一个梯度Boosting框架,使用基于决策树的学习算法.它可以说是分布式的,高效的,有以下优势: 1)更快的训练效率 2)低内存使用 3)更高的准确率 4) ...

  5. R︱Yandex的梯度提升CatBoost 算法(官方述:超越XGBoost/lightGBM/h2o)

    俄罗斯搜索巨头 Yandex 昨日宣布开源 CatBoost ,这是一种支持类别特征,基于梯度提升决策树的机器学习方法. CatBoost 是由 Yandex 的研究人员和工程师开发的,是 Matri ...

  6. 比XGBOOST更快--LightGBM介绍

    xgboost的出现,让数据民工们告别了传统的机器学习算法们:RF.GBM.SVM.LASSO.........现在,微软推出了一个新的boosting框架,想要挑战xgboost的江湖地位.笔者尝试 ...

  7. LightGBM

    1.简介 lightGBM包含两个关键点:light即轻量级,GBM 梯度提升机 LightGBM 是一个梯度 boosting 框架,使用基于学习算法的决策树.它可以说是分布式的,高效的,有以下优势 ...

  8. RF,GBDT,XGBoost,lightGBM的对比

    转载地址:https://blog.csdn.net/u014248127/article/details/79015803 RF,GBDT,XGBoost,lightGBM都属于集成学习(Ensem ...

  9. 如何看待微软新开源的LightGBM?

    GBDT虽然是个强力的模型,但却有着一个致命的缺陷,不能用类似mini batch的方式来训练,需要对数据进行无数次的遍历.如果想要速度,就需要把数据都预加载在内存中,但这样数据就会受限于内存的大小: ...

随机推荐

  1. Root谷歌OnHub路由器

    Exploitee.rs极客小组因破解谷歌电视而成名,并且他们还发布了许多硬件相关的工具和exp.这次他们root了OnHub路由器.并发布在了他们的博客里. Google OnHub是谷歌于今年八月 ...

  2. UDP广播与多播

    UDP广播与多播 使用UDP协议进行信息的传输之前不需要建议连接.换句话说就是客户端向服务器发送信息,客户端只需要给出服务器的ip地址和端口号,然后将信息封装到一个待发送的报文中并且发送出去.至于服务 ...

  3. python3.6 ubuntu

    apt-get install python3.6-dev 安装 pip install mysqlclient 必备

  4. 为什么要使用AOP

    首先,按照软件重构思想的理念,如果多个类中出现相同的代码,应该考虑定义一个共同的抽象类,将这些相同的代码提取到抽象类当中去.比如Horse.Pig.Camel这些对象都有run().eat()方法,通 ...

  5. 获奖感言和C语言的学习心得

    获奖感言和C语言的学习心得 自我介绍: 大家好,我的名字叫袁忠,我来自湖南,今年快19岁了,现在是大学一年级,我平时喜欢跑步.打羽毛球,我也喜欢学算法与数学,以及喜欢看一些与计算机有关的书籍,每次我学 ...

  6. 利用asynchttpclient开源项目来把数据提交给服务器

    可以通过github去查找asynchttpclient,并下载源代码,并加载到自己的工程中. 1.利用get方法提交 2.利用post方法来提交

  7. 结构体内的函数与bfs的情景变量

    关于结构体内的函数,太难的尚且不会用,下面是一个简单一点的结构体内函数的代码 定义这样一个结构体函数之后就能像如下这样使用了 以上为结构体内的简单函数,下面重点来了,关于bfs找最短路由于需要避免走回 ...

  8. UVA1252 【Twenty Questions】

    分析 为了叙述方便,设"心里想的物体"为W.首先在读入时把每个物体转化为一个二进制整数.不难发现,同一个特征不需要问两遍,所以可以用一个集合s表示已经询问的特征集. 在这个集合s中 ...

  9. Mysql ON子句和USING子句

    Mysql ON子句和USING子句   Mysql 中联接SQL语句中,ON子句的语法格式为:table1.column_name = table2.column_name. 当模式设计对联接表的列 ...

  10. POJ_2299 Ultra-QuickSort【归并排序】

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/u013912596/article/details/35655703 题目链接:http://poj ...