XGBoost全称 “Extreme Gradient Boosting“,陈天奇大佬提出来的梯度提升模型。

Part A: 目标函数推导

目标函数的基本形式

模型对于某个样本的预测值为:

是基学习器,最终模型是多个基学习器

最初的目标函数可以写成

:是前t-1个集成学习器对样本的预测值
:是当前学习器对样本的预测值
:是第t个学习器的正则项

对目标函数进行泰勒二阶展开

:为
函数对
的一阶导数
:为
函数对
的二阶导数

正则项

接下来,将正则项具体化为如下的式子

表示叶子节点的个数,模型中将叶子节点的个数作为L1正则项,将叶子节点的权重值作为L2正则项。

这个叶子节点的权重,有的资料上成为叶子节点上输出的score,实际上就是预测值。

化简

并将原本单独的样本按照最终所在的叶子节点进行归类,令

表示样本
被划分到编号为j的叶子节点上

最终形式

对待求变量求导

求偏导并令其等于0,我们就能得到最终的
的解析解如下:

目标函数的值

代入原来的目标函数,我们就能得到原来目标函数的最终值。

这个式子表示在给定的决策树q下的目标函数的值,一定要注意,括号里加个q表示这是确定的一个树。

Part B: 分裂点的选择

分裂依据

由面我们推倒出Xgboost 目标函数(损失函数)的表达形式为

其实际意义表示按照特定分裂点(即按照某种树的结构)分裂后产生的损失值

其中

表示被分到编号为j的个叶子节点的样本

这样,我们可以得到样本群

依据某个特征值分裂后的损失函数的减小值
,将其作为分裂时的依据。

其中:

表示分裂后形成的两拨样本

有了节点分裂的依据,那么我们在基学习器中就可以生成树的结构,也就如何选择分裂点。

论文中共介绍了三种分裂点选择方法,

  • 第一种“Exact Greedy Algorithm for Split Finding”,是一种利用穷举法选择最佳的分裂节点
  • 第二种“Approximate Algorithm for Split Finding”,通过加权分位数方法近似选择最佳的分裂节点
  • 第三种“Sparsity-aware Split Finding”,针对稀疏特征的分裂点选择法

(一)Exact Greedy Algorithm for Split Finding 精确贪心算法

算法如上图所示,核心思想如下

  • 两个for循环,第一个for遍历所有特征,第二个for找出最佳的特征值作为分裂点
  • 选分裂点的依据score为分裂前后损失函数的减少量
  • 第二个for循环中,先对数据按照特征值进行排序,这样做的目的为了后面一次遍历就能求出所有分裂点的score值。
    只需要在当前的基础上进行加减,不需要再扫描所有数据
  • 贪心算法体现在,当前分裂点的选择只考虑能使得当前损失函数减少量最大

(二)Approximate Algorithm for Split Finding 近似分割算法

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

加权分位数算法

近似分割算法的核心是加权分位数算法,首先介绍分位数点。比如有下面10个样本数据,已经排好序了

分位数点

value: 1 1 2 3 4 5 5 6 7 8
rank :  1 2 3 4 5 6 7 8 9 10

那么0.3分数点的值是多少呢,对应的rank为10*0.3 =3,对应的值为2。这就是分位数点的基本思想,我们只要选出一些合适的分位数点然后遍历然后取遍历他们,就能达到和穷举法相同的精确程度。

加权分位数

因为我们要均分的是loss,而不是样本的数量,而每个样本对loss的贡献可能是不一样的,按样本均分会导致loss分布不均匀,取到的分位点会有偏差。所以要在每个样本前面加个权重。而目标函数又可以化简为如下的形式,所谓我们可以将二阶偏导

作为权重。

样本的权重定义好之后,我们就能定义rank函数

表示第k个特征中特征值小于z的样本所占的加权比例。

举个例子来理解加权分位点:

99对应的分位点就是(0.1 * 6+0.4+0.2)/(0.1 * 6+0.4+0.2+0.6) = 2/3

这样我们就能选出一些候选分割点

,并让他们满足下面的条件:

这样,我们就选出了大约

候选分割点,对这些分割点进行枚举遍历,选出最佳的分割点即可。

需要注意是:引入的分割不一定会使得情况变好,因为在引入分割的同时也引入新叶子的惩罚项。所以通常需要设定一个阈值,如果引入的分割带来的增益小于一个阀值的时候,我们可以剪掉这个分割。此外在XGBoost的具体实践中,通常会设置树的深度来控制树的复杂度,避免单个树过于复杂带来的过拟合问题。

关于上述两个算法的小结

QA:为什么近似分割算法比精确贪心算法要快?

首先我们得捋一下这两个寻找最佳分裂点的时候都有哪些公共的时间开销

  • 预排序:每个特征都是按照排序好的顺序存储的,这一部分在存储的时候就已经完成了
  • 计算所有样本的一阶导G和二阶导L,这个过程只需要进行一次
  • 对样本的G和L累加求和,这个过程也只需要进行一次,为了后续做差加速
    • 精确贪心算法中是将所有样本G、L累加
    • 近似分割算法中是按桶累加
  • 算法中的两个for循环,第一个循环是遍历所有特征,这一步两个算法相同

不同的开销在于,两个算法中第二个for循环中:

  • 精确贪心算法遍历的所有样本 O(#feature x # samples)
  • 近似贪心算法遍历了所有桶 : O(#feature x # bins )

因为桶的数目远小于样本数,所以得以加速

(三)Sparsity-aware Split Finding 稀疏特征处理

Xgboost 在处理带缺失值的特征时,先对非缺失的样本进行排序,对该特征缺失的样本先不处理,然后在遍历每个分裂点时,将这些缺失样本分别划入左子树和右子树来计算损失然后求最优。

如果训练样本中没有缺失值,而预测过程中出现了缺失值,那么样本会被默认分到右子树。

Part C: 分块并行与缓存优化

XGBoost的并行不是树粒度的而是特征粒度的,随机森林就是树粒度的并行。

寻找分裂点的时候,算法中先是遍历所有特征再遍历每个特征下的所有值。

遍历特征下所有值时要求值是排序好的,这样就可以使用差加速。

如果不排序,那么计算分类时候的损失函数减少量就没法达到O(1)的复杂度,因为二叉树的分裂是> x,分到a子树这样的形式。

在建树的过程中,最耗时是找最优的切分点,而这个过程中,最耗时的部分是将数据排序。为了减少排序的时间,提出Block结构存储数据。

  • Block中的数据以稀疏格式CSC进行存储
  • Block中的特征进行排序(不对缺失值排序,**排序只有一次**)
  • Block 中特征还需存储指向样本的索引,这样才能根据特征的值来取梯度。
  • 一个Block中存储一个或多个特征的值

个人理解是,这个block是原样本的一种映射,在这个block里,"样本"是按照列存储的,其实他存储的是列,而不是样本。因为样本是按照行来组织的,block中存储的是原样本的各个排序后的列。

所以就要有列中的每个元素与原样本之间的映射关系,因为在分裂节点的选择时,不仅要遍历某个特征(即列)中的所有元素,还要用到原样本的梯度(一阶导和二阶导), 所以就要通过列中的元素找到原样本。

按照block存储的好处就是,不同列之间可以并行查找,并且因为预排序了所以使得分裂节点查找时更快。坏处是空间大了一倍

缓存优化

在分块并行中,block存储了排序的列,并建立和原来样本的一一映射,这样可以通过索来找到原始样本获得梯度,但是原始样本是存放是按照列值的原始顺序的(相邻内存的样本他们对应的列值可能不是连续的,而我们现在根据排序后的列值来找原样本,那么肯定会出现在内存上的跳跃式查找,就非连续内存访问,可能导致CPU cache命中率降低。

CPU cache命中率低对于加权分位数选择分裂点的方法没太大影响,因为其选择分裂点的时候本来就是跳跃着选的,但是对于精确贪心算法的效率影响就非常大了,因为其要遍历所有样本。

下图中,calculate 上下两个部分表示连续列值上计算G和H但是其对应的样本不连续。

红色字说明了连续列值对应的样本不连续性。

原论文中说

A naive implementation of split enumeration introduces immediate read/write dependency between the accumulation and the non-continuous memory fetch operation

通过降低读写的依赖性来解决cache miss的问题

1.对于精确贪心算法,对每个线程分配一个连续的缓存空间,预取接下来要读取的数据,这样就降低了直接从内存读取并且cache miss消耗的时间。

2. 对于近似分割算法,选取适当的block大小即可(2^16 * each_sample_size)

###### 参考资料

『我爱机器学习』集成学习(三)XGBoost - 细语呢喃

https://arxiv.org/pdf/1603.02754.pdf

xgboost算法_【模型篇】XGBoost模型相关推荐

  1. xgboost算法_详解xgboost算法的样本不平衡问题

    XGBoost官方文档对参数scale_pos_weight的定义: 翻译: 调节正负样本权重的平衡 ,常用来处理不平衡的正负样本数据 . 典型值算法: scale_pos_weight = 负样本总 ...

  2. ML之XGBoost:利用XGBoost算法对波士顿数据集回归预测(模型调参【2种方法,ShuffleSplit+GridSearchCV、TimeSeriesSplitGSCV】、模型评估)

    ML之XGBoost:利用XGBoost算法对波士顿数据集回归预测(模型调参[2种方法,ShuffleSplit+GridSearchCV.TimeSeriesSplitGSCV].模型评估) 目录 ...

  3. xgboost算法_基于XGBoost算法构建投资组合

    摘要 极端梯度提升 (eXtreme Gradient Boosting) 是一种基于决策树的集成机器学习方法,适用于分类和回归问题.其优点是速度快.效果好.能处理大规模数据.支持自定义损失函数等. ...

  4. python xgboost参数_如何对XGBoost模型进行参数调优

    匿名用户 1级 2017-01-19 回答 XGBoost参数调优完全指南(附Python代码) 译注:文内提供的代码和运行结果有一定差异,可以从这里下载完整代码对照参考.另外,我自己跟着教程做的时候 ...

  5. xgboost算法_第113天: Python XGBoost 算法项目实战

    Python 实现机器学习 如果你的机器学习预测模型表现得不尽如人意,那就用XGBoost.XGBoost算法现在已经成为很多数据工程师的重要武器. XGBoost 算法 说到XGBoost,不得不提 ...

  6. xgboost算法_工业大数据:分析算法

    一. 应用背景 大数据分析模型的研究可以分为3个层次,即描述分析(探索历史数据并描述发生了什么).预测分析(未来的概率和趋势)和规范分析(对未来的决策给出建议).工业大数据分析的理论和技术研究仍处于起 ...

  7. xgboost算法_回归建模的时代已结束,算法XGBoost统治机器学习世界

    作者 | 冯鸥 发布 | ATYUN订阅号 Vishal Morde讲了这样一个故事:十五年前我刚完成研究生课程,并以分析师的身份加入了一家全球投资银行.在我工作的第一天,我试着回忆我学过的一切.与此 ...

  8. xgboost算法_手把手机器学习实战系列:xgboost 算法

    算法简介 xgboost算法是一种boosting的集成学习算法,是将多个弱学习模型进行组合,从而获得更好的效果,使得组合后的模型有更强的泛化能力, 它通常是由基本的回归树(CART)树模型组成 如图 ...

  9. xgboost算法_飞速精确的XGboost算法时代|Python算法回归预测

    线性回归.BP神经网络.支持向量机.随机森林算法对比 一.概念 各种模型算法概念可以参考往期文章: 开通头条号|细思极恐!股票价格竟是可预测Python集成算法 二.关于XGboost回归预测锂电池的 ...

  10. 第三章 模型篇:模型与模型的搭建

    写在前面的话 这部分只解释代码,不对线性层(全连接层),卷积层等layer的原理进行解释. 尽量写的比较全了,但是自身水平有限,不太确定是否有遗漏重要的部分. 教程参考: https://pytorc ...

最新文章

  1. jenkins-svn配置
  2. OpenCV学习笔记七-创建滑动条
  3. Swoole 源码分析——内存模块之内存池
  4. 上交大博导:写给不想做学术的你
  5. 怎样把连续的多个commit整理成1个?
  6. linux php任务计划,linux系统怎么添加计划任务执行php文件
  7. jQuery源码解析(2)—— Callback、Deferred异步编程
  8. Spring Boot 中使⽤ Cache 缓存的使⽤
  9. POSIX定时器Timer
  10. FFmpeg — 屏幕录制器材
  11. Window环境下使用C#调用VBScript、JavaScript等脚本
  12. 图像分割(一)--综述
  13. estore简版商城问题总结
  14. Linux 平台上的软件包管理
  15. 楷书书法规则_写好楷书的五条规律,不懂这些,书法就很难入门
  16. 关于Chandrashekhar阿扎德概述
  17. 时间序列分析教程(一):基本性质
  18. transformer的简要解读(应该都能看懂)
  19. Android屏蔽呼出电话提示音,Android来电拦截及拦截后的提示音
  20. 信道容量、数字基带与带通传输系统误码率公式整理

热门文章

  1. 自然语言处理NLP星空智能对话机器人系列:深入理解Transformer自然语言处理 Workshop on Machine Translation (WMT)
  2. easypoi 动态获取表头
  3. JavaScript中字符串拼接
  4. 关于三极管Ube在电路中变化的疑问
  5. wangeditor扩展:借用API实现latex的公式渲染
  6. 第三十章 光照及贴图总结
  7. 织梦仿站系列教程第十一讲——幻灯片的制作
  8. Nginx安装与启动
  9. 次世代3D游戏场景贴图绘制技巧,学起建模更简单!
  10. iOS开发 UIImage图片拼接