XGBoost算法个人理解
提升树Boosting Tree算法实例详解_程大海的博客-CSDN博客
从提升树Boosting Tree过度到梯度提升Gradient Boosting_程大海的博客-CSDN博客
GBDT梯度提升之回归算法个人理解_程大海的博客-CSDN博客_梯度回归算法
GBDT梯度提升之二分类算法个人理解_程大海的博客-CSDN博客_gbdt二分类
GBDT梯度提升之多分类算法个人理解_程大海的博客-CSDN博客_gbdt可以多分类吗
XGBoost算法个人理解_程大海的博客-CSDN博客_xgboost 叶子节点权重
交叉熵损失与极大似然估计_程大海的博客-CSDN博客_极大似然估计和交叉熵
使用泰勒展开解释梯度下降方法参数更新过程_程大海的博客-CSDN博客
AdaBoost算法实例详解_程大海的博客-CSDN博客_adaboost算法实例
XGBoost算法仍然是一种使用加法模型和前向分布算法逐步逼近最优结果的Gradient boosting梯度提升方法。并且,XGBoost算法在目标函数中同时引入了正则化项(度量树模型的复杂度)用来降低模型过拟合的风险。
损失函数
其中,表示模型对于样本的预测损失,也叫经验误差。
表示模型的复杂度,也叫结构误差,起到正则化的作用。这个损失函数的形式类似于加入L1或L2正则化的逻辑回归损失函数。
二阶泰勒展开公式:
对应用二阶泰勒展开公式,其中
相当于
,
相当于
,
相当于
,
是一个函数模型,是一个自变量,作为最小的优化粒度,这也照应了Gradient Boosting梯度提升方法中所说的梯度提升方法是在函数空间中进行优化的说法。令
和
分别为经验损失函数
对
的一阶偏导和二阶偏导。
所以在进行第t轮迭代学习时,和
只和前t-1个已经确定的模型参数有关,与当前第t轮正在学习的模型参数无关,所以可以认为
和
是确定的常数。所以优化的目标函数
可以改写为:
其中只和前t-1个已经确定的模型参数有关,与当前第t轮正在学习的模型参数无关,可以看做一个常数。此时可以看到目标函数
是一个关于
的一元二次函数,后面关于XGBoost为什么要使用二阶泰勒展开的讨论中再说一下。
正则项(模型复杂度)
是正则化项,用于控制树的复杂度,
和叶子节点个数、叶子节点权重有关。首先将一棵树
定义如下:
这里 表示树叶上的权重,
是一个将每个数据样本点
分配给叶子节点的函数,
是树叶的数量。 在 XGBoost算法中,将一棵树的复杂度定义为叶子结点的个数和树叶权重的L2范数的函数:
其中叶子节点的个数表示树的规模大小,树叶权重的L2范数表示叶子节点权重的平滑程度。
优化目标
减小,也就是说使
和
都减小,也就是得到的模型预测结果更准确的同时,模型更简单,也就是奥卡姆剃刀原理。
需要求解的优化目标就是得到每棵树的结构,以及对应叶子节点的权重。对上面的优化目标做一下转换,由于
和
与当前第t轮学习的模型参数无关,且
表示的是样本
所在叶子节点的权重,所以可以将目标函数
转化为当前第t轮得到的决策树所有叶子节点目标函数的累加和:
将遍历所有样本求损失转换为遍历所有叶子节点上的样本求损失,因为样本终究会落在叶子节点上。其中,表示落在第j个叶子节点上的样本集合,
表示i是落在第j个叶子节点上的样本集合中的样本。这样转换的好处就是,当树结构也就是
确定的情况下,由于一棵树叶子节点的权重计算与其他叶子节点无关,可以同时对
个叶子节点进行并行优化,提升优化速度,当每个叶子结点的子式都达到最值点时,整个目标函数
才达到最值点。同时,由于使用了二阶导数和L2正则化项,经过此转换后将每个叶子节点的优化函数转换成了一个关于
的一元二次函数,便于直接使用求根公式进行求解(解析解)。
XGBoost为什么要使用二阶导数?
参照MSE损失函数的优化过程,关于二次方程的最优解可以直接计算一阶导数等于0计算得到,但是对于一般损失函数,没有MSE这种凸函数的性质,无法通过一阶导数为0计算最优结果。然而,在二阶泰勒展开中会自然的引入变量的二次项,这样方便通过直接计算一阶导数为0得到优化结果。
最终优化目标转换为关于第 t 轮函数的一元二次函数,可以使用求解公式求解最优解,这也是引入二阶导数的目的,便于使用求解公式求解。
确定树结构
前面说过,当树结构确定的情况下,可以使用求根公式求解每个叶子节点的权重。那么怎么才能快速的确定树的结构呢?
XGBoost的基模型可以是决策树和线型模型,当基模型是线性模型时,目标函数就相当于是同时使用了L1和L2正则化的线性回归模型。当基模型是决策树模型时,需要计算决策树的结构。
贪心算法
从树的深度0开始,计算所有特征的最佳分裂点,选择分裂收益最大的特征分裂点进行分裂左右分支,类似于ID3、C4.5和CART决策树算法的分裂规则。区别仅在于分裂原则不同,XGBoost的分裂原则是自己定义了一套计算收益的规则,而ID3则是信息增益。
对每个叶节点枚举所有的可用特征;
计算分裂收益:针对每个特征,把属于该节点的训练样本根据该特征值进行升序排列,通过线性扫描的方式来决定该特征的最佳分裂点,并记录该特征的分裂收益;
选择分裂特征:选择收益最大的特征作为分裂特征,用该特征的最佳分裂点作为分裂位置,在该节点上分裂出左右两个新的叶节点,并为每个新节点关联对应的样本集;
递归迭代:回到第1步,递归执行直到满足特定条件为止;
分裂规则:计算分裂前的目标函数值,计算分裂后的目标函数值(包含分裂后的左右子树),计算分裂后的目标函数收益
可以在这里看到一个重要的事实:如果增益小于gamma,最好不要添加那个分支,这样也可以起到防止过拟合的作用。
近似算法
贪心算法的计算量大,需要计算每个特征在每个可能的分裂位置的分裂收益,当训练数据量太大时,无法一次性全部加载入内存计算每个特征在每个可能的分裂位置的分裂收益。近似算法对于每个特征进行分位数离散化分桶,只考察分位点,计算在分位点位置的分裂收益,可以减少特征的分裂位置计算数量,降低计算复杂度。
两种特征离散化分桶策略:
Global全局模式:学习每棵树前就提出候选切分点,并在每次分裂时都采用这种分割,计算的是全部样本每个特征的分位数,然后进行离散化分桶
Local局部模式:每次分裂前将重新提出候选切分点,计算的是落在当前待分裂叶子节点上样本每个特征的分位数,然后进行离散化分桶。
特性:Local策略对于每个待分裂的叶子结点,分别计算当前叶子节点上样本特征的分位数,计算量小,分位数计算精细,但是需要更多的计算步骤。而Global策略因为节点已有划分,如果想得到与Local同样的分位数分桶粒度,需要划分更多的候选点,也就是分更多的桶。
上图中表示算法的精度,其倒数表示分位数分桶的数量,也就是分桶的粒度大小,粒度越大精度越低,粒度越小精度越高,过拟合的风险也越大。在上图中
的情况下,Local的精度要远高于Global的精度,这也就是上文中说的,如果Global想得到与Local相同的计算精度,需要分更多的桶。当Global的
时,分的桶更多,同时Global也达到了了与Local
相当的精度。同时近似算法也可以得到与贪心算法相当的精度。
分别以每个分位点作为切分点,计算切分前后的目标函数收益,选择目标函数收益最大的切分点。
预测结果
回归问题:
二分类问题:
多分类问题:
XGBoost每一轮拟合的目标是什么?
我们都知道提升树算法拟合的是残差,梯度提升算法拟合的是损失函数负梯度在当前模型的值,其实拟合的也是残差。而通过上面描述的XGBoost算法可知,XGBoost算法与提升树和梯度提升算法的优化方向不同,提升树和梯度提升算法的优化方向是逐步降低模型预测的残差,损失函数是,而XGBoost算法的优化方向是逐步降低模型预测的误差,预测误差通过损失函数来定义,损失函数是
。所以XGBoost算法在每一轮拟合的都是样本的真实标签label,那么XGBoost每一轮拟合的数据岂不是都一样吗?我的个人理解是,表面上看上去每一轮的拟合数据都是一样的,但是XGBoost采用的是前向分布加法,每一轮的迭代是在前面t-1轮的基础上进行的,所以第t轮迭代的优化会受到前面t-1轮结果的约束,从这个角度来理解,那么每一轮的拟合数据又都是不一样的。GBDT每一步的损失函数是
,而XGBoost每一步的损失函数是
,
一直在变,而每一步
不变。如果一定要说XGBoost分类问题每轮拟合一个什么东西,那就是输入样本对应某类的真实概率–前面k-1棵树组合计算的对应该类的概率值。
就说到这吧,头发要紧。
以下是来自于知乎大神wepon对于XGBoost的总结:
传统GBDT以CART作为基分类器,xgboost还支持线性分类器,这个时候xgboost相当于带L1和L2正则化项的逻辑斯蒂回归(分类问题)或者线性回归(回归问题)。
传统GBDT在优化时只用到一阶导数信息,xgboost则对代价函数进行了二阶泰勒展开,同时用到了一阶和二阶导数。顺便提一下,xgboost工具支持自定义代价函数,只要函数可一阶和二阶求导。
xgboost在代价函数里加入了正则项,用于控制模型的复杂度。正则项里包含了树的叶子节点个数、每个叶子节点上输出的score的L2模的平方和。从Bias-variance tradeoff角度来讲,正则项降低了模型的variance,使学习出来的模型更加简单,防止过拟合,这也是xgboost优于传统GBDT的一个特性。
Shrinkage(缩减),相当于学习速率(xgboost中的eta)。xgboost在进行完一次迭代后,会将叶子节点的权重乘上该系数,主要是为了削弱每棵树的影响,让后面有更大的学习空间。实际应用中,一般把eta设置得小一点,然后迭代次数设置得大一点。(补充:传统GBDT的实现也有学习速率)
列抽样(column subsampling)。xgboost借鉴了随机森林的做法,支持列抽样,不仅能降低过拟合,还能减少计算,这也是xgboost异于传统gbdt的一个特性。
对缺失值的处理。对于特征的值有缺失的样本,xgboost可以自动学习出它的分裂方向。
xgboost工具支持并行。boosting不是一种串行的结构吗?怎么并行的?注意xgboost的并行不是tree粒度的并行,xgboost也是一次迭代完才能进行下一次迭代的(第t次迭代的代价函数里包含了前面t-1次迭代的预测值)。xgboost的并行是在特征粒度上的。我们知道,决策树的学习最耗时的一个步骤就是对特征的值进行排序(因为要确定最佳分割点),xgboost在训练之前,预先对数据进行了排序,然后保存为block结构,后面的迭代中重复地使用这个结构,大大减小计算量。这个block结构也使得并行成为了可能,在进行节点的分裂时,需要计算每个特征的增益,最终选增益最大的那个特征去做分裂,那么各个特征的增益计算就可以开多线程进行。
可并行的近似直方图算法。树节点在进行分裂时,我们需要计算每个特征的每个分割点对应的增益,即用贪心法枚举所有可能的分割点。当数据无法一次载入内存或者在分布式情况下,贪心算法效率就会变得很低,所以xgboost还提出了一种可并行的近似直方图算法,用于高效地生成候选的分割点。
参考文献
XGBoost做分类问题时每一轮迭代拟合的是什么?
深入理解XGBoost
机器学习算法中 GBDT 和 XGBOOST 的区别有哪些?
XGB做分类时每一轮都在干啥?
XGBoost算法个人理解相关推荐
- 数据分析利器:XGBoost算法最佳解析
作者:symonxiong,腾讯 CDG 应用研究员 XGBoost是一种经典的集成式提升算法框架,具有训练效率高.预测效果好.可控参数多.使用方便等特性,是大数据分析领域的一柄利器.在实际业务中,X ...
- Hessian矩阵在XGBoost算法的应用小结
来源:机器学习算法那些事本文约1100字,建议阅读5分钟 本文深入浅出的总结了Hessian矩阵在XGboost算法中的两种应用,即权重分位点算法和样本权重和算法 . 前言 Hessian矩阵最常见的 ...
- xgboost算法_详解xgboost算法的样本不平衡问题
XGBoost官方文档对参数scale_pos_weight的定义: 翻译: 调节正负样本权重的平衡 ,常用来处理不平衡的正负样本数据 . 典型值算法: scale_pos_weight = 负样本总 ...
- 【白话机器学习】算法理论+实战之Xgboost算法
1. 写在前面 如果想从事数据挖掘或者机器学习的工作,掌握常用的机器学习算法是非常有必要的,在这简单的先捋一捋, 常见的机器学习算法: 监督学习算法:逻辑回归,线性回归,决策树,朴素贝叶斯,K近邻,支 ...
- Python机器学习笔记:XgBoost算法(亲测)
前言 1,Xgboost简介 Xgboost是Boosting算法的其中一种,Boosting算法的思想是将许多弱分类器集成在一起,形成一个强分类器.因为Xgboost是一种提升树模型,所以它是将许多 ...
- Xgboost算法原理详解及python实现
Xgboost算法(回归树) 1.算法原理 2.对数据的要求(无需规范化) 3.算法的优缺点 4.XGB.GBDT.LR与RF 5.python代码实现 导入相关包 读取数据并预处理 训练 贝叶斯初步 ...
- XGBoost算法的相关知识
文章目录 背景 定义损失函数 (1)原始目标函数Obj (2)原始目标函数Obj的泰勒展开 (3)具体化目标函数的泰勒展开细节 (4)求解目标函数中的wjw_jwj 最优切分点算法 基于分桶的划分策 ...
- xgboost算法_工业大数据:分析算法
一. 应用背景 大数据分析模型的研究可以分为3个层次,即描述分析(探索历史数据并描述发生了什么).预测分析(未来的概率和趋势)和规范分析(对未来的决策给出建议).工业大数据分析的理论和技术研究仍处于起 ...
- 干货▍全网通俗易懂的数据竞赛大杀器XGBoost 算法详解
前言 xgboost一直在竞赛江湖里被传为神器,比如时不时某个kaggle/天池比赛中,某人用xgboost于千军万马中斩获冠军. 而我们的机器学习课程里也必讲xgboost,如寒所说:"R ...
最新文章
- 黑客内参告诉你一个:设计师用div+css 必须知道的网页布局类型
- 机器学习流程模板及多模型对比实战梳理
- 初级,用powerdesigner生成的sql创建access数据库
- Ajax原理详细说明
- boost::fusion::pop_front用法的测试程序
- linux memcached 运行,linux下查看Memcached运行状态
- Linux内存寻址方式
- 想在研发群里装?先学会这几个排查K8s问题的办法
- MySQL 8.0中的JSON增强
- 融会贯通——最常用的面向对象设计原则“合成复用原则”
- vue 事件调用 传参_vue如何在父组件指定点击事件后向子组件传递参数并调用子组件的事件?...
- MySQL-高并发优化
- 《iOS 6核心开发手册(第4版)》——1.13节秘诀:从滚动视图中拖动
- 腾讯WebQQ 3.0 密码、验证码加密算法分析
- 包含所有的计算机视频教程
- php 主机管理系统,LuManager虚拟主机管理系统
- 【深度学习入门案例】Senta情感分析
- Python栈的应用之二进制与十进制转换
- 利用网线在两台电脑之间传输文件
- Android BLE HIDS Data ,从问询DB 到写入Android 节点的flow 之四