集成学习之Xgboost、LightGBM对GBDT的改进

上篇文章集成学习之梯度提升决策树(GBDT)已经介绍了集成学习中boosting系列的重要算法GBDT,这里的GBDT特指“Greedy Function Approximation:A Gradient Boosting Machine”里提出的算法,它只用了 一阶导数信息。

实际上GBDT泛指所有梯度提升树算法,包括XGBoost、LightGBM,它们是GBDT的变种。

1.Xgboost

GBDT在利用前向分布算法学习加法模型时,用到了基于一阶泰勒展开的梯度提升求解法;而XGBoost在函数空间中用牛顿法进行优化。

1.1模型函数形式

给定数据集D = {(Xi,Yi)},XGBoost进行additive training,学习 K棵树,采用以下函数对样本进行预测:

这里F是假设空间,f(x)是回归树(CART):

q(x)表示将样本x分到了某个叶子节点上,W是叶子节点的分数(leaf score),所以 Wq(x) 表示回归树对样本的预测值。

  • 例子:预测一个人是否喜欢电脑游戏

回归树的预测输出是实数分数,可以用于回归、分类、排序等任务中。对于回归问题,可以直接作为目标值,对于分类问题,需要映射成概率,比如采用Sigmoid函数。

1.2目标函数

参数空间中的目标函数:

误差函数可以是square loss,logloss等,正则项可以是L1正则, L2正则等。
XGBoost的目标函数(函数空间)

正则项对每棵回归树的复杂度进行了惩罚

正则项

正则项的作用,可以从Bayes先验的角度去解释。从Bayes角度来看,正则相当于对模型参数引入先验分布:

L2正则,模型参数服从高斯分布 Θ \Theta Θ ~ N (0, σ 2 \sigma^2 σ2),对参数加了分布约束,大部分绝对值很小。

L1正则,模型参数服从拉普拉斯分布,对参数加了分布约束,大部分取值为0。

Xgboost的正则项

相比原始的GBDT,XGBoost的目标函数多了正则项,使得学习出来的 模型更加不容易过拟合。
有哪些指标可以衡量树的复杂度? 树的深度,内部节点个数,叶子节点个数(T),叶节点分数(w)… XGBoost采用的:

对叶子节点个数进行惩罚,相当于在训练过程中做了剪枝。

误差函数的二阶泰勒展开

第t次迭代后,模型的预测等于前t-1次的模型预测加上第t棵树的预测:

此时目标函数可写作:

公式中 yi , yi(t-1) 都已知,模型要学习的只有第t棵树 ft。
将误差函数在 yi(t-1) 处进行二阶泰勒展开:

上式中,

将公式中的常数项去掉,得到:

把 ft ,Ω( ft ) 写成树结构的形式,即把下式代入目标函数中:

得到:

怎么统一起来?
定义每个叶节点j上的样本集合为:

则目标函数可以写成按叶节点累加的形式:

如果确定了树的结构(即q(x)确定),为了使目标函数最小,可以令其导数为0,解得每个叶节点的最优预测分数为:

代入目标函数,得到最小损失为:

1.3回归树的学习策略

当回归树的结构确定时,我们前面已经推导出其最优的叶节点分数以及 对应的最小损失值,问题是怎么确定树的结构?
暴力枚举所有可能的树结构,选择损失值最小的 - NP难问题
贪心法,每次尝试分裂一个叶节点,计算分裂前后的增益,选择增益最大的。

分裂前后的增益怎么计算?
ID3算法采用信息增益
C4.5算法采用信息增益比
CART采用Gini系数
XGBoost呢?

XGBoost的打分函数

标红部分衡量了每个叶子节点对总体损失的的贡献,我们希望损失越小越好,则标红部分的值越大越好。
因此,对一个叶子节点进行分裂,分裂前后的增益定义为:

Gain的值越大,分裂后 L 减小越多。所以当对一个叶节点分割时,计算所 有候选(feature,value)对应的gain,选取gain最大的进行分割。

树节点分裂方法(Split Finding)

精确算法
遍历所有特征的所有可能的分割点,计算gain值,选取值最大的(feature,value)去分割

近似算法
对于每个特征,只考察分位点,减少计算复杂度
Global:学习每棵树前,提出候选切分点
Local:每次分裂前,重新提出候选切分点

近似算法举例:三分位数

实际上XGBoost不是简单地按照样本个数进行分位,而是以二阶导数值作为权重(Weighted Quantile Sketch),比如:

为什么用hi加权?
把目标函数整理成以下形式,可以看出hi有对loss加权的作用

稀疏值处理

• 稀疏值: 缺失,类别one-hot编码,大量0值
• 当特征出现缺失值时,XGBoost 可以学习出默认的节点分裂方向

XGBoost怎么处理缺失值?
这是XGBoost的一个优点。具体处理方法为:在某列特征上寻找分裂节点时,不会对缺失的样本进行遍历,只会对非缺失样本上的特征值进行遍历,这样减少了为稀疏离散特征寻找分裂节点的时间开销。另外,为了保证完备性,对于含有缺失值的样本,会分别把它分配到左叶子节点和右叶子节点,然后再选择分裂后增益最大的那个方向,作为预测时特征值缺失样本的默认分支方向。如果训练集中没有缺失值,但是测试集中有,那么默认将缺失值划分到右叶子节点方向。

XGBoost中的一棵树的停止生长条件

当树达到最大深度时,停止建树,因为树的深度太深容易出现过拟合,这里需要设置一个超参数max_depth。当新引入的一次分裂所带来的增益Gain<0时,放弃当前的分裂。这是训练损失和模型结构复杂度的博弈过程。当引入一次分裂后,重新计算新生成的左、右两个叶子结点的样本权重和。如果任一个叶子结点的样本权重低于某一个阈值,也会放弃此次分裂。这涉及到一个超参数:最小样本权重和,是指如果一个叶子节点包含的样本数量太少也会放弃分裂,防止树分的太细。

XGBoost可以做特征选择,它是如何评价特征重要性的?

XGBoost中有三个参数可以用于评估特征重要性:weight :该特征在所有树中被用作分割样本的总次数。gain :该特征在其出现过的所有树中产生的平均增益。cover :该特征在其出现过的所有树中的平均覆盖范围。覆盖范围这里指的是一个特征用作分割点后,其影响的样本数量,即有多少样本经过该特征分割到两个子节点。

1.4重点

w是叶子分数就是某一个数据的当前拟合值,是最优化求出来的,不是啥平均值或规则指定的,CART中用均值是对损失函数的负梯度令其为0得到的,这里xgboost也是用的目标函数的泰勒展开的负梯度令其为0得到的,这个算是一个思路上的新颖吧;

正则化防止过拟合的技术,上述看到了,直接loss function里面就有;支持自定义loss function,只要能泰勒展开(能求一阶导和二阶导,二次可微);

支持并行化
这是xgboost的闪光点,直接的效果是训练速度快,boosting技术中下一棵树依赖上述树的训练和预测,所以树与树之间应该是只能串行!那么大家想想,哪里可以并行?!
没错,在选择最佳分裂点,进行枚举的时候并行!(据说恰好这个也是树形成最耗时的阶段)

Attention:同层级节点可并行。具体的对于某个节点,节点内选择最佳分裂点,候选分裂点计算增益用多线程并行。

对于每个特征,需要遍历所有的特征值去选择最佳分割点。如果在训练之前就排好序并存储在内存block中,每一个特征对应一个block。这样在构建第k棵树的过程中,可以同时对所有的叶结点进行分割点的遍历,也可以同时对所有特征进行分割点的遍历,这样特征的选择和叶结点的分裂可以同时进行,达到并行化计算的目的,可以进行分布式或多线程计算,缩短训练时间。

较少的离散值作为分割点倒是很简单,比如“是否是单身”来分裂节点计算增益是很easy,但是“月收入”这种feature,取值很多,从5k~50k都有,总不可能每个分割点都来试一下计算分裂增益吧?(比如月收入feature有1000个取值,难道你把这1000个用作分割候选?缺点1:计算量,缺点2:出现叶子节点样本过少,过拟合)我们常用的习惯就是划分区间,那么问题来了,这个区间分割点如何确定(难道平均分割),作者是这么做的:

方法名字:Weighted Quantile Sketch
大家还记得每个样本在节点(将要分裂的节点)处的loss function一阶导数gi和二阶导数hi,衡量预测值变化带来的loss function变化,举例来说,将样本“月收入”进行升序排列,5k、5.2k、5.3k、…、52k,分割线为“收入1”、“收入2”、…、“收入j”,满足(每个间隔的样本的hi之和/总样本的hi之和)为某个百分比ϵ(我这个是近似的说法),那么可以一共分成大约1/ϵ个分裂点。

1.5工程优化

Column Block for Parallel Learning
总的来说:按列切开,升序存放;
方便并行,同时解决一次性样本读入炸内存的情况

由于将数据按列存储,可以同时访问所有列,那么可以对所有属性同时执行split finding算法,从而并行化split finding(切分点寻找)-特征间并行
可以用多个block(Multiple blocks)分别存储不同的样本集,多个block可以并行计算-特征内并行

Blocks for Out-of-core Computation
数据大时分成多个block存在磁盘上,在计算过程中,用另外的线程读取数据,但是由于磁盘IO速度太慢,通常更不上计算的速度,
将block按列压缩,对于行索引,只保存第一个索引值,然后只保存该数据与第一个索引值之差(offset),一共用16个bits来保存 offset,因此,一个block一般有216个样本。

1.6疑问及总结

Xgboost第一感觉就是防止过拟合+各种支持分布式/并行,所以一般传言这种大杀器效果好(集成学习的高配)+训练效率高(分布式),与深度学习相比,对样本量和特征数据类型要求没那么苛刻,适用范围广。

GBDT是一个梯度迭代树,使用梯度迭代下降法求解,认为每一棵迭代树都在学习前N-1棵树的负梯度。残差只是误差为均方误差的情况下推导出来的。

这里真心有个疑问:
Xgboost在下一棵树拟合的是残差还是负梯度,还是说是一阶导数+二阶导数,−gi(1+hi)? 应该是一阶导数除以二阶导数gi/hi。

Xgboost和深度学习的关系,陈天奇在Quora上的解答如下:
不同的机器学习模型适用于不同类型的任务。深度神经网络通过对时空位置建模,能够很好地捕获图像、语音、文本等高维数据。而基于树模型的XGBoost则能很好地处理表格数据,同时还拥有一些深度神经网络所没有的特性(如:模型的可解释性、输入数据的不变性、更易于调参等)。
这两类模型都很重要,并广泛用于数据科学竞赛和工业界。举例来说,几乎所有采用机器学习技术的公司都在使用tree boosting,同时XGBoost已经给业界带来了很大的影响。

2.LightGBM

2.1直方图算法

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

• 减小内存占用,比如离散为256个bin时,只需要8bit,节省7/8
• 减小了splitfinding时计算增益的计算量,从O(#data)降到O(#bins)

直方图差加速

一个叶子的直方图可以由它的父亲节点的直方图与它兄弟节点的直方图做差得到,提升一倍速度:

思考:选取哪个子节点统计直方图?

2.2建树过程的两种方法

Level-wise和Leaf-wise

XGBoost同一层所有节点都做分裂,最后剪枝。

LightGBM选取具有最大增益的节点分裂,容易过拟合,通过max_depth限制。

2.3并行优化(Optimization in parallel learning)

特征并行

传统的特征并行
• 垂直切分数据,每个worker只有部分特征;
• 每个worker找到局部最佳切分点(feature,threshold)
• worker之间互相通信,找到全局最佳切分点;
• 具有全局最佳切分特征的worker进行节点分裂,然后广播切分后左右子树的instance indices;
• 其他worker根据广播的instance indices进行节点分裂。

特征并行示意图

缺点:
split finding计算复杂度O(#data),当数据量大时会比较慢。
网络通信代价大,需要广播instanceindices。

LightGBM的特征并行
每个worker保存所有数据集
• 每个worker在其特征子集上寻找最佳切分点
• worker之间互相通信,找到全局最佳切分点
• 每个worker根据全局最佳切分点进行节点分裂

优点:
避免广播instance indices,减小网络通信量。

缺点:
split finding计算复杂度没有减小且当数据量比较大时,单个worker存储所有数据代价高。

数据并行

传统的数据并行
水平切分数据,每个worker只有部分数据
• 每个worker根据本地数据统计局部直方图
• 合并所有局部直方图得到全局直方图
• 根据全局直方图进行节点分裂

数据并行示意图

缺点:网络通信代价巨大
采用point-to-point communication algorithm,每个worker通信量 O(#machine * #feature * #bin)
采用collective communication algorithm , 每个worker通信量O(2 * #feature * #bin)

LightGBM的数据并行
• 不同的worker合并不同特征的局部直方图
• 采用直方图做差算法,只需要通信一个节点的直方图
通信量减小到 O(0.5 * #feature* #bin)
Voting parallel,参考论文“A Communication-Efficient Parallel Algorithm for Decision Tree”

其它

• Gradient-based One Side Sampling (GOSS)
在每一次迭代前,利用了GBDT中的样本梯度和误差的关系,对训练样本进行采样: 对误差大(梯度绝对值大)的数据保留;对误差小的数 据采样一个子集,但给这个子集的数据一个权重,让这个子集可以近 似到误差小的数据的全集。这么采样出来的数据,既不损失误差大的 样本,又在减少训练数据的同时不改变数据的分布,从而实现了在几 乎不影响精度的情况下加速了训练。
• Exclusive Feature Bundling (EFB)
在特征维度很大的数据上,特征空间一般是稀疏的。利用这个特征, 我们可以无损地降低GBDT算法中需要遍历的特征数量,更确切地说, 是降低构造特征直方图(训练GBDT的主要时间消耗)需要遍历的特征 数量。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: AdaboostGBDTXGBoostLightGBM都是机器学习中常用的集成学习算法。 Adaboost是一种迭代算法,通过不断调整样本权重和分类器权重,逐步提高分类器的准确率。 GBDT(Gradient Boosting Decision Tree)是一种基于决策树的集成学习算法,通过不断迭代,每次训练一个新的决策树来纠正前面树的错误,最终得到一个强分类器。 XGBoost是一种基于GBDT的算法,它在GBDT的基础上引入了正则化和并行化等技术,使得模型更加准确和高效。 LightGBM是一种基于GBDT的算法,它采用了基于直方图的决策树算法和互斥特征捆绑技术,使得模型训练速度更快,占用内存更少,同时也具有较高的准确率。 ### 回答2: adaboost(Adaptive Boosting) 是一种基于不同权重的弱分类器的算法,它通过迭代的方式来逐步提高分类器的准确性。在每轮迭代中,它会调整训练样本的权重,使得前一轮分类错误的样本在当前轮得到更多的关注。最终,通过组合这些弱分类器来构建一个强分类器。其优点在于不易过拟合,但需要耗费大量的时间来训练和预测。 gbdt(Gradient Boosting Decision Tree) 是一种基于决策树的集成学习算法,它通过迭代的方式来提升分类器的准确性。基于训练样本和实际输出的误差进行梯度下降,将它们作为下一个分类器的训练数据。每个分类器都在之前所有分类器得到的残差的基础上进行训练,并且将它们组合成一个最终的分类器。在训练过程中,为了避免过拟合,可以限制决策树的深度等参数,并采用交叉验证等技术。gbdt可以处理缺失数据、不平衡分类和高维度数据等问题,但需要注意过拟合的问题。 xgboost(Extreme Gradient Boosting) 是一种基于决策树的集成学习算法,它在gbdt的基础上引入了正则化项和精细的特征选择,进一步提高了分类器的准确性和效率。通过Hessian矩阵对损失函数进行二阶泰勒展开,引入正则化约束,可以优化损失函数,并通过交叉验证等技术选择最优的超参数。xgboost还支持GPU加速,提高模型训练的速度和效率,但需要更多的计算资源。xgboost在分类、回归和排名任务中表现优异,但需要注意过拟合和计算量的问题。 lightgbm是微软旗下一款高效、快速、分布式的梯度提升框架,也是一种基于决策树的集成学习算法,定位在处理高维度数据和大规模数据集上。lightgbm采用了GOSS(Gradient-based One-Side Sampling)技术和EFB(Exclusive Feature Bundling)技术对数据进行处理,大大减少数据的内存占用和训练时间。同时,还支持并行计算和GPU加速,提高了模型的速度和效率。lightgbm在排序、分类、回归等任务中表现出色,只是对离群值敏感,需要对数据进行预处理。 ### 回答3: Adaboost,Gradient Boosting Decision Tree (GBDT),XGBoostLightGBM都是常见的集成学习算法,它们用于提高模型在复杂数据集上的准确度,并处理复杂数据集上遇到的问题。 Adaboost是一种迭代算法,每次迭代它使用提高错误分类样本的加权值,并降低正确分类样本的加权值,以便让前一个弱分类器无法捕捉并由后续分类器学习。Adaboost弱分类器快速训练和预测,且不需要太多超参数调整,但是它倾向于过度拟合数据,并且实力可能不足以解决大型数据集的问题。 GBDT使用决策树作为弱分类器,将每一棵树的预测结果作为下一棵树的预测输入,最后对所有树的预测结果进行加权求和。GBDT可以很好地处理线性和非线性问题,但是它倾向于过度拟合数据,需要进行精细调整参数,并且需要较长时间的训练时间。 XGBoost结合了GBDT的优势和树的强大性质。它采用了一些优秀的技术,如Boosting树算法,Shrinkage,Column Sampling和Pruning Nodes,以提高模型的性能和降低过拟合风险。XGBoost可以处理大规模数据集和高维数据集,并且速度较快,但需要的资源较多,如内存、计算能力和高质量的数据集。 LightGBMXGBoost的新一代版本,采用了GOI(Gradient-based One-side Sampling)算法和Histogram-based Gradient Boosting方法来加快训练速度和降低内存占用。GOI算法通过对数据进行一侧采样来提高训练速度,而直方图梯度提升方法将节点分裂建模为一个直方图分桶过程,以减少节点分裂的计算成本。LightGBM对大数据集的处理能力很强,速度相对较快,但对于处理小数据集的效果可能不明显。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值