XGBoost原理学习总结

前言

​ XGBoost是一个上限提别高的机器学习算法,和Adaboost、GBDT等都属于Boosting类集成算法。虽然现在深度学习算法大行其道,但很多数据量往往没有太大,无法支持神经网络,并且如风控等一些业务需要可解释的算法模型,所以XGBoost等一众集成学习算法还是有很大的用武之地的。最近在一直准备找工作,重新复盘机器学习算法,所以把最近学得的东西记录在此,方便之后学习回顾。

1. XGBoost与GBDT的联系与区别

​ XGBoost具体上是GBDT的工程实现,但是有很多细节进行了具体的改进,具体上主要有以下三点:

(1) 算法本身的优化

​ 在算法的弱学习器模型选择上,对比GBDT只支持决策树,还可以直接很多其他的弱学习器。在算法的损失函数上,除了本身的损失,还加上了正则化部分。在算法的优化方式上,GBDT的损失函数只对误差部分做负梯度(一阶泰勒)展开,而XGBoost损失函数对误差部分做二阶泰勒展开,更加准确。算法本身的优化是我们后面讨论的重点。

(2) 算法运行效率的优化

​ 对每个弱学习器,比如决策树建立的过程做并行选择,找到合适的子树分裂特征和特征值。在并行选择之前,先对所有的特征的值进行排序分组,方便前面说的并行选择。对分组的特征,选择合适的分组大小,使用CPU缓存进行读取加速。将各个分组保存到多个硬盘以提高IO速度。

(3)算法健壮性优化

​ 对于缺失值的特征,通过枚举所有缺失值在当前节点是进入左子树还是右子树来决定缺失值的处理方式。算法本身加入了L1和L2正则化项,可以防止过拟合,泛化能力更强。

2. XGBoost的原理

原理概述:首先,像GBDT这类集成模型一样,确定一棵树的损失函数,由两部分组成,一部分是预测值与真实值的偏差,另一部分是正则项。接下来的目的就是通过二级泰勒展开式简化损失函数,为下一步寻找损失函数的最小值做准备。此时,是一个含有一次和二次导数的损失函数,并且损失函数是在n个CART决策树上迭代产生的。然后,经过损失函数变形,转化为在不同叶子节点上迭代,通过偏导计算,可得在此节点的最优权重。在选择CART决策树的分裂特征值时,不是采用一般的均方误差,而是根据之前计算的损失函数确定的。

(1)XGBoost的损失函数

​ XGBoost的损失函数与一般的GBDT集成算法类似,都是表示预测值与真实值的偏差,不同的是,XGBoost的损失函数增添了正则项,具体公式如下:
\[
L(\phi)=\sum_il(\widehat y_i,y_i)+\sum_i\Omega(f_k) \\
where\ \Omega(f)=\gamma T+\dfrac{1}{2}\lambda||w||^2\tag{1}
\]
​ 上式中\(\Omega(f)\)表示正则化项,其中\(T\)为叶子节点数,\(\omega\)为每个叶子节点的权重大小。

​ 泰勒级数的公式为:
\[
\begin{array}{*{20}{l}}
{f{ \left( {x} \right) }=\mathop{ \sum }\limits_{{n=0}}^{{ \infty }}\frac{{1}}{{n!}}\mathop{{f}}\nolimits^{{n}}{ \left( {\mathop{{x}}\nolimits_{{0}}} \right) }{\mathop{{ \left( {x-\mathop{{x}}\nolimits_{{0}}} \right) }}\nolimits^{{n}}},x \in U{ \left( {\mathop{{x}}\nolimits_{{0}}} \right) }}\tag{2}\\
\end{array}
\]
​ 由泰勒级数可以将(1)式的损失函数进行化简。
\[
L(t)=\sum_i^nl(y_i,\widehat y_i^{(t-1)}+f_t(X_i))+\sum_i\Omega(f_k) \tag{3}
\]
​ 将上式中的\(f_t(X_i))\)用二阶泰勒级数展开,得到如下(4)式:
\[
L^{(t)}\approx\sum_i^nl[(y_i,\widehat y_i^{(t-1)})+g_if_t(X_i)+h_i\dfrac{1}{2}f_t^2(X_i)]+\sum_i\Omega(f_t) \tag{4}
\]
​ 将上式中常数项\(l(y_i,\widehat y_i^{t-1})\)省略,因为前\(t-1\)颗数已经生成,不会对当前决策树生产生影响。并将以n颗数遍历得到损失函数变换为以T个叶子节点遍历得到损失函数。
\[
\tilde L^{(t)}=\sum_{i=1}^n[g_if_t(X_i)+h_i\dfrac{1}{2}f_t^2(X_i)]+\gamma T+\dfrac{1}{2}\lambda\sum_{j=1}^Tw_j^2\\
=\sum_{j=1}^T[(\sum_{i\in I_j}g_i)w_j+\dfrac{1}{2}(\sum_{i\in I_j}h_i+\lambda)w_j^2]+\gamma T\tag{5}
\]

(2)通过损失函数,寻找最优权重

​ 如果我们已经求出了第t个决策树的J个最优的叶子节点区域,如何求出每个叶子节点区域的最优解呢?通过式(5),可以通过迭代每个叶子节点来计算决策树总体的损失函数。为了使总体的损失函数最小,在进行迭代时使用贪心的思想,使每一个叶子节点的损失函数最小,具体方法通过对损失函数求\(\omega_j\)的导数,并令其为0,计算得\(w\)权重如下:
\[
w_j^*=-\dfrac{\sum_{i\in I_j}g_i}{\sum_{i\in I_j}h_i+\lambda}\tag{6}
\]
​ 当每个叶子节点\(w\)取得最优值时,损失函数的表达式可以改写为:
\[
\tilde L^{(t)}=-\dfrac{1}{2}\sum_{j=1}^T\dfrac{(\sum_{i\in I}^jg_i)^2}{\sum_{i\in I_j}h^i+\lambda}+\gamma T \tag{7}
\]

(3)决策树分裂的最优特征值计算

​ 通过上节已经可以确定叶子节点分裂后的最优解,但是在这之前还应该确定该叶子节点是否应该分裂,以及最优的特征分裂值。由式(7)的损失函数计算,计算每个叶子节点分裂后损失值的减少程度。
\[
L_{split}=L_{分裂前损失值}-(L_{分裂后左子树的损失值}+L_{分裂后右子树的损失值})\\
=\dfrac{1}{2}[\dfrac{(\sum_{i\in I_L}g_i)^2}{\sum_{i\in I_L}h_i+\lambda}+\dfrac{(\sum_{i\in I_R}g_i)^2}{\sum_{i\in I_R}h_i+\lambda}-\dfrac{(\sum_{i\in I}g_i)^2}{\sum_{i\in I}h_i+\lambda}]-\gamma\tag{8}
\]
​ 遍历此特征的全部数值,当\(L_{split}\)大于0,且取到最大值时确定最优特征值;如果都小于等于0,则此节点分裂结束。

(4)XGBoost算法中其他方面的优化

  • XGBoost的并行计算

​ XGBoost为boosting系列集成算法,实质上是不能进行并行计算的,但这里说的并行计算实际上是在构建决策树时进行特征搜索是并行的,在此之前各个特征就已经排好序被存储block中。

  • 特征分裂值的选取有两种方法

​ 第一就是上文中使用的逐值遍历的方法,文中称为Basic Exact Greedy Algorithm;另一种就是近似分割算法, 精确贪心算法虽然很强大,但是当数据无法完全加载到内存中或者在分布式的条件下,这种基于穷举的分裂点寻找方法效率就会非常低下。于是作者提出了一种近似分割的算法,这种算法首先通过加权分位数的算法选出了一些可能的分裂点,然后再遍历这些较少的分裂点来找到最佳分裂点。

  • 通过收缩步长和列采样的方法来避免过拟合

收缩步长即在每一次迭代的过程中,对拟合的残差乘以一个收缩系数,从而限制当前迭代过程的学习步长;列采样即本次迭代参与优化的特征维度并不是所有的维度,而是通过采样得到的维度,更少的选择会让算法不容易将训练集的残差拟合得过好,从而造成过拟合;

3. XGBoost常见问题总结

(1)XGBoost为什么通过二阶泰勒级数展开优化损失函数?

​ 首先,采用二阶泰勒级数足以接近损失函数;通过引入二阶泰勒级数把损失函数化简有利于后续的计算,例如,将在不同决策树迭代计算损失函数转化为在不同叶子节点上迭代产生损失函数;还有就是有利于算法本身的可扩展性。

(2)XGBoost是怎样处理缺失值的?

​ XGBoost 在处理带缺失值的特征时,先对非缺失的样本进行排序,对该特征缺失的样本先不处理,然后在遍历每个分裂点时,将这些缺失样本分别划入左子树和右子树来计算损失然后求最优。如果训练样本中没有缺失值,而预测过程中出现了缺失值,那么样本会被默认分到右子树。

XGBoost原理学习总结的更多相关文章

  1. 【Python机器学习实战】决策树与集成学习(六)——集成学习(4)XGBoost原理篇

    XGBoost是陈天奇等人开发的一个开源项目,前文提到XGBoost是GBDT的一种提升和变异形式,其本质上还是一个GBDT,但力争将GBDT的性能发挥到极致,因此这里的X指代的"Extre ...

  2. xgboost原理及应用

    1.背景 关于xgboost的原理网络上的资源很少,大多数还停留在应用层面,本文通过学习陈天奇博士的PPT 地址和xgboost导读和实战 地址,希望对xgboost原理进行深入理解. 2.xgboo ...

  3. 一文读懂机器学习大杀器XGBoost原理

    http://blog.itpub.net/31542119/viewspace-2199549/ XGBoost是boosting算法的其中一种.Boosting算法的思想是将许多弱分类器集成在一起 ...

  4. xgboost原理

    出处http://blog.csdn.net/a819825294 1.序 距离上一次编辑将近10个月,幸得爱可可老师(微博)推荐,访问量陡增.最近毕业论文与xgboost相关,于是重新写一下这篇文章 ...

  5. xgboost原理及应用--转

    1.背景 关于xgboost的原理网络上的资源很少,大多数还停留在应用层面,本文通过学习陈天奇博士的PPT地址和xgboost导读和实战 地址,希望对xgboost原理进行深入理解. 2.xgboos ...

  6. xgboost原理总结和代码展示

    关于xgboost的学习推荐两篇博客,每篇看2遍,我都能看懂,你肯定没问题 两篇方法互通,知识点互补!记录下来,方便以后查看 第一篇:作者:milter链接:https://www.jianshu.c ...

  7. XGBoost 原理及应用

    xgboost原理及应用--转   1.背景 关于xgboost的原理网络上的资源很少,大多数还停留在应用层面,本文通过学习陈天奇博士的PPT地址和xgboost导读和实战 地址,希望对xgboost ...

  8. XGBoost原理简介

    XGBoost是GBDT的改进和重要实现,主要在于: 提出稀疏感知(sparsity-aware)算法. 加权分位数快速近似学习算法. 缓存访问模式,数据压缩和分片上的实现上的改进. 加入了Shrin ...

  9. xgboost原理与实战

    目录 xgboost原理 xgboost和gbdt的区别 xgboost安装 实战 xgboost原理 xgboost是一个提升模型,即训练多个分类器,然后将这些分类器串联起来,达到最终的预测效果.每 ...

随机推荐

  1. java连接elasticsearch:查询、添加数据

    导入jar包 <!-- https://mvnrepository.com/artifact/org.elasticsearch.client/transport --> <depe ...

  2. 002使用eop来烧写程序

  3. Verilog门级建模

    门级建模就是将逻辑电路图用HDL规定的文本语言表示出来,即调用Verilog语言中内置的基本门级元件描述逻辑图中的元件以及元件之间的连接关系. Verilog语言内置了12个基本门级元件模型,如下表所 ...

  4. $Noip2018/Luogu5022$ 旅行

    $Luogu$ $Description$ 一个$n$个点,$m$条边的图.$m=n-1$或$m=n$.任意选取一点作为起始点,可以去往一个没去过的点,或者回到第一次到达这个点时来自的点.要求遍历整个 ...

  5. CommandPattern(命令模式)-----Java/.Net

    命令模式(Command Pattern)是一种数据驱动的设计模式,它属于行为型模式.请求以命令的形式包裹在对象中,并传给调用对象.调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该 ...

  6. [技术翻译]使用Nuxt生成静态网站

    本周再来翻译一些技术文章,本次预计翻译三篇文章如下: 04.[译]使用Nuxt生成静态网站(Generate Static Websites with Nuxt) 05.[译]Web网页内容是如何影响 ...

  7. (httpd、php)2

    (一)再说编译安装httpd2.4 新特性: 1:MPM(多处理模块)支持运行为DSO(动态共享,动态加载模式)机制,以模块形式按需加载,支持动态加载 2:event MPM生产环境可用 3:支持异步 ...

  8. bat无法识别命令、无法识别运算符、结果不符合预期等问题

    1.无法识别的命令等可能为中文字符编码等问题,破坏了bat文件格式,建议去掉中文,加上引号或者重新创建文件.例如:@echo off%~d0cd /d %~dp0title epoch时间转换(%cd ...

  9. 用Eclipse和Tomcat搭建一个本地服务器

    服务器软件环境 Eclipse oxygen Tomcat 9.0 SQL Sever 2014 参考资料 https://blog.csdn.net/qq_21154101/article/deta ...

  10. 关于MySQL幻读的实验

    该实验基于 CentOS 7 + MySQL 5.7 进行 打开两个窗口连接到MySQL 第一个连接的事务我们命名为  T1 第二个连接的事务我们命名为 T2 T2 发生在 T1 的 O1 操作结束以 ...