浅谈 GBDT
在 Xgboost 那篇文章 (Kaggle 神器 xgboost) 中提到了 Gradient Boosted Decision Trees,今天来仔细看看 GBDT。
本文结构:
- 什么是 GBDT ?
- GBDT 与 Adaboost 的区别与联系是什么 ?
- GBDT 与 Xgboost 的区别是什么?
什么是 GBDT?
GBDT(Gradient Boosting Decision Tree,梯度提升决策树),由名字可以看出涉及到三点:
1. 首先是 Boosting:
前面写过一篇 Adaboost 算法,里面简单介绍了 Boosting 的思想:
给定初始训练数据,由此训练出第一个基学习器;
根据基学习器的表现对样本进行调整,在之前学习器做错的样本上投入更多关注;
用调整后的样本,训练下一个基学习器;
重复上述过程 T 次,将 T 个学习器加权结合。
简单讲,就是每次训练单个弱学习器时,都将上一次分错的数据权重提高一点再进行当前单个弱学习器的学习。这样越往后执行,训练出的单个弱学习器就会越在意那些容易分错(权重高)的点。当执行 M 次后,通过加权求和的方式组合成一个最终的学习器。
2. 接着是 Gradient Boosting:
Gradient boosting 是 boosting 的其中一种方法,它主要的思想是,每一次建立单个学习器时,是在之前建立的模型的损失函数的梯度下降方向。
我们知道损失函数(loss function)越大,说明模型越容易出错,如果我们的模型能够让损失函数持续的下降,则说明我们的模型在不停的改进,而最好的方式就是让损失函数在其梯度(Gradient)的方向上下降。
接下来看算法具体细节:
最终模型 F 是多个弱学习器的加权组合:
![](http://image.baizhud.com/images/mytent/2022-05-07/165188566916w5188AS56169.png)
整体损失函数,其中 P 为模型的参数:
![](http://image.baizhud.com/images/mytent/2022-05-07/16518856691s651885sd6869.png)
我们要求使损失函数达到最小的参数:
![](http://image.baizhud.com/images/mytent/2022-05-07/16518856691651w8h8M56W69.png)
或者写成梯度下降的方式,就是我们将要得到的模型 fm 的参数 {αm,βm} 能够使得 fm 的方向是之前得到的模型 Fm-1 的损失函数下降最快的方向:
![](http://image.baizhud.com/images/mytent/2022-05-07/1651885669NP1A6518A85669.png)
因为 Fm-1 的损失函数下降最快的方向为:
![](http://image.baizhud.com/images/mytent/2022-05-07/16518856701Eg65188567qc0.png)
那我们可以用最小二乘法来得到 αm:
![](http://image.baizhud.com/images/mytent/2022-05-07/165188567016wF5188j56570.png)
在此基础上,可以得到 βm:
![](http://image.baizhud.com/images/mytent/2022-05-07/1651885670165tw1L88s5670.png)
最终得到整体:
![](http://image.baizhud.com/images/mytent/2022-05-07/16518856701s6518I8f5z670.png)
完整算法:
![](http://image.baizhud.com/images/mytent/2022-05-07/1651885670165148R8567ZO0.png)
3. 然后是 Decision Tree:
GBDT 是 GB 和 DT 的结合,就是当 GB 中的单个学习器为决策树时的情况,此处 DT 使用的是回归树。
下面两个图分别表示 DT 和 由 100 棵树组合成的 GB 在树的深度为 0,3,6 时的效果,0 时就是要拟合的函数的图像,可以看到 GB 可以在有限的深度就能得到比较光滑的的拟合:
![](http://image.baizhud.com/images/mytent/2022-05-07/16518856701S65188564B7l0.png)
Decision Tree
![](http://image.baizhud.com/images/mytent/2022-05-07/1651885670X16561U8585670.png)
Gradient Boosting
既然都是 boosting 方法,那么 GBDT 与 Adaboost 的区别与联系是什么?
它们都属于 boosting 提升方法:
![](http://image.baizhud.com/images/mytent/2022-05-07/16518856701D6s6518o85670.png)
adaboost 可以表示为 boosting 的前向分布算法(Forward stagewise additive modeling)的一个特例。
在上图中,如何选择损失函数决定了算法的名字。不同的损失函数和极小化损失函数方法决定了 boosting 的最终效果,下面是几个常见的 boosting:
![](http://image.baizhud.com/images/mytent/2022-05-07/165188567016F51885QtW670.png)
AdaBoost 是通过提升错分数据点的权重来定位模型的不足, 而 Gradient Boosting是通过算梯度(gradient)来定位模型的不足。
GBDT 与 Xgboost 的关系又是什么?
在 Kaggle 神器 xgboost 这篇文章中简单地提了一下 xgboost 的特点,除了很多优化外它与 GBDT 的区别有:
- Xgboost 是 GB 算法的高效实现,xgboost 中的基学习器除了可以是CART(gbtree)也可以是线性分类器(gblinear)。
- xgboost在目标函数中显示的加上了正则化项:
![](http://image.baizhud.com/images/mytent/2022-05-07/1651885670q316r518i85670.png)
- GB 中使用 Loss Function 对 f(x) 的一阶导数计算出伪残差用于学习生成fm,xgboost 不仅使用到了一阶导数,还使用二阶导数:
![](http://image.baizhud.com/images/mytent/2022-05-07/1651885670R16518m8i56t70.png)
- CART 回归树中寻找最佳分割点的衡量标准是最小化均方差,xgboost 寻找分割点的标准是最大化,lamda,gama 与正则化项相关:
![](http://image.baizhud.com/images/mytent/2022-05-07/16518856701Qx6r51885c670.png)
参考: 统计学习方法 A Gradient Boosting Machine-Jerome H. Friedman http://homes.cs.washington.edu/~tqchen/pdf/BoostedTree.pdf http://blog.csdn.net/yangtrees/article/details/7506052 http://blog.csdn.net/shenxiaoming77/article/details/51542982 http://blog.csdn.net/dark_scope/article/details/24863289 http://arogozhnikov.github.io/2016/06/24/gradient_boosting_explained.html
- TensorFlow从0到1 | 第十二章:TensorFlow构建3层NN玩转MNIST
- 如何通过预加载器提升网页加载速度
- 分钟学会正则表达式(译)
- TensorFlow从0到1 | 第十一章 74行Python实现手写体数字识别
- 让浏览器不再显示 https 页面中的 http 请求警报
- 跨域访问和防盗链基本原理
- 【翻译】MongoDB指南/CRUD操作(一)
- 【直播】我的基因组50:从测序深度和位点间距来看SNV分布情况
- 【翻译】MongoDB指南/CRUD操作(二)
- 【翻译】MongoDB指南/CRUD操作(三)
- 为什么 Laravel 会成为最成功的 PHP 框架?
- 【生信菜鸟经】如何系统入门Perl
- 【翻译】MongoDB指南/CRUD操作(四)
- R包终极解决方案
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 一个小小的签到功能,到底用 MySQL 还是 Redis ? ?
- 下载丨9月数据库技术通讯:Redo日志丢失,重建遭遇ORA-16433处理
- knative serving 组件分析
- 在 minikube 上部署 knative
- 认识 JS 静态类型检查工具 Flow
- PostgreSQL中如何实现密码复杂度检查?
- JS/TS 对数组中的对象按对象的值进行去重
- JS/TS 对数组中的对象按相同值进行分组
- CSS 实现输入框从右往左和反向倒序输入
- SAP Spartacus PagelayoutComponent里的template
- Python实战 | 送亲戚,送长辈,月饼可视化大屏来帮忙!
- SAP Spartacus PagelayoutComponent里的section和slot
- SAP Spartacus ComponentData的提前subscription
- 如何在 SwiftUI 中使用手势
- jQuery 尺寸、位置操作