传统机器学习笔记7——GBDT模型详解

article/2025/8/21 9:01:43

目录

  • 前言
  • 一.GBDT算法
    • 1.1.Boosting
    • 1.2.GDBT
      • 1.2.1.GBDT与负梯度近似残差
      • 1.2.2.GDBT训练过程
  • 二.梯度提升与梯度下降
  • 三.GDBT模型优缺点
  • 四.GDBT vs 随机森林

前言

  上篇博文我们介绍了关于回归树模型的基本知识点,有不懂的小伙伴可以回到前面再看下,传统机器学习笔记6——回归树模型。这篇博文我们继续介绍传统机器学习的内容,传统机器学习之GBDT

一.GBDT算法

  GBDT(Gradient Boosting Decision Tree),即梯度提升决策树,是一种迭代的决策树算法,我们又称为MART,他通过构造一组弱的学习器,并把多颗决策树的结果累加起来最为最终的预测结果,将决策树与集成算法进行了有效的结合。

1.1.Boosting

  在介绍GDBT算法之前,我们还需要先看下BoostingBoosting方法训练及分类器的时候采用串行的方式,各个基分类器之间有依赖,他的思路就是将基分类器进行层层叠加,每一层训练的时候对前一层基分类器分错的样本给予更高的权重,测试的时候根据各层分类器的结果的加权得到最终的结果。注意这里跟我们之前介绍的BaggingBagging在训练的时候,各个基分类器之间无强依赖,可以进行并行训练。关于Bagging有不懂的小伙伴可以回到前面的博文回顾下,1.4.Bagging。

1.2.GDBT

  下面我们开始正式介绍GDBT算法,其实他的原理很简单原理如下:

  • 所有弱分类器的结果相加等于预测值。
  • 每次都以当前预测为基准,下一个弱分类器去拟合误差函数对预测值的残差(预测值与真实值之间的误差)。
  • GBDT的弱分类器使用的是树模型。

在这里插入图片描述
如上图所示,我们用GDBT去预测价格:

  • 第一个弱分类器(第一棵树)预测一个年龄(如90元),计算发现误差有10元;
  • 第二棵树预测拟合残差,预测值6元,计算发现差距还有4元;
  • 第三棵树继续预测拟合残差,预测值3元,发现差距只有公式1元;
  • 第四课树用1元拟合剩下的残差,完成。

  最终,四棵树的结论加起来,得到100元这个标注答案(实际工程实现里,GBDT 是计算负梯度,用负梯度近似残差)。

1.2.1.GBDT与负梯度近似残差

  在做回归任务时,GDBT在每一轮的迭代时都会对样本有个预测值,此时的损失函数为均方误差损失函数:
l ( y i , y ^ i ) = 1 2 ( y i − y ^ i ) 2 l\left(y_i, \hat{y}_i\right)=\frac{1}{2}\left(y_i-\hat{y}_i\right)^2 l(yi,y^i)=21(yiy^i)2
损失函数的负梯度计算
− [ ∂ l ( y i , y i ^ ) ∂ y ^ i ] = ( y i − y i ^ ) -\left[\frac{\partial l\left(y_i, \hat{y_i}\right)}{\partial \hat{y}_i}\right]=\left(y_i-\hat{y_i}\right) [y^il(yi,yi^)]=(yiyi^)
从上面的公式可以看出,当损失函数为均方误差时,每一次的拟合的值就是“真实值-预测值”,即残差。

1.2.2.GDBT训练过程

  我们下面以预测四个人的年龄为例来介绍下GDBT的训练过程。假设现在有四个人(A,B,C,D),他们的年龄分别是(14,16,24,26)。其中A,B为高一,高二学生,C,D为应届生和工作两年的员工,我们先用回归树来训练,有如下结果:
在这里插入图片描述
  接下来我们使用GBDT来做这件事,由于数据太少,我们限定叶子节点最多有两个,即每棵树都只有一个分枝,并且限定只学两棵树。我们会得到如下图2所示结果:
在这里插入图片描述
  上图中的左图和上面的决策树图一样,由于A,B年龄较为相近,C,D年龄较为相近,他们被分为两拨,每拨用平均年龄作为预测值。此时计算残差(即 A的预测值 + A的残差 = A的实际值),所以A的残差就是16-15=1(注意,A的预测值是指前面所有树累加的和,这里前面只有一棵树所以直接是15,如果还有树则需要都累加起来作为A的预测值)。进而得到A,B,C,D的残差分别为-1,1,-1,1。然后我们拿残差替代A,B,C,D的原值,到第二棵树去学习,如果我们的预测值和它们的残差相等,则只需把第二棵树的结论累加到第一棵树上就能得到真实年龄了。这里的数据显然是我可以做的,第二棵树只有两个值1和-1,直接分成两个节点。此时所有人的残差都是0,即每个人都得到了真实的预测值。也就是说,现在A,B,C,D的预测值都和真实年龄一致了。

  • A: 14岁高一学生,购物较少,经常百度提问;预测年龄A = 15 – 1 = 14
  • B: 16岁高三学生;购物较少,经常回答问题;预测年龄B = 15 + 1 = 16
  • C: 24岁应届毕业生;购物较多,经常百度问题;预测年龄C = 25 – 1 = 24
  • D: 26岁工作两年员工;购物较多,经常回答问题;预测年龄D = 25 + 1 = 26

二.梯度提升与梯度下降

  下面我们再来对比下梯度提升和梯度下降算法,两种迭代优化算法,都是在每1轮迭代中,利用损失函数负梯度方向的信息,更新当前模型。我们先来看下两种模型的计算公式。
梯度下降:
  梯度下降中,模型是以参数化形式表示,从而模型的更新等价于参数的更新。
F = F t − 1 − ρ t ∇ F L ∣ F = F t − 1 L = ∑ i l ( y i , F ( x i ) ) \begin{gathered} F=F_{t-1}-\left.\rho_t \nabla_F L\right|_{F=F_{t-1}} \\ L=\sum_i l\left(y_i, F\left(x_i\right)\right) \end{gathered} F=Ft1ρtFLF=Ft1L=il(yi,F(xi))
梯度上升:
  梯度提升中,模型并不需要进行参数化表示,而是直接定义在函数空间中,从而大大扩展了可以使用的模型种类。
w t = w t − 1 − ρ t ∇ w L ∣ w = w t − 1 L = ∑ i l ( y i , f w ( w i ) ) \begin{gathered} w_t=w_{t-1}-\left.\rho_t \nabla_w L\right|_{w=w_{t-1}} \\ L=\sum_i l\left(y_i, f_w\left(w_i\right)\right) \end{gathered} wt=wt1ρtwLw=wt1L=il(yi,fw(wi))

三.GDBT模型优缺点

  上面我们介绍了GDBT模型的基本算法,那么他有哪些优缺点呢?
优点:

  • 预测阶段,因为每棵树的结构都已确定,可并行化计算,计算速度快。
  • 适用稠密数据,泛化能力和表达能力都不错,数据科学竞赛榜首常见模型。
  • 可解释性不错,鲁棒性亦可,能够自动发现特征间的高阶关系。

缺点:

  • GBDT 在高维稀疏的数据集上,效率较差,且效果表现不如 SVM 或神经网络。
  • 适合数值型特征,在 NLP 或文本特征上表现弱。
  • 训练过程无法并行,工程加速只能体现在单颗树构建过程中。

四.GDBT vs 随机森林

相同点:

  • 都是集成模型,由多棵树组构成,最终的结果都是由多棵树一起决定。
  • RF 和 GBDT 在使用 CART 树时,可以是分类树或者回归树。

不同点:

  • 训练过程中,随机森林的树可以并行生成,而 GBDT 只能串行生成。
  • 随机森林的结果是多数表决表决的,而 GBDT 则是多棵树累加之。
  • 随机森林对异常值不敏感,而 GBDT 对异常值比较敏感。
  • 随机森林降低模型的方差,而 GBDT 是降低模型的偏差。

http://chatgpt.dhexx.cn/article/RTPBeFoV.shtml

相关文章

机器学习集成学习——GBDT(Gradient Boosting Decision Tree 梯度提升决策树)算法

系列文章目录 机器学习神经网络——Adaboost分离器算法 机器学习之SVM分类器介绍——核函数、SVM分类器的使用 机器学习的一些常见算法介绍【线性回归,岭回归,套索回归,弹性网络】 文章目录 系列文章目录 前言 一、GBDT(Gradient Boos…

移动端UI框架大比拼

1、vonic vonic是一个基于 vue.js 和 ionic 样式的 UI 框架,用于快速构建移动端单页应用 onic 依赖以下几个库,在创建 vonic 项目之前,请确保引入它们。 vue.js vue-router.js axios.js (vue.js 官方推荐的 ajax 方案) 中文文档 在线预览 …

手机/移动端的UI框架-Vant和NutUI

下面推荐2款手机/移动端的UI框架。 其实还有很多的框架,各个大厂都有UI框架。目前,找来找去,只有腾讯的移动端是setup语法写的TDesign,其他大厂,虽然都是VUE3写的,但是都还未改成setup的语法,而…

一:移动端UI框架mint-ui

官网按需引入的.babelrc写法是老的写法,配置的plugins一直报错是因为"component"后面不要[]直接跟{} 一:Mint-UI中按钮组件的使用 简介:Mint UI是基于 Vue.js 的移动端组件库.mint-ui官网链接 1.安装 // 安装 # Vue 1.x npm install mint-ui1 -S # Vue…

vue3使用的移动端UI框架,vue3.0 ui组件库

vue 3.0 项目中 element-ui form 表单元素中 仅 el-button 显示,其他不显示,如何解决? 谷歌人工智能写作项目:小发猫 在页面中引用了laydate插件,在显示的时候,字体图标一直显示不出来 typescript&#x…

值得推荐的Vue 移动端UI框架

1. Vant(支持Vue3) 是有赞前端团队基于有赞统一的规范实现的 Vue 组件库,提供了一整套 UI 基础组件和业务组件,这是我目前用过最好用的框架。 中文文档 | github地址 | 在线预览 2. Mint UI Mint UI 由饿了么前端团队推出的 M…

移动端UI框架总结

1. React Native 网站地址:React Native 中文网 使用React来编写原生应用的框架 GitHub:https://github.com/facebook/react-native 网站描述:Facebookt推出基于 React 的创建跨平台移动应用开发框架 React Native使你能够在Javascript和React的基础上获得完全一致的开发体验…

与运算()、或运算(|)、异或运算(^)的本质 及 用途,文末附加 位运算面试题

目录 一:与运算符(&)and 1、运算规则: 2、例如:3&5 3、用途: 1)判断 奇偶性 2)清零。 3)取一个数中指定位 二:或运算(|&#xff…

Python与或运算

今天碰到一道有意思的题目,看了之后发现自己对Python与或的理解还是欠缺,如下。 题目:求12…n 来源:Leetcode 如果不加限制,我们有很多方法计算该值,例如高斯公式,递归等。 我们思考下递归的解…

sql查询数据表某列的重复值并计数

查询sql为: SELECTdevice_id,count( device_id ) AS number FROMcms_sticker_member GROUP BYdevice_id HAVINGcount( device_id ) > 1 ORDER BYnumber DESC; 结果:

查询多个字段同时重复2次以上的记录的sql的次数

表数据如上图, 1.筛选 type、pid 重复的数据的次数大于等于2的 次数和对应的数据值 SELECT COUNT(*),TYPE,pid FROM AREA GROUP BY TYPE,pid HAVING COUNT(*)>2; 2.筛选 type、pid 重复的数据的次数大于等于2,并且对应的 pid和type值相反的重复的数…

sql查询、删除重复相同数据的语句或只保留一条数据

1、查询(字段1, 字段2, 字段3)全部重复相同的数据 SELECT * FROM 表 WHERE (字段1, 字段2, 字段3) IN (SELECT 字段1, 字段2, 字段3 FROM 表 GROUP BY 字段1, 字段2, 字段3 HAVING COUNT(*) > 1) ORDER BY 排序字段2、过滤(字段1, 字段…

分享SQL重复记录查询的几种方法

SQL重复记录查询的几种方法,需要的朋友可以参考一下 1、查找表中多余的重复记录,重复记录是根据单个字段(peopleId)来判断 代码如下: select * from people where peopleId in (select peopleId from people group by peo…

SQL查询重复记录

1、查找表中多余的重复记录,重复记录是根据单个字段(peopleId)来判断 select * from people where peopleId in (select peopleId from people group by peopleId having count(peopleId) > 1) 2、删除表中多余的重复记录,重…

为什么int无法转换为Double????

规律:拆、装箱和升、降级两者可以在同一条语句中进行,但是一定要先拆箱或装箱再升级或者降级。。。 一条语句中,int无法转换为Double,因为这里涉及到先升级再装箱子,拆装箱一定要在升降级前面。。。。。 一条语句中&…

C++中int或double与string的相互转换

一、int转string 1.c11标准增加了全局函数std::to_string: string to_string (int val); string to_string (long val); string to_string (long long val); string to_string (unsigned val); string to_string (unsigned long val); string to_string (unsigned long …

java byte[]转int和double

一般无需java来处理byte字节的数据转成 int , C语言更适合干这事. 但是无奈遇到了这种需求. 网上百度了一小部分代码, 发现好多错误代码… 干脆自己手写了一遍… byte[]数据的格式协议文档如下: 先上使用代码 byte[] hex Base64.getDecoder().decode(data); int head Read…

详细讲解int、float与double的区别

最近为了看一下float的精确度仔细看了一下这三种数据在内存中的样子,看了一下别人的博客发现大家对精度都有这不同的定义,我自己也简单画了一下。 下面来主要讲解一下int、float与double三者的区别与详解 一、int(最简单的一种)…

c++ string转int, double,int,double转string

c string与常用数值变量互转 写了几个字符串与数值变量互相转换的几个函数,每次用到都要上网查一堆,耽误时间,写好放到这里备用。方法有很多,这里列出来测试过能用的,其他方法慢慢添加。以下函数自动判断int或者double…

C++下string类型转double类型

最近coding的时候随手写了std::stod()函数来进行类型的转换,发现输出的时候自动做了小数位的截取 尝试使用std::stold()函数转换成long double类型之后,依旧不能解决问题,输出依旧不是想要的 发现网上对这个问题的解答没有,于是…