GBDT的决策树:

​ 无论是处理回归任务还是二分类以及多分类任务,GBDT使用的决策树是CART回归树。因为GBDT每次迭代要拟合的是梯度值,是连续值所以要用回归树。

​ 对于回归树算法来说最重要的是寻找最佳的划分点,那么回归树中的可划分点包含了所有特征的所有可取的值。在分类树中最佳划分点的判别标准是熵或者基尼系数,都是用纯度来衡量的,但是在回归树中的样本标签是连续数值,所以再使用熵之类的指标不再合适,取而代之的是平方误差,它能很好的评判拟合程度。

注意:

  • 梯度下降从来都是拟合负梯度,GBDT平方损失只是恰好等于残差

  • 训练步骤:

    • 每棵决策树利用负梯度对样本点进行划分(拟合负梯度)
    • 求使得损失函数最小的C(即树叶子结点的输出),且C的值通常是一个与负梯度相关的式子(见下文分类问题模块介绍)

提升树(Boosting Tree)

​ 先来个通俗理解:假如有个人30岁,我们首先用20岁去拟合,发现损失有10岁,这时我们用6岁去拟合剩下的损失,发现差距还有4岁,第三轮我们用3岁拟合剩下的差距,差距就只有一岁了。如果我们的迭代轮数还没有完,可以继续迭代下面,每一轮迭代,拟合的岁数误差都会减小。最后将每次拟合的岁数加起来便是模型输出的结果。

Gradient Boosting:拟合负梯度

​ 当损失函数是平方损失和指数损失函数时,提升树(Boosting Tree)每一步优化是很简单的,但是对于一般损失函数而言,往往每一步优化起来不那么容易,针对这一问题,Freidman提出了梯度提升树算法,这是利用最速下降的近似方法,其关键是利用损失函数的负梯度作为提升树算法中的残差的近似值。

​ Gradient Boosting 的基本思想是:串行地生成多个弱学习器,每个弱学习器的目标是拟合先前累加模型的损失函数的负梯度, 使加上该弱学习器后的累积模型损失往负梯度的方向减少。即如果第 m 轮弱学习器拟合损失函数关于累积模型 的负梯度,则加上该弱学习器之后累积模型的 loss 会最小。(个人理解是:随着m棵树的不断叠加使得模型的整体梯度趋近于0,模型近似最优

GBDT算法原理

GBDT 回归与分类

  • GBDT(Gradient Boosting Decision Tree)是弱学习器使用 CART 回归树的一种 Gradient Boosting,使用决策树作为弱学习器的一个好处是:决策树本身是一种不稳定的学习器(训练数据的一点波动可能给结果带来较大的影响),从统计学的角度单棵决策树的方差比较大。而在集成学习中,弱学习器间方差越大,弱学习器本身泛化性能越好,则集成学习模型的泛化性能就越好。因此使用决策树作为弱学习器通常比使用较稳定的弱学习器(如线性回归等)泛化性能更好。

  • 回归问题

    GBDT 中的每个弱学习器都是 CART 回归树,在回归问题中,损失函数采用均方损失函数:



    损失函数的负梯度为:



    核心代码如下:

    def fit(self, train_X, train_y):
    self.estimator_list = list()
    self.F = np.zeros_like(train_y, dtype=float) for i in range(1, self.n_estimators + 1):
    # get negative gradients
    neg_grads = train_y - self.F
    base = DecisionTreeRegressor(max_depth=self.max_depth)
    base.fit(train_X, neg_grads) # cart树的叶结点值是负梯度,也是残差
    train_preds = base.predict(train_X)
    self.estimator_list.append(base) if self.is_first:
    self.F = train_preds
    self.is_first = False
    else:
    self.F += self.lr * train_preds
  • 分类问题

    GBDT 中都的弱学习器都是 CART 回归树,在回归问题上使用 GBDT 比较 intuitive,损失函数为均方损失,负梯度就是残差,下一棵树就去拟合之前的树的和与真实值的残差。对于分类问题,可以对拟合目标稍作转换实现分类。

    基本的思路可以参考线性回归通过对数几率转化为逻辑回归进行分类。逻辑回归也是广义上的线性模型,可以看做是线性回归模型去拟合对数几率







    可以看到最后的负梯度形式十分简洁,将此负梯度作为第 m 轮的拟合目标,依次不断迭代,GBDT 分类的核心代码如下:

    @staticmethod
    def logit(F):
    return 1.0 / (1.0 + np.exp(-F)) def fit(self, train_X, train_y):
    self.estimator_list = list()
    self.F = np.zeros_like(train_y, dtype=float) for i in range(1, self.n_estimators + 1):
    # get negative gradients
    neg_grads = train_y - self.logit(self.F)
    base = DecisionTreeRegressor(max_depth=self.max_depth)
    base.fit(train_X, neg_grads) #cart树的叶结点值是负梯度,不是实际标签的残差(个人理解,若有错误,请不吝指教)
    train_preds = base.predict(train_X) # train_preds 即为C
    self.estimator_list.append(base) if self.is_first:
    self.F = train_preds
    self.is_first = False
    else:
    self.F += self.lr * train_preds
    ```

GBDT 优点和局限性

  • 优点
  1. 预测阶段速度快,树与树之间可以并行预测
  2. 在数据分布稠密的数据上,泛化能力和表征能力都很好
  3. 使用 CART 作为弱分类器不需要对数据进行特殊的预处理如归一化等
  • 局限性
  1. 在高维稀疏的数据上,表现不如 SVM 或神经网络
  2. 训练过程需要串行训练,只能在决策树内部采用一些局部并行手段提高训练速度

参考链接:

小点

  • 同一棵树中可以多次利用同一特征进行划分

  • GBDT中会出现两棵树(除叶子结点外)结构相同的情况吗?
    • 学习率太小(把一棵树一次可以拟合好的树,让这棵树分多次来拟合)?

GBDT初识的更多相关文章

  1. Android动画效果之初识Property Animation(属性动画)

    前言: 前面两篇介绍了Android的Tween Animation(补间动画) Android动画效果之Tween Animation(补间动画).Frame Animation(逐帧动画)Andr ...

  2. scikit-learn 梯度提升树(GBDT)调参小结

    在梯度提升树(GBDT)原理小结中,我们对GBDT的原理做了总结,本文我们就从scikit-learn里GBDT的类库使用方法作一个总结,主要会关注调参中的一些要点. 1. scikit-learn ...

  3. 梯度提升树(GBDT)原理小结

    在集成学习之Adaboost算法原理小结中,我们对Boosting家族的Adaboost算法做了总结,本文就对Boosting家族中另一个重要的算法梯度提升树(Gradient Boosting De ...

  4. 初识Hadoop

    第一部分:              初识Hadoop 一.             谁说大象不能跳舞 业务数据越来越多,用关系型数据库来存储和处理数据越来越感觉吃力,一个查询或者一个导出,要执行很长 ...

  5. python学习笔记(基础四:模块初识、pyc和PyCodeObject是什么)

    一.模块初识(一) 模块,也叫库.库有标准库第三方库. 注意事项:文件名不能和导入的模块名相同 1. sys模块 import sys print(sys.path) #打印环境变量 print(sy ...

  6. 初识IOS,Label控件的应用。

    初识IOS,Label控件的应用. // // ViewController.m // Gua.test // // Created by 郭美男 on 16/5/31. // Copyright © ...

  7. UI篇(初识君面)

    我们的APP要想吸引用户,就要把UI(脸蛋)搞漂亮一点.毕竟好的外貌是增进人际关系的第一步,我们程序员看到一个APP时,第一眼就是看这个软件的功能,不去关心界面是否漂亮,看到好的程序会说"我 ...

  8. Python导出Excel为Lua/Json/Xml实例教程(一):初识Python

    Python导出Excel为Lua/Json/Xml实例教程(一):初识Python 相关链接: Python导出Excel为Lua/Json/Xml实例教程(一):初识Python Python导出 ...

  9. 初识SpringMvc

    初识SpringMvc springMvc简介:SpringMVC也叫Spring Web mvc,属于表现层的框架.Spring MVC是Spring框架的一部分,是在Spring3.0后发布的 s ...

  10. 初识redis数据类型

    初识redis数据类型 1.String(字符串) string是redis最基本的类型,一个key对应一个value. string类型是二进制安全的.意思是redis的string可以包含任何数据 ...

随机推荐

  1. 题解P3847 [TJOI2007]调整队形

    简要题意 给出一个长度为 \(n\) 的序列 \(A\),你需要执行下面的操作,将这个序列变成回文序列: 在序列左右侧或中间插入一个元素,元素数值任意. 删除一个元素. 更改一个元素的值. \(1 \ ...

  2. 01-Verilog基础

    Verilog RTL编程实践 在进行数字IC设计过程中,RTL coding能力是非常重要的.结合逻辑仿真(VCS)和逻辑综合(Design Compiler)工具.看RTL. 1 ASIC Des ...

  3. 写出单个字符到文件-flush方法和close方法的区别

    写出单个字符到文件 flush方法和close方法的区别 因为内置缓冲区的原因,如果不关闭输出流,无法写出字符到文件中.但是关闭的流对象,是无法继续写出数据的.如果我们既想写出数据,又想继续使用流,就 ...

  4. Vue项目 invalid host header 问题 配置 disableHostCheck:true报错

    项目场景: 解决 Vue 项目 invalid host header 问题disableHostCheck:true报错 问题描述 使用内网穿透时出现 invalid host header 找了好 ...

  5. vue学习笔记(四)---- 品牌管理案例

    一.导入相关包 <script src="../lib/vue2.6.10.min.js"></script> <script src=". ...

  6. ChatGPT 背后核心技术的白话版

    本文是关于ChatGPT 背后核心技术实现的一个通俗白话版,不涉及到的AI具体实现的技术细节哦. 在编排上增加了一些分割,内容具体如下: LLMs(大型语言模型) 如果将ChatGPT比作是动物,它就 ...

  7. 企业微信集成openai实现ChatGPT机器人

    背景: 现在网上查资料,痛点太多了,什么广告,什么重复的,对于程序员的我来说,简直是无语 最近接触到ChatGpt,问了些技术问题,答的比某度好,甚至可以写代码,真的太棒了 因此想写个专门的机器人,给 ...

  8. 洛谷p5723

    1 #include<bits/stdc++.h> 2 using namespace std; 3 int z(int a) 4 { 5 if(a==2) return 1; 6 if( ...

  9. Vue31 消息订阅和发布

    1 简介 组件之间的通信除了使用事件总线之外,还可以使用一些插件来通过消息的订阅和发布来实现.pubsub-js就是一个不错的选择. 2 使用 2.1 安装 npm i pubsub-js # 或 y ...

  10. 线程基础知识 04 synchronized锁的四种状态和升级

    转https://www.cnblogs.com/mingyueyy/p/13054296.html 1 轻量级锁和重量级锁简要说明 线程调度本来是由操作系统来管理的.现在,操作系统上跑了一个虚拟机J ...