LightGBM介绍

news2024/11/15 10:47:49

LightGBM介绍

GBDT是机器学习中一个长盛不衰的模型,其主要思想是利用弱分类器(决策树)迭代训练以得到最优模型,该模型具有训练效果好,不易过拟合等优点。GBDT不仅在工业界应用广泛,通常被应用于多分类、点击率预测、搜索排序等任务。在各种数据挖掘竞赛中也是致命的武器,据统计Kaggle比赛上有一般的冠军方案都是基于GBDT,而LightGBM(Light Gradient Boosting Machine)是一个实现GBDT算法的框架,支持高效率的并行训练,并且具有更快的训练速度,更低的内存消耗,更好的准确率。支持分布式可以快速处理海量数据等优点。

LightGBM提出的动机

常用的机器学习算法,例如神经网络等算法,都可以以mini-batch等方式进行训练,训练数据的大小不会受到内存限制,而GBDT在每一次迭代的时候,都需要遍历整个训练数据多次,如果把整个训练数据装进内存则会限制训练数据大小。如果不装进内存,反复的读取训练数据又会消耗非常大的时间,尤其是面对工业级海量的数据,普通的GBDT算法是不能满足其需求的。
LightGBM提出的主要原因就是为了解决GBDT在海量数据遇到的问题,让GBDT可以更好更快地用于工业实践

XGBoost缺点以及LightGBM的优化

XGBoost缺点

在LightGBM提出来之前,最有名的GBDT工具都是XGBoost,其是基于预排序方法的决策树算法,这种构建决策树算法的基本思想是:

  • 首先,对所有特征都按照特征的数值进行预排序。
  • 其次,在遍历分割点的时候用O(#data)的代价找到一个特征上的最好分割点。
  • 最后,在找到一个特征的最好分割点后,将数据分裂成左右子节点
    这样的预排序算法优点是能够精确的找到分割点,但是缺点也很明显:
    首先**,空间消耗大。这样的算法需要保存数据的特征值**,还保存了特征排序的结果(例如,为了后续快速的计算分割点,保存了排序后的索引),这就需要消耗训练数据两倍的内存

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

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

LightGBM的优化

为了避免上述XGBoost的缺陷,并且能够在不损害准确率的条件下加快GBDT模型的训练速度,lightGBM在传统的GBDT算法上进行了如下优化:

  • 基于Histogram的决策树算法
  • 单边梯度采样 Gradient-based One-Side Sampling(GOSS):使用GOSS可以减少大量只具有小梯度的数据实例,这样在计算信息增益的时候只利用剩下的具有高梯度的数据就可以了,相比XGBoost遍历所有特征值节省了不少时间和空间上的开销
  • 互斥特征捆绑 Exclusive Feature Bundling(EFB):使用EFB可以将许多互斥的特征绑定为一个特征,这样达到了降维的目的。
  • 带深度限制的Leaf-wise的叶子生长策略:大多数GBDT工具使用低效的按层生长 (level-wise)的决策树生长策略,因为它不加区分的对待同一层的叶子,带来了很多没必要的开销。实际上很多叶子的分裂增益较低,没必要进行搜索和分裂。LightGBM使用了带有深度限制的按叶子生长 (leaf-wise) 算法。
    *** 直接支持类别特征(Categorical Feature)**
  • 支持高效并行
    *** Cache命中率优化**

LightGBM基本原理

基于Histogram的决策树算法

直方图算法

Histogram algorithm应该翻译为直方图算法,直方图算法的基本思想是:先把连续的浮点特征值离散化为 K K K个整数,同时构造一个宽度为 K K K的直方图,在遍历数据的时候,根据离散化后的值作为索引在直方图中累积统计量,当遍历一次数据后,直方图累积了需要的统计量,然后根据直方图的离散值,遍历寻找最优的分割点
在这里插入图片描述
直方图算法简单理解为:首先确定对于每一个特征需要多少个箱子(bin)并为每一个箱子分配一个整数;然后将浮点数的范围均分成若干区间,区间个数与箱子个数相等,将属于该箱子的样本数据更新为箱子的值;最后用直方图(#bins)表示。看起来很高大上,其实就是直方图统计,将大规模的数据放在了直方图中。
特征离散化具有很多优点:存储方便、运算更快、鲁棒性强、模型更加稳定等。对于直方图算法来说,最直接的有以下两个优点:
在这里插入图片描述
当然,Histogram算法并不是完美的。由于特征被离散化后,找到的并不是很精确的分割点,所以会对结果产生影响。但在不同的数据集上的结果表明**,离散化的分割点对最终的精度影响并不是很大**,甚至有时候会更好一点。原因是决策树本来就是弱模型分割点是不是精确并不是太重要;较粗的分割点也有正则化的效果,可以有效地防止过拟合;即使单棵树的训练误差比精确分割的算法稍大,但在梯度提升(Gradient Boosting)的框架下没有太大的影响。

直方图做差加速

LightGBM另一个优化是Histogram(直方图)做差加速。一个叶子的直方图可以由它的父亲节点的直方图与它兄弟的直方图做差得到,在速度上可以提升一倍。通常构造直方图时,需要遍历该叶子上的所有数据,但直方图做差仅需遍历直方图的k个桶。在实际构建树的过程中,LightGBM还可以先计算直方图小的叶子节点,然后利用直方图做差来获得直方图大的叶子节点,这样就可以用非常微小的代价得到它兄弟叶子的直方图

在这里插入图片描述
注意,XGBoost在进行预排序时候,只考虑非零值进行加速,而 LightGBM 也采用类似策略:只用非零特征构建直方图

带深度限制的 Leaf-wise 算法

Histogram算法之上,LightGBM进行进一步的优化。首先它抛弃了大多数GBDT工具使用的按层生长 (level-wise) 的决策树生长策略,而使用了带有深度限制的按叶子生长 (leaf-wise) 算法

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

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

在这里插入图片描述

单边梯度采样算法

Gradient-based One-Side Sampling 应该被翻译为单边梯度采样(GOSS)。GOSS算法从减少样本的角度出发,排除大部分小梯度的样本,仅用剩下的样本计算信息增益,它是一种在减少数据量和保证精度上平衡的算法

AdaBoost中,样本权重是数据重要性的指标。然而在GBDT中没有原始样本权重,不能应用权重采样。幸运的是,我们观察到GBDT中每个数据都有不同的梯度值,对采样十分有用。即梯度小的样本,训练误差也比较小,说明数据已经被模型学习得很好了,直接想法就是丢掉这部分梯度小的数据。然而这样做会改变数据的分布,将会影响训练模型的精确度,为了避免此问题,提出了GOSS算法。
GOSS是一个样本的采样算法,目的是丢弃一些对计算信息没有帮助的样本留下有帮助的,根据计算信息增益的定义,梯度大的样本对信息增益有更大的影响。因此,GOSS在进行数据采样的时候只保留了梯度较大的数据,但是如果直接将所有梯度较小的数据都丟弃掉势必会影响数据的总 体分布
所以,GOSS首先将要进行分裂的特征的所有取值按照绝对值大小降序排序(XGBoost一 样也进行了排序,但是LightGBM不用保存排序后的结果

在这里插入图片描述
在这里插入图片描述

互斥特征捆绑算法

高维度的数据往往是稀疏的,这种稀疏性启发我们设计一种无损的方法来减少特征的维度。通常被 抹绑的特征都是互斥的(即特征不会同时为非零值,像one-hot),这样两个特征描绑起来才不会 丟失信息。如果两个特征并不是完全互斥 (部分情况下两个特征都是非零值),可以用一个指标对 特征不互斥程度进行像量,称之为冲突比率,当这个值较小时,我们可以选择把不完全互斥的两个 特征肺绑,而不影响最后的精度

在这里插入图片描述

LightGBM工程优化

我们将论文《Lightgbm: A highly efficient gradient boosting decision tree》中没有提到的优化方案,而在其相关论文《A communication-efficient parallel algorithm for decision tree》中提到的优化方案,放到本节作为LightGBM的工程优化来向大家介绍.

直接支持类别特征

实际上大多数机器学习工具都无法直接支持类别特征,一般需要把类别特征,通过 one-hot 编码,转化到多维的0/1特征降低了空间和时间的效率。但我们知道对于决策树来说并不推荐使用 one-hot 编码,尤其当类别特征中类别个数很多的情况下,会存在以下问题

一、会产生样本切分不平衡问题导致切分增益非常小(即浪费了这个特征)。使用 one-hot编码,意味着在每一个决策节点上只能使用one vs rest(例如是不是狗,是不是猫等)的切分方式
例如**,动物类别切分后,会产生是否狗,是否猫等一系列特征**,这一系列特征上只有少量样本为 1,大量样本为 0,这时候切分样本会产生不平衡,这意味着切分增益也会很小。较小的那个切分样本集,它占总样本的比例太小,无论增益多大,乘以该比例之后几乎可以忽略;较大的那个拆分样本集,它几乎就是原始的样本集,增益几乎为零。比较直观的理解就是不平衡的切分和不切分没有区别
二、会影响决策树的学习。因为就算可以对这个类别特征进行切分,独热编码也会把数据切分到很多零散的小空间上,如下图左边所示。而决策树学习时利用的是统计信息,在这些数据量小的空间上,统计信息不准确,学习效果会变差。但如果使用下图右边的切分方法**,数据会被切分到两个比较大的空间,进一步的学习也会更好**。下图右边叶子节点的含义是X=A或者X=C放到左孩子,其余放到右孩子。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在Expo数据集上实验结果表明,相比0/1展开方法,使用LigtGBM支持的类别特征可以使训练速度加速8倍,并且精度一致,更重要的是,LightGBM是第一个直接支持类别特征的GBDT工具

支持高效并行

特征并行

特征并行的主要思想是不同机器在不同的特征集合上分别寻找最优的分割点,然后在机器间同步最优的分割点。XGBoost使用的就是这种特征并行方法。这种特征并行方法有个很大的缺点:就是对数据进行垂直划分,每台机器所含数据不同,然后使用不同机器找到不同特征的最优分裂点,划分结果需要通过通信告知每台机器增加了额外的复杂度
LigtGBM则不进行数据垂直划分,而是在每台机器上保存全部训练数据,在得到最佳划分方案后,可在本地执行划分而减少不必要的通信,具体过程如下图所示:
在这里插入图片描述

数据并行

传统的数据并行策略主要为水平划分数据,不同的机器先在本地构造直方图,然后进行全局的合 并,最后在合并的直方图上面寻找最优分割点。这种数据划分有一个很大的缺点:通讯开销过大。 如果使用点对点通信,一台机器的通讯开销大约为 O(#machine* # feature*#bin) 如果使用集成的通信,则通讯开销
在这里插入图片描述

LightGBM在数据并行中使用分散规约 (Reduce scatter) 把直方图合并的任务分摊到不同的机器,降低通信和计算,并利用直方图做差,进一步减少了一半的通信量。具体过程如下图所示。

在这里插入图片描述

投票并行

基于投票的数据并行则进一步优化数据中并行的通信代价,使通信代价变成常数级别,在数据量很大的时候,使用投票并行的方式只合并部分特征的直方图从而达到降低通信量的目的,可以得到非常好的加速效果。具体过程如下图所示

大致步骤分为两步

  • 本次找出 T o p K Top K TopK特征,并基于投票筛选出可能最优分割点特征。
  • 合并时只合并每个机器选出来的特征。
    在这里插入图片描述

Cache命中率优化

XGBoost对cache优化不友好,如下图所示。在预排序后,特征对梯度的访问是一种随机访问,并且不同的特征访问的顺序不一样,无法对cache进行优化。同时,在每一层长树的时候,需要随机访问一个行索引到叶子索引的数组,并且不同特征访问的顺序也不一样,也会造成较大的cache miss。为了解决缓存命中率低的问题,XGBoost 提出了缓存访问算法进行改进

在这里插入图片描述
而LigthGBM所使用直方图算法对Cache天生友好。

  • 首先,所有的特征都采用相同的方式获得梯度(区别于XGBoost的不同特征通过不同的索引获得梯度),只需要对梯度进行排序并可实现连续访问,大大提高了缓存命中率;
  • 其次,因为不需要存储行索引到叶子索引的数组,降低了存储消耗,而且也不存在 Cache Miss的问题
    在这里插入图片描述

LigtGBM的优缺点

  • 从内存和速度两方面进行介绍:
  • 速度更快

  • 在这里插入图片描述
  • 内存更小

  • 在这里插入图片描述
  • 缺点

    • 可能会长出比较深的决策树,产生过拟合。因此LightGBM在Leaf-wise之上增加了一个最大深度限制,在保证高效率的同时防止过拟合;
  • Boosting族是迭代算法,每一次迭代都根据上一次迭代的预测结果对样本进行权重调整,所以随着迭代不断进行,误差会越来越小,模型的偏差(bias)会不断降低。由于LightGBM是基于偏差的算法,所以会对噪点较为敏感;
  • 在寻找最优解时,依据的是最优切分变量,没有将最优解是全部特征的综合这一理念考虑进去;

经验

  • 会将Xgboost、LightGBM、GBDT啥的都研究一波。慢慢的全部都将其搞定都行啦的回事与打算。

t

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/176873.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【ONE·C || 数据存储】

总言 C语言:数据存储相关介绍。 文章目录总言1、基本数据类型介绍1.1、整体介绍1.2、各数据类型分别说明(整型、浮点型、构造、指针、空)2、整型在内存中的存储2.1、原码、反码、补码2.1.1、总体介绍2.1.2、char、short类型在内存中的存储范围…

顺序表的具体使用方法.数据解构(二)

前言 提示:文本为数据解构(一)后续补充文: 本文具体讲解顺序表的具体使用方法 提示:以下是本篇文 系列文章目录 第一章 数据解构(一) 文章目录 前言 系列文章目录 一、静态的使用方式 二、动态的使用方式 1.定义一个结构体 2.初始化 3.扩容…

【ArcGIS微课1000例】0060:ArcGIS打开las格式点云数据的方法

文章目录 1. 使用上下文菜单创建 LAS 数据集2. 使用地理处理工具创建 LAS 数据集3. 显示LAS数据集LAS 数据集是位于文件夹中的独立文件,并且引用 LAS 格式的激光雷达数据和用于定义表面特征的可选表面约束要素。ArcGIS中,可使用创建 LAS 数据集工具或 ArcCatalog 中文件夹的上…

23种设计模式(二十)——责任链模式【数据结构】

文章目录 意图什么时候使用责任链真实世界类比责任链模式的实现责任链模式的优缺点亦称:职责链模式、命令链、CoR、Chain of Command、Chain of Responsibility 意图 将链中的每一个节点看作是一个对象,每个节点处理的请求不同,且内部自动维护一个下一节点对象。当一个请求…

【OpenGL学习】camera and camera control

摄像机 游戏中的相机可以理解为与现实中的相机类似,可以捕获对应的游戏画面。Camera在游戏引擎中一般也会展示为现实中相机的模型,使用时有两种实现方式,一种以组件形式挂载在Character上,一种则是单独存在。通常来讲&#xff0c…

Flutter 基础-下

一、shared_preferences shared_preferences 是一个本地数据缓存库(类似 AsyncStorage) https://pub.dev/packages/shared_preferences 使用步骤 在 pubsepc.yaml 中添加 shared_preferences 依赖安装依赖(pub get | flutter packages get |…

Git使用Merge和Rebase区别及心得技巧

git rebase命令常常因为江湖上关于它是一种Git魔法命令的名声而导致Git新手对它敬而远之,但是事实上如果一个团队能够正确使用的话,它确实可以让生活变得更简单。在这篇文章中我们会比较git rebase和经常与之相提并论的git merge命令,并且在真…

【回望2022,走向2023】一个双非二本非科班的学生的旅途

目录 1.自我介绍 2.高考与暑假 梦想 幻灭 决心 暑假 3.大一上学期 4.奋进之路 5.展望未来 1.自我介绍 我是一个双非本科的大一学生,在2023年的新春之际,借着CSDN的这次年度总结活动,来好好回顾一下,2022这个平凡却又不乏…

css 2D转换

文章目录一、什么是2D转换二、rotate() 方法(旋转)三、translate() 方法(位移)四、scale() 方法(缩放)五、skew() 方法 (倾斜)一、什么是2D转换 在二维空间下对元素进行移动、缩放、…

面试官问我有没有分布式系统开发经验,我一脸懵圈…

目录 从单块系统说起团队越来越大,业务越来越复杂分布式出现:庞大系统分而治之分布式系统所带来的技术问题一句话总结:什么是分布式系统设计和开发经验补充说明:中间件系统及大数据系统 前言 现在有很多Java技术方向的同学在找工…

深度学习网络---YOLO系列

深度学习网络—YOLO yolov1(仅适用一个卷积神经网络端到端地实现检测物体的目的) 首先将输入图片resize到448448,然后送入CNN网络,最后处理预测的结果得到检测的目标;yolov1的具体思想是将全图划分为SS的格子&#xf…

结构型模式-外观模式

1.概述 有些人可能炒过股票,但其实大部分人都不太懂,这种没有足够了解证券知识的情况下做股票是很容易亏钱的,刚开始炒股肯定都会想,如果有个懂行的帮帮手就好,其实基金就是个好帮手,支付宝里就有许多的基…

智能的本质不是数据算法算力和知识

编者按:人机之间未解决的大部分问题不是统计问题,而是统计概率分布外的问题。人是自然的,又不是自然的,还是社会的,人类和机器都可以作为认知的载体,但认知的性质是不同的,一个是生命的认知&…

GA6-BGSM/GPRS模块介绍

GA6-BGSM/GPRS模块简介GA6-B是一个4频的GSM/GPRS模块,工作的频段为:EGSM 900MHz、 GSM850MHz和DCS1800, PCS1900。GA6-B支持GPRS multi-slot class 10/ class 8(可选)和 GPRS 编码格式CS-1, CS-2, CS-3 and CS-4。模块的尺寸只有2…

SelectPdf for .NET 22.0 Crack

SelectPdf for .NET 是一个专业的 PDF 库,可用于创建、编写、编辑、处理和读取 PDF 文件,而无需在 .NET 应用程序中使用任何外部依赖项。使用此 .NET PDF 库,您可以实现丰富的功能,从头开始创建 PDF 文件或完全通过 C#/VB.NET 处理…

python数据结构——栈、队列

python数据结构——栈、队列、树和算法栈栈的操作队列单端队列操作双端队列操作链表或者顺序表的使用场景: 当数据需要后进先出,来构建栈或者先进先出,构建队列时 栈或者队列之内的数据可以以顺序表或者链表的方式进行存储 python内置的数据…

Python基础学习 -- 模块与包

1、模块每一个py文件都可以理解为一个模块,模块可以增加项目的可读性2、新建一个名为算数.py文件,代码内容如下:print("算数模块被加载!") def 加法(a,b):print(ab)3、新建一个main.py文件,调用模块的内容第…

Vue TypeScript 使用eval函数的坑

正常情况下,项目里不会用eval函数,但是万一要调用一个全局的js库,就需要用eval做些骚操作,这个时候编译会提示: is strongly discouraged as it poses security risks and may cause issues with minification. 警告是…

Java多线程(二)——ReentrantLock源码解析(补充1——从AQS中唤醒的线程)

ReentrantLock源码解析(补充1) 上一章仅介绍了 ReentrantLock 的常用方法以及公平锁、非公平锁的实现。这里对上一章做一些补充。主要是: AQS 中阻塞的线程被唤醒后的执行流程 (本篇讲述) 可打断的锁 lock.lockInter…

【QT5.9】与MFC对比学习笔记-感悟篇2【2023.01.23】

是对QT的分析,不仅局限于QT。 二者区别 天下文章一大抄,技术也一样。MFC是对Windows系统API进行的封装,是以视类与文档类为核心的框架设计。微软20年前就已经把MVC玩的很6了,还有控件、动态库等等技术都是微软爸爸先搞出来的。若…