XGBoost的基本原理

XGBoost的基本原理XGBoost原理与实践

大家好,又见面了,我是你们的朋友全栈君。

说明:本文是阅读XGBoost有关的论文和一些博客后的入门笔记。有什么不足之处还望大家多多赐教,欢迎交流,转载。

一. 前言

  • XGBoost是提升方法中的一个可扩展的机器学习系统。XGBoost在许多机器学习和数据挖掘问题中产生了广泛的影响。2015年发表在Kaggle竞赛的博客的29个冠军解决方案中,有17个是使用XGBoost解决的,其中有8个是仅使用了XGBoost方法去训练模型,剩余的是用XGBoost和其他模型相结合使用的。相比较而言,第二个受欢迎的方法是深度神经网络,有11个是使用该方法的。
  • XGBoost成功的最重要因素就是它在任何场景下的可扩展性。XGBoost系统在单台机器上的运行速度比现有流行的解决方案快10倍以上,并可在分布式或内存限制设置中扩展到数十亿个示例。XGBoost的可扩展性是由于在它的系统实现中的一些创新,包括:
    1. 为处理稀疏数据使用了一个新颖的树学习算法;
    2. 理论上合理的加权分位数草图过程,使得能够在近似树学习中处理实例权重;
    3. 平行和分布式计算使得学习更快,从而能够更快的进行模型探索;
    4. 最重要的是XGBoost使用核外计算并且能够让数据科学家在台式机上处理数以亿计的示例;
    5. 更令人兴奋的是结合这些技术使端到端系统以最少的集群资源扩展到更大的数据。

    下面开始介绍XGBoost的模型训练原理

  • 二. XGBoost原理

    1. 学习目标

    在讨论学习目标之前,先说一说XGBoost是如何预测输出值的。XGBoost是一个树集成模型,它使用的是K(树的总数为K)个树的每棵树对样本的预测值的和作为该样本在XGBoost系统中的预测,定义函数如下:
    这里写图片描述
    对于所给的数据集有n个样本,m个特征,定义为:
    这里写图片描述
    其中Xi表示第i个样本,yi表示第i个样本的类别标签。CART树的空间为F,如下:
    这里写图片描述
    其中q表示每棵树的结构映射每个样本到相应的叶节点的分数,即q表示树的模型,输入一个样本,根据模型将样本映射到叶节点输出预测的分数;Wq(x)表示树q的所有叶节点的分数组成集合;T是树q的叶节点数量。
    所以,由(1)式可以看出,XGBoost的预测值为每棵树的预测值之和,即每棵树相应的叶节点的得分之和(Wi的和,Wi表示第i个叶节点的得分)。
    我们的目标就是学习这样的K个树模型f(x).。为了学习模型f(x),我们定义下面的目标函数:
    这里写图片描述
    这里写图片描述
    其中,(2)式右边第一项为损失函数项,即训练误差,是一个可微的凸函数(比如用于回归的均方误差和用于分类的Logistic误差函数等),第二项为正则化项,即每棵树的复杂度之和,目的是控制模型的复杂度,防止过拟合。我们的目标是在L(φ)取得最小化时得出对应的模型f(x)。
    由于XGBoost模型中的优化参数是模型f(x),不是一个具体的值,所以不能用传统的优化方法在欧式空间中进行优化,而是采用additive training的方式去学习模型。每一次保留原来的模型不变,加入一个新的函数f到模型中,如下:
    这里写图片描述
    预测值在每一次迭代中加入一个新的函数f目的是使目标函数尽量最大地降低。
    因为我们的目标是最小化L(φ)时得到模型f(x),但是L(φ)中并没有参数f(x),所以,我们将上图中的最后一式代入L(φ)中可得到如下式子:
    这里写图片描述
    对于平方误差(用于回归)来说(3)式转换成如下形式:
    这里写图片描述
    对于不是平方误差的情况下,一般会采用泰勒展开式来定义一个近似的目标函数,以方便我们的进一步计算。
    根据如下的泰勒展开式,移除高阶无穷小项,得:
    这里写图片描述
    这里写图片描述
    (3)式等价于下面的式子:
    这里写图片描述
    由于我们的目标是求L(φ)最小化时的模型f(x)(也是变量),当移除常数项时模型的最小值变化,但是取最小值的变量不变(比如:y=x^2+C,无论C去何值,x都在0处取最小值)。所以,为了简化计算,我们移除常数项,得到如下的目标函数:
    这里写图片描述
    定义 这里写图片描述 为叶节点j的实例,重写(4)式,将关于树模型的迭代转换为关于树的叶子节点的迭代,得到如下过程:
    这里写图片描述
    此时我们的目标是求每棵树的叶节点j的分数Wj,求出Wj后,将每棵树的Wj相加,即可得到最终的预测的分数。而要想得到最优的Wj的值,即最小化我们的目标函数,所以上式对Wj求偏导,并令偏导数为0,算出此时的W*j为:
    这里写图片描述
    这里写图片描述
    将W*j代入原式得:
    这里写图片描述
    方程(5)可以用作得分(score)函数来测量树结构q的质量。该得分类似于评估决策树的不纯度得分,除了它是针对更广泛的目标函数得出的。下图表示得分(score)是如何被计算的:
    这里写图片描述
    由上图可以看出,当我们指定一颗树的结构的时候,每棵树的得分(score)只与损失函数的一阶导数和二阶倒数相关(γ和λ是在实际应用中需要自己调参的),而该得分表示我们在目标上面最多减少多少。我们可以把它叫做结构分数(structure score)。你可以认为这个就是类似吉尼系数一样更加一般的对于树结构进行打分的函数。
    到这里,我们的XGBoost学习目标的原理已经介绍完毕,接下来就是如何进行节点的切分了。

    2. 节点的划分

    树学习的其中之一的重要问题就是找到最好的节点划分,而节点划分的目的是寻找一个最优结构的树。假设IL和IR是一个节点切分后的左右节点,I等于IL和IR的并集。然后切分后的损失函数定义如下:
    这里写图片描述
    上面的式子通常在实践中被使用来评估切分的候选节点。我们的目标是希望找到一个特征及其对应的大小,使得上式取得最大值。
    节点划分有两种方式,一是基本精确的贪心算法(Basic Exact Greedy Algorithm),二是近似算法(Approximate Algorithm)。下面我们来分别介绍这两种方式。

    2.1 基本精确的贪心算法(Basic Exact Greedy Algorithm)

    为了找到节点最好的划分,该算法的原理是在所有特征上枚举所有的可能的划分,我们称这个算法为Basic Exact Greedy Algorithm。大多数已存在的单台机器上的树提升算法库都是用这种方法实现的,例如scikit-learn,R’s gbm 以及 XGBoost的单机版本都支持这种算法。该算法要求为连续特征枚举所有可能的切分,这对计算机的要求很高,所以该算法为了有效的做到这一点,首先根据特征值排序数据并且按照顺序访问数据,以累积方程(6)中结构分数的梯度统计量。该算法如下:
    这里写图片描述

    2.2 近似算法

    Basic Exact Greedy Algorithm是一个非常精确的算法,因为它枚举的所有可能的切分点。但是,当数据不能完全的加载到内存时,它可能不是特别有效地。同样的问题也出现在分布式的设置中。为了有效的支持在这两种设置中的有效的梯度提升,一个近似算法需要被使用。该算法首先根据特征分布的百分位数提出n个候选切分节点,然后,算法将位于相邻分位点之间的样本分在一个桶中,在遍历该特征的时候,只需要遍历各个分位点,从而计算最优划分。注意到上面算法流程中表明有全局的近似(global)和局部(local)的近似,所谓全局就是在新生成一棵树之前就对各个特征计算分位点并划分样本,之后在每次分裂过程中都采用近似划分,而局部就是在具体的某一次分裂节点的过程中采用近似算法。该算法如下所示:
    这里写图片描述
    以上两个算法都应用在了XGBoost中。
    接下来,最后一个问题就是近似算法中的如何根据分位数来提出候选切分点。

    2.3 带权重的分位数草图(Weighted Quantile Sketch)

    Weighted Quantile Sketch是近似算法中的一个重要步骤,主要用于解决近似算法中如何选取候选切分点的问题。通常,特征的百分位数用于使候选节点均匀地分布在数据上。也就是在特征集上选取一个百分数,然后根据这个百分数来依次的选取候选节点。比如某个特征的样本点是1~100,特征的百分位数设为2%,则候选节点的选择就是100*0.02*1=2,4,…,100。用数学公式表示,定义一个rank function,如下:
    这里写图片描述
    上式表示特征值k小于z的实例的比例。其中:
    这里写图片描述
    表示每个训练样本的第k个特征值和二阶梯度值。
    这里写图片描述
    其中ε是近似因子,也就是切分百分数。这意味着大概有1/ε个候选切分点。
    到这里,XGBoost的理论部分已经介绍完毕。有不足之处希望指出,一起学习。接下来就是介绍XGBoost的一些优缺点。

    三. XGBoost的优缺点:

    3.1 与GBDT相比:

    1)GBDT以传统CART作为基分类器,而XGBoost支持线性分类器,相当于引入L1和L2正则化项的逻辑回归(分类问题)和线性回归(回归问题);

    2)GBDT在优化时只用到一阶导数,XGBoost对代价函数做了二阶Talor展开,引入了一阶导数和二阶导数。XGBoost支持自定义的损失函数,只要是能满足二阶连续可导的函数均可以作为损失函数;

    3)XGBoost在损失函数中引入正则化项,用于控制模型的复杂度。正则化项包含全部叶子节点的个数,每个叶子节点输出的score的L2模的平方和。从Bias-variance tradeoff角度考虑,正则项降低了模型的方差,防止模型过拟合,这也是xgboost优于传统GBDT的一个特性。

    4)当样本存在缺失值是,xgBoosting能自动学习分裂方向,即XGBoost对样本缺失值不敏感;

    5)XGBoost借鉴RF的做法,支持列抽样,这样不仅能防止过拟合,还能降低计算,这也是xgboost异于传统gbdt的一个特性。

    6)XGBoost在每次迭代之后,会将叶子节点的权重乘上一个学习率(相当于XGBoost中的eta,论文中的Shrinkage),主要是为了削弱每棵树的影响,让后面有更大的学习空间。实际应用中,一般把eta设置得小一点,然后迭代次数设置得大一点;

    7)XGBoost工具支持并行,但并行不是tree粒度的并行,XGBoost也是一次迭代完才能进行下一次迭代的(第t次迭代的代价函数里包含了前面t-1次迭代的预测值),XGBoost的并行是在特征粒度上的。XGBoost在训练之前,预先对数据进行了排序,然后保存为(block)结构,后面的迭代中重复地使用这个结构,大大减小计算量。这个块结构也使得并行成为了可能,在进行节点的分裂时,需要计算每个特征的增益,最终选增益最大的那个特征去做分裂,那么各个特征的增益计算就可以开多线程进行;

    8)可并行的近似直方图算法,树结点在进行分裂时,需要计算每个节点的增益,若数据量较大,对所有节点的特征进行排序,遍历的得到最优分割点,这种贪心法异常耗时,这时引进近似直方图算法,用于生成高效的分割点,即用分裂后的某种值减去分裂前的某种值,获得增益,为了限制树的增长,引入阈值,当增益大于阈值时,进行分裂;

    9) XGBoost的原生语言为C/C++,这是也是它训练速度快的一个原因。

    3.2 与LightGBM相比:

    1)XGBoost采用预排序,在迭代之前,对结点的特征做预排序,遍历选择最优分割点,数据量大时,贪心法耗时,LightGBM方法采用histogram算法,占用的内存低,数据分割的复杂度更低,但是不能找到最精确的数据分割点;

    2)XGBoost采用level-wise生成决策树策略,同时分裂同一层的叶子,从而进行多线程优化,不容易过拟合,但很多叶子节点的分裂增益较低,没必要进行更进一步的分裂,这就带来了不必要的开销;LightGBM采用leaf-wise生长策略,每次从当前叶子中选择增益最大的叶子进行分裂,如此循环,但会生长出更深的决策树,产生过拟合,因此 LightGBM 在leaf-wise之上增加了一个最大深度的限制,在保证高效率的同时防止过拟合)。另一个比较巧妙的优化是 histogram 做差加速。一个容易观察到的现象:一个叶子的直方图可以由它的父亲节点的直方图与它兄弟的直方图做差得到。

    四. 参考文献/博文

    1. XGBoost: A Scalable Tree Boosting System(XGBoost原论文)
    2. 陈天奇的XGBoost ppt
    3. https://blog.csdn.net/xwd18280820053/article/details/68927422
    4. http://www.52cs.org/?p=429
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/138711.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • Android Studio Button背景颜色无法修改「建议收藏」

    Android Studio Button背景颜色无法修改「建议收藏」关于AndroidStudioButton背景无法修改,一直呈现亮紫色作为安卓初学者,发现Button的背景颜色无法修改,也没法链接到drawable的样式xml文件,前前后后折腾了好久,查阅了CSDN发现是新版本主题文件的问题,将方法分享给有需要的人原因:由于新版本的主题问题导致解决方法:将app/res/values目录下的themes”<stylename=…”一句代码改成如下内容重启Androidstudio即可<stylename=”Theme.Androi

  • elasticsearch批量插入数据的时候出现java.net.SocketTimeoutException: 30,000 milliseconds timeout on connection「建议收藏」

    elasticsearch批量插入数据的时候出现java.net.SocketTimeoutException: 30,000 milliseconds timeout on connection「建议收藏」问题:elasticsearch每次都批量插入几万数据量,然后就会出现下列问题。看这个问题应该是配置的问题ERROR[https-jsse-nio-443-exec-4]2020-07-0923:31:54(EsMiniDaansouDataInfoWithBLOBsUtil.java:80)java.net.SocketTimeoutException:30,000millisecondstimeoutonconnectionhttp-outgoing-0[ACTIVE]

  • 关于旁路由设置后,主路由WIFI无法上网的问题「建议收藏」

    关于旁路由设置后,主路由WIFI无法上网的问题「建议收藏」前言旁路由设置好后,手机、电脑连接主路由WIFI,会无法访问外网。但是,如果电脑用网线连接主路由,则可以正常上网。这究竟是怎么一回事儿呢?1.旁路由解释旁路由:旁路由其实并不是路由,路由是用来连接不同网络的,最常用的就是用来连接互联网和局域网。旁路由起到的主要是网关的作用,是用来分流数据和扩展插件的。因此,严谨一点的叫法应该是旁路网关,只是大家好像约定俗成了都叫做旁路由,所以我们这里也跟着叫旁路由,但是要明白它的核心是网关而不是路由。2.网络流量示意图如图所示,对于普通流量,由于旁路

  • 将 VSCode 快捷键修改为 eclipse的快捷键[通俗易懂]

    将 VSCode 快捷键修改为 eclipse的快捷键[通俗易懂]文章目录1、VSCode中打开`命令面板`,如下图所示。2)在命令面板中输入`keyboard`3)打开`首选项:打开键盘快捷方式(JSON)`4)在`keybindings.json`中配置快捷键配置1(常用的快捷键)配置2(最全的快捷键)1、VSCode中打开命令面板,如下图所示。2)在命令面板中输入keyboard在命令面板中输入keyboard,然后在列表中选择首选项:打开键盘快捷方式(JSON):3)打开首选项:打开键盘快捷方式(JSON)点击

  • python udp发送数据(http视频传输)

    一、前言最近想写一个实时的视频传输程序,然后上网找了很久没有找到合适的我想用OpenCV进行图像采集,然后用pygame将视频信号转化为可通过UDP网络传输的字符流,然后到达终端后再通过pygame对字符流进行解析,进而将图像显示出来之所以使用UDP传输而不是TCP传输,是因为UDP在视频传输方面拥有快速、无需连接等优点,适合密集传送大量信息的场合但UDP传输有一个问题,…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号