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. Hive详解(05) - 压缩和存储

    Hive详解(05) - 压缩和存储 Hadoop压缩配置 MR支持的压缩编码 压缩格式 算法 文件扩展名 是否可切分 DEFLATE DEFLATE .deflate 否 Gzip DEFLATE ...

  2. 使用SQL4Automation让CodeSYS连接数据库

      摘要:本文旨在说明面向CodeSYS的数据库连接方案SQL4Automation的使用方法. 1.SQL4Automation简介 1.1.什么是SQL4Automation   SQL4Auto ...

  3. visualstudio2017 community版本,有点失去信心了,同样两行代码,外观看不出任何区别,但是一个报错

    不多废话,先上代码 注意查看函数fputs_FILE,该函数的两行代码fopen_s是同样的,但事实上: 第一条fopen_s执行起来会报错,但是第二条就不会!!! /* 练习:获取用户键盘输入,写入 ...

  4. 动力节点——day07

    什么是异常? 异常是指在程序的运行过程中所发生的不正常的事件,它会中断正在运行的程序 Java中异常的存在形式? 异常在java中以类的形式存在,每一个异常类都可以创建异常对象 异常的继承结构图 编译 ...

  5. Python解释器下载与安装

    Python解释器下载与安装 一.Python解释器 1.Python的发展方向 web方向,自动化运维,自动化测试,自动化办公,网络爬虫,金融量化,人工智能,机器学习,数据分析 2.Python解释 ...

  6. 【分析笔记】NXP PCF85263 设备驱动分析笔记

    驱动移植 供应商无法提供相应的驱动程序,不过在 linux 最新的内核倒是有一份 pcf85363 的驱动,看代码并核对寄存器功能,是可以兼容 pcf85263 芯片.只是我们用的内核比较老 linu ...

  7. 12月19日内容总结——Q查询进阶、ORM查询优化、ORM事务、ORM常用字段类型和字段参数、Ajax介绍、数据编码格式、Ajax携带文件数据

    目录 一.Q查询进阶操作 二.ORM查询优化 三.ORM事务操作 四.ORM常用字段类型 五.ORM常用字段参数 六.Ajax AJAX简介 应用场景 AJAX的优点 语法实现 七.数据编码格式(Co ...

  8. Spring02---IOC-Debug查看Bean的实例化过程

    1 简介 springIOC它是对bean进行管理. 我们通常可以通过xml.properties.yml.注解等来配置bean的信息 spring读取这些配置信息,解析,生成BeanDefiniti ...

  9. C++并发-同步并发

    1.等待事件 std::mutex m; void wait() { std::unique_lock<std::mutex> lk(m); lk.unlock(); std::this_ ...

  10. python requests 最牛攻略

    目录 安装 Reuqests HTTP 简介 什么是 HTTP HTTP工作原理 HTTP的9种请求方法 HTTP状态码 requests 快速上手 requests 发起请求的步骤 requests ...