推荐博文

https://blog.csdn.net/sb19931201/article/details/52557382

https://www.jianshu.com/p/7467e616f227


xgb讲起来还有点复杂,刚开始看算法的时候也是一愣一愣的。白话讲一讲吧。

先确定一个概念,xgboost是什么?就是一堆二叉树,准确来讲是CART树,和GBDT一样,在GBDT中,无论是分类还是回归,也都是一堆CART树。当然xgboost还支持其它的基分类器。


直接上与GBDT的一些比较吧,从比较中来分析,为什么XGB能这么牛叉。

XGB的改进

  1. 传统GBDT以CART作为基分类器,xgboost还支持线性分类器,这个时候xgboost相当于带L1和L2正则化项的逻辑斯蒂回归(分类问题)或者线性回归(回归问题)。 —可以通过booster [default=gbtree]设置参数:gbtree: tree-based models/gblinear: linear models
  2. xgboost在代价函数里加入了正则项,用于控制模型的复杂度。正则项里包含了树的叶子节点个数、每个叶子节点上输出的score的L2模的平方和。从Bias-variance tradeoff角度来讲,正则项降低了模型variance,使学习出来的模型更加简单,防止过拟合,这也是xgboost优于传统GBDT的一个特性 
    —正则化包括了两个部分,都是为了防止过拟合,剪枝是都有的,叶子结点输出L2平滑是新增的。
    下面的式子就是正则化的式子。加号左边为叶子节点树的复杂度惩罚,右边是L2正则化。
  3. 传统GBDT在优化时只用到一阶导数信息,xgboost则对代价函数进行了二阶泰勒展开,同时用到了一阶和二阶导数。顺便提一下,xgboost工具支持自定义代价函数,只要函数可一阶和二阶求导。 —对损失函数做了改进(泰勒展开,一阶信息g和二阶信息h),下图就具体展示了目标函数。

去掉常数项之后就长这个样子。这个损失函数就是用来建树的,可以理解成cart树的MSE建树过程。后面会做一些变形。

  • Shrinkage(缩减),相当于学习速率(xgboost中的eta)。xgboost在进行完一次迭代后,会将叶子节点的权重乘上该系数,主要是为了削弱每棵树的影响,让后面有更大的学习空间。实际应用中,一般把eta设置得小一点,然后迭代次数设置得大一点。(补充:传统GBDT的实现也有学习速率)
  • column subsampling列(特征)抽样,说是从随机森林那边学习来的,防止过拟合的效果比传统的行抽样还好(行抽样功能也有),并且有利于后面提到的并行化处理算法。
  • xgboost工具支持并行。boosting不是一种串行的结构吗?怎么并行的?注意xgboost的并行不是tree粒度的并行,xgboost也是一次迭代完才能进行下一次迭代的(第t次迭代的代价函数里包含了前面t-1次迭代的预测值)。xgboost的并行是在特征粒度上的。我们知道,决策树的学习最耗时的一个步骤就是对特征的值进行排序(因为要确定最佳分割点),xgboost在训练之前,预先对数据进行了排序,然后保存为block结构,后面的迭代中重复地使用这个结构,大大减小计算量。这个block结构也使得并行成为了可能,在进行节点的分裂时,需要计算每个特征的增益,最终选增益最大的那个特征去做分裂,那么各个特征的增益计算就可以开多线程进行。(其实就是在特征分类的时候,传统的做法是遍历每个特征再遍历每个特征的所有分裂点,然后去寻找一个损失最小的特征的分裂点。这些特征与特征间的选择是独立的,所以给了实现并行计算的可能性。同时在分裂点的选取的时候还需要对特征进行排序,这个也是独立的,所以也给了实现并行计算的可能。)
  • 对缺失值的处理。对于特征的值有缺失的样本,xgboost可以自动学习出它的分裂方向。  —稀疏感知算法,论文3.4节,Algorithm 3: Sparsity-aware Split Finding
  • split finding algorithms(划分点查找算法):

(1)exact greedy algorithm—贪心算法获取最优切分点 
(2)approximate algorithm— 近似算法,提出了候选分割点概念,先通过直方图算法获得候选分割点的分布情况,然后根据候选分割点将连续的特征信息映射到不同的buckets中,并统计汇总信息。详细见论文3.3节 
(3)Weighted Quantile Sketch—分布式加权直方图算法,论文3.4节 
这里的算法(2)、(3)是为了解决数据无法一次载入内存或者在分布式情况下算法(1)效率低的问题,以下引用的还是wepon大神的总结:

可并行的近似直方图算法。树节点在进行分裂时,我们需要计算每个特征的每个分割点对应的增益,即用贪心法枚举所有可能的分割点。当数据无法一次载入内存或者在分布式情况下,贪心算法效率就会变得很低,所以xgboost还提出了一种可并行的近似直方图算法,用于高效地生成候选的分割点。


好了,讲完了优缺点,大概可以知道了XGBoost改进了哪些地方,接下来就来介绍一下具体的算法流程。

争取讲的简单一点。

监督学习中总会有目标函数和模型。上图中就是我们最终想要得到的模型和优化模型所用的目标函数。这里可能什么都看不懂,后面会慢慢解释。

xbg也是一个加法模型,通GBDT一样,下一个模型是之前所有模型的累加。但有一点区别,在GBDT中第二步是计算残差,但在xgb中新模型的输出就是实际的预测值了,我们不计算残差而是直接用预测值与损失函数去得到下一时刻的决策树。

是t时刻的预测,我们希望能够越接近真实值越好,而由加法公式可以知道是t-1时刻的预测值,我们已经知道了。可想而知,t时刻的任务就是拟合使得结果尽可能好,这就是上图中第二个公式所表达的意思。第三个公式只是把式子展开来之后,把与当前时刻t无关的变量通通扔到了const中去。

这一步对应回GBDT中就是计算负梯度(MSE损失函数的化就是残差),不过这边用了二阶导数,海森矩阵。这也是xgb性能更强大的原因之一。(废话,计算复杂度高了,精度不提高要它干嘛T_T)

树分裂的打分函数是什么,就是cart分类树中的基尼系数增益或者回归树中的mse

xgb也允许我们自定义损失函数,只要它是一阶二阶可导的

这样我们就得到了新的目标函数,白话一点也就是t时刻的损失函数。去掉常数项时因为是t-1时刻的损失,所以在t时刻是已知的,当作常数项就去掉了。

后面一串英文讲的是,为什么我们要话费如此大的精力去得到目标函数,而不是直接去生成树。论文从两方面来讲,一方面从理论层面上讲,我们是做什么,让模型达到最优解,最优解怎么达到,降低误差,误差怎么降低,让损失函数收敛。从工程层面上来理解,就是为了方便实现,可以把模型分离开来,就是损失函数不依赖于树的生成过程,只依赖于一阶导数与二阶导数,这样就可以分离开来。


做个小结吧,前面做了这么多事都在干什么呢!其实都是在定义目标函数。仅仅完成了GBDT中对应的1,2两步,第一步就是初始化模型为常数0,第二步对应的是计算负梯度(残差)。因为在xgb中用到了一阶导二阶导,所以目标函数的定义比较复杂。前面这么长的篇幅都只是在解释,当xgb是如何在gbdt的基础上改进了这个目标函数。利用了二阶导信息和更新了目标函数的公式使得模型具有更强大 性能。

补充:其实到这里xgb第二步“负梯度”还没有计算出来,只是计算了损失函数L,后面还要推导真正的对应“负梯度”的叶节点值。


好了,大家回想一下gbdt做完这两步接下来要做什么了!bingo,接下来就是根据计算得到的负梯度建新的cart树。那来回想一下在gbdt中cart树是怎么被构建的(这里再提一嘴,gbdt无论是分类还是回归,都是cart回归树,对于分类问题只是在最后加了一层激活层,将数值型变量转换成对应类别的概率输出而已。),很简单,cart树的构建是通过最小化均方误差损失来构建的。

在xgb中也差不多类似,不过就是最小化的目标函数变了一个东西。

先要铺垫一点东西,xgb做了一些新的定义。

这整个都算是正则项,模型的惩罚项,就在前面的目标函数中已经有了。

在上面我们已经得到了目标函数最后长这个样子

现在我们把最后的正则项带进去,然后把替换掉,表示这个样本在t时刻被树预测成什么值,其实就是,表示被分到的叶子节点的值。这么一替换,公式就好看多了


接下来就是一个树特征分裂的判断标准了。

卧槽,其实到这边才真正搞出来对应GDBT中残差或者负梯度的叶子节点值W的计算。……


损失函数的作用在这里才用到了。求增益最大的特征进行分裂。gain越大越好


好,特征分裂完,最后一步就是更新强学习器,用加法模型加上去就结束了。


接下来贴一下完整的算法流程。

好了,接下讲一下XGB的一些注意事项

  • 多类别分类时,类别需要从0开始编码
  • Watchlist不会影响模型训练。
  • 类别特征必须编码,因为xgboost把特征默认都当成数值型的
  • 调参:Notes on Parameter Tuning 以及  Complete Guide to Parameter Tuning in XGBoost (with codes in Python)
  • 训练的时候,为了结果可复现,记得设置随机数种子。
  • XGBoost的特征重要性是如何得到的?某个特征的重要性(feature score),等于它被选中为树节点分裂特征的次数的和,比如特征A在第一次迭代中(即第一棵树)被选中了1次去分裂树节点,在第二次迭代被选中2次…..那么最终特征A的feature score就是 1+2+….

正则项:

LightGBM

以后有时间再另开一章。

【机器学习】XGBoost学习笔记相关推荐

  1. python嵩天课堂笔记_[Python机器学习]强化学习笔记(嵩天礼欣老师mooc第三周)

    [Python机器学习]强化学习笔记(嵩天礼欣老师mooc第三周) [Python机器学习]强化学习笔记(嵩天礼欣老师mooc第三周) 目录 强化学习 定义 马尔科夫决策过程 基本元素 值函数 最优值 ...

  2. 机器学习入门学习笔记:(4.2)SVM的核函数和软间隔

    前言 之前讲了有关基本的SVM的数学模型(机器学习入门学习笔记:(4.1)SVM算法).这次主要介绍介绍svm的核函数.软间隔等概念,并进行详细的数学推导.这里仅将自己的笔记记录下来,以便以后复习查看 ...

  3. 机器学习入门学习笔记:(3.2)ID3决策树程序实现

    前言 之前的博客中介绍了决策树算法的原理并进行了数学推导(机器学习入门学习笔记:(3.1)决策树算法).决策树的原理相对简单,决策树算法有:ID3,C4.5,CART等算法.接下来将对ID3决策树算法 ...

  4. 机器学习入门学习笔记:(2.3)对数几率回归推导

    理论推导   在以前的博客(机器学习入门学习笔记:(2.1)线性回归理论推导 )中推导了单元线性回归和多元线性回归的模型.   将线性回归模型简写为:y=ωTx+by = \omega^Tx+b:   ...

  5. 机器学习入门学习笔记:(2.2)线性回归python程序实现

      上一篇博客中,推导了线性回归的公式,这次试着编程来实现它.(机器学习入门学习笔记:(2.1)线性回归理论推导 )   我们求解线性回归的思路有两个:一个是直接套用上一篇博客最后推导出来的公式:另一 ...

  6. 吴恩达《机器学习》学习笔记十四——应用机器学习的建议实现一个机器学习模型的改进

    吴恩达<机器学习>学习笔记十四--应用机器学习的建议实现一个机器学习模型的改进 一.任务介绍 二.代码实现 1.准备数据 2.代价函数 3.梯度计算 4.带有正则化的代价函数和梯度计算 5 ...

  7. 吴恩达《机器学习》学习笔记十二——机器学习系统

    吴恩达<机器学习>学习笔记十二--机器学习系统 一.设计机器学习系统的思想 1.快速实现+绘制学习曲线--寻找重点优化的方向 2.误差分析 3.数值估计 二.偏斜类问题(类别不均衡) 三. ...

  8. 吴恩达《机器学习》学习笔记十一——应用机器学习的建议

    吴恩达<机器学习>学习笔记十一--应用机器学习的建议 一.训练完模型后下一步要做什么 二.评估算法与模型选择 1.训练集与测试集 2.训练/测试步骤 3.模型选择 4.数据集新的划分--验 ...

  9. 吴恩达《机器学习》学习笔记十一——神经网络代码

    吴恩达<机器学习>学习笔记十一--神经网络代码 数据准备 神经网络结构与代价函数· 初始化设置 反向传播算法 训练网络与验证 课程链接:https://www.bilibili.com/v ...

  10. 吴恩达《机器学习》学习笔记十——神经网络相关(2)

    吴恩达<机器学习>学习笔记十--神经网络相关(2) 一. 代价函数 二. 反向传播算法 三. 理解反向传播算法 四. 梯度检测 五. 随机初始化 1.全部初始化为0的问题 2.随机初始化的 ...

最新文章

  1. ai会取代程序员吗_机器会取代程序员吗?
  2. 如何使用proteus仿真
  3. C语言编程题目(精心准备,特别适合C语言小白)
  4. 计算机中单位换算tb,bit Byte KB MB GB TB 单位换算
  5. 智能陈桥五笔输入法 for linux,解决在Linux下安装陈桥五笔输入法的方法
  6. python 抢票程序_程序员硬核Python抢票教程”,帮你抢回家车票
  7. 11、git查看往日提交以及删除分支ID命令
  8. 快学scala第二版笔记
  9. [生存志] 第38节 平王东周都洛阳
  10. Javascript的设计模式之从设计到模式(重要设计模式)
  11. 程序员面试资源大收集
  12. C Prime Plus 第二章 C语言概述
  13. linux安装及配置mycat eye可视化监控界面
  14. 【JavaWeb之旅二】MySQL数据库之SQL语句中的DML语句与DQL语句
  15. 数据结构 第一节 第一课
  16. 陈力:传智播客古代 珍宝币 泡泡龙游戏开发第28讲:PHP数组
  17. Qt实现桌面画线、标记,流畅绘制,支持鼠标和多点触控绘制原创
  18. 几个好玩的区块链app推荐
  19. 基于 RT_Thread 的ADC驱动源代码 drv_adc.c
  20. 高级程序员装逼指南,是高级哦!

热门文章

  1. 浅析C++ Compile-time Assertion技术
  2. php中MySQL数据库导入与导出_Mysql数据库导出和导入
  3. react控制元素的显示或隐藏
  4. Maven拉取私服Jar包和发布jar包到maven私服
  5. JavaScript设计模式——单例模式的理解与应用
  6. 【移动端vue ui框架学习】vue项目如何使用基于vue的UI框架mint ui
  7. 基于3D模型的MaskRCNN的训练数据生成
  8. 安卓程序段——时间测试函数
  9. VS2010编译错误:fatal error C1189: #error : This file requires _WIN32_WINNT to be #defined at least to 0x
  10. 如何修改移动设备按钮默认样式