XBG和LGB和CATBOOST 要用哪一种? 深度分析


概述

尽管最近几年神经网络复兴,并变得流行起来,但我还是更加关注 boosting 算法,因为在训练样本量有限、所需训练时间较短、缺乏调参知识的场景中,它们依然拥有绝对优势。

在这里插入图片描述

  • 2014 年 3 月,XGBOOST 最早作为研究项目,由陈天奇提出

  • 2017 年 1 月,微软发布首个稳定版 LightGBM

  • 2017 年 4 月,俄罗斯顶尖技术公司 Yandex 开源 CatBoost

LightGBM 和 XGBoost 的结构差异

在过滤数据样例寻找分割值时,LightGBM 使用的是全新的技术:基于梯度的单边采样(GOSS);而 XGBoost 则通过预分类算法和直方图算法来确定最优分割。这里的样例(instance)表示观测值/样本。

首先让我们理解预分类算法如何工作:

  • 对于每个节点,遍历所有特征

  • 对于每个特征,根据特征值分类样例

  • 进行线性扫描,根据当前特征的基本信息增益,确定最优分割

  • 选取所有特征分割结果中最好的一个

简单说,直方图算法在某个特征上将所有数据点划分到离散区域,并通过使用这些离散区域来确定直方图的分割值。虽然在计算速度上,和需要在预分类特征值上遍历所有可能的分割点的预分类算法相比,直方图算法的效率更高,但和 GOSS 算法相比,其速度仍然更慢。
关键信息:预分类,直方图算法,GOSS

为什么 GOSS 方法如此高效?

在 Adaboost 中,样本权重是展示样本重要性的很好的指标。但在梯度提升决策树(GBDT)中,并没有天然的样本权重,因此 Adaboost 所使用的采样方法在这里就不能直接使用了,这时我们就需要基于梯度的采样方法。

梯度表征损失函数切线的倾斜程度,所以自然推理到,如果在某些意义上数据点的梯度非常大,那么这些样本对于求解最优分割点而言就非常重要,因为算其损失更高。

GOSS 保留所有的大梯度样例,并在小梯度样例上采取随机抽样。比如,假如有 50 万行数据,其中 1 万行数据的梯度较大,那么我的算法就会选择(这 1 万行梯度很大的数据+x% 从剩余 49 万行中随机抽取的结果)。如果 x 取 10%,那么最后选取的结果就是通过确定分割值得到的,从 50 万行中抽取的 5.9 万行。

在这里有一个基本假设:如果训练集中的训练样例梯度很小,那么算法在这个训练集上的训练误差就会很小,因为训练已经完成了。

为了使用相同的数据分布,在计算信息增益时,GOSS 在小梯度数据样例上引入一个常数因子。因此,GOSS 在减少数据样例数量与保持已学习决策树的准确度之间取得了很好的平衡。
在这里插入图片描述

每个模型是如何处理分类变量的

CatBoost

完整版代码 catboost(记不住的可以收藏)
关键词:独热最大量,CatBoost

CatBoost 可赋予分类变量指标,进而通过独热最大量得到独热编码形式的结果(独热最大量:在所有特征上,对小于等于某个给定参数值的不同的数使用独热编码)。

如果在 CatBoost 语句中没有设置「跳过」,CatBoost 就会将所有列当作数值变量处理。

注意,如果某一列数据中包含字符串值,CatBoost 算法就会抛出错误。另外,带有默认值的 int 型变量也会默认被当成数值数据处理。在 CatBoost 中,必须对变量进行声明,才可以让算法将其作为分类变量处理。

from catboost import CatBoostRegressor
cat_features = [0,1,2]
train_data = [["a","b",1,4,5,6],["a","b",4,5,6,7],["c","d",30,40,50,60]]
test_data = [["a","b",2,4,6,8],["a","b",1,4,50,60]]
train_labels = [10,20,30]
model = CatBoostRegressor(iterations=2,learning_rate=1,depth=2)
model.fit(train_data,train_labels,cat_features)

这里面的cat_features表示,第一个特征需要编码,这里是0,1,2个特征都要编码,就是两个字符特征和第一个整数特征都是按照分类变量来看待的。这里也可以是[0,1]。
对于可取值的数量比独热最大量还要大的分类变量,CatBoost 使用了一个非常有效的编码方法,这种方法和均值编码类似,但可以降低过拟合情况。它的具体实现方法如下:

  1. 将输入样本集随机排序,并生成多组随机排列的情况。

  2. 将浮点型或属性值标记转化为整数。

  3. 将所有的分类特征值结果都根据以下公式,转化为数值结果。

在这里插入图片描述

其中 CountInClass 表示在当前分类特征值中,有多少样本的标记值是「1」;Prior 是分子的初始值,根据初始参数确定。TotalCount 是在所有样本中(包含当前样本),和当前样本具有相同的分类特征值的样本数量。

LightBGM

和 CatBoost 类似,LighGBM 也可以通过使用特征名称的输入来处理属性数据;它没有对数据进行独热编码,因此速度比独热编码快得多。LGBM 使用了一个特殊的算法来确定属性特征的分割值。
在这里插入图片描述

注意,在建立适用于 LGBM 的数据集之前,需要将分类变量转化为整型变量;此算法不允许将字符串数据传给分类变量参数。

XGBoost

和 CatBoost 以及 LGBM 算法不同,XGBoost 本身无法处理分类变量,而是像随机森林一样,只接受数值数据。因此在将分类数据传入 XGBoost 之前,必须通过各种编码方式:例如标记编码、均值编码或独热编码对数据进行处理。

超参数中的相似性

在这里插入图片描述

结果对比

在一次预测任务中,我对比了结果,下面是结果分析:

为了评估模型,我们应该同时考虑模型的速度和准确度表现。

请记住,CatBoost 在测试集上表现得最好,测试集的准确度最高(0.816)、过拟合程度最小(在训练集和测试集上的准确度很接近)以及最小的预测和调试时间。但这个表现仅仅在有分类特征,而且调节了独热最大量时才会出现。如果不利用 CatBoost 算法在这些特征上的优势,它的表现效果就会变成最差的:仅有 0.752 的准确度。因此我们认为,只有在数据中包含分类变量,同时我们适当地调节了这些变量时,CatBoost 才会表现很好。

第二个使用的是 XGBoost,它的表现也相当不错。即使不考虑数据集包含有转换成数值变量之后能使用的分类变量,它的准确率也和 CatBoost 非常接近了。但是,XGBoost 唯一的问题是:它太慢了。尤其是对它进行调参,非常令人崩溃(我用了 6 个小时来运行 GridSearchCV——太糟糕了)。更好的选择是分别调参,而不是使用 GridSearchCV。

最后一个模型是 LightGBM,这里需要注意的一点是,在使用 CatBoost 特征时,LightGBM 在训练速度和准确度上的表现都非常差。我认为这是因为它在分类数据中使用了一些修正的均值编码方法,进而导致了过拟合(训练集准确率非常高:0.999,尤其是和测试集准确率相比之下)。但如果我们像使用 XGBoost 一样正常使用 LightGBM,它会比 XGBoost 更快地获得相似的准确度,如果不是更高的话(LGBM—0.785, XGBoost—0.789)。

最后必须指出,这些结论在这个特定的数据集下成立,在其他数据集中,它们可能正确,也可能并不正确。但在大多数情况下,XGBoost 都比另外两个算法慢。

总结:CatBoost自带的编码效果非常好,在处理有分类特征的预测任务的时候,效果好;XGB效果跟LGM相差无几但是速度太慢,需要自己事先对分类变量进行编码;LGM自带的编码效果不佳,但是如果按照XGB的事先进行编码,则效果会强于XGB

个人认为,XGB也许可以被LGB代替,CatBoost感觉会跟LGB重要性相当。

公众号回复【下载】有精选的免费机器学习学习资料。 公众号每天会更新一个机器学习、深度学习的小知识,都是面试官会问的知识点哦~

  • 【机器学习的基础数学(PDF)】
  • 【竞赛中的大数据处理流程(PDF)】
  • 【如何做大数据的基础特征工程(PDF)】
  • 【自然语言处理NLP的应用实践大合集(PDF)】
  • 【python入门级教材(400页PDF)】

公众号每天会更新一个机器学习、深度学习的小知识,都是面试官会问的知识点哦~

在这里插入图片描述

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值