本文首发于我的微信公众号里,地址:【完善版】深入理解GBDT二分类算法
我的个人微信公众号:Microstrong
微信公众号ID:MicrostrongAI
微信公众号介绍:Microstrong(小强)同学主要研究机器学习、深度学习、计算机视觉、智能对话系统相关内容,分享在学习过程中的读书笔记!期待您的关注,欢迎一起学习交流进步!
个人博客:https://blog.csdn.net/program_developer
目录:
1. GBDT分类算法简介
2. GBDT二分类算法
2.1 逻辑回归的对数损失函数
2.2 GBDT二分类原理
3. GBDT二分类算法实例
4. 手撕GBDT二分类算法
4.1 用Python3实现GBDT二分类算法
4.2 用sklearn实现GBDT二分类算法
5. GBDT分类任务常见的损失函数
6. 总结
7. Reference
本文的主要内容概览:
1. GBDT分类算法简介
GBDT无论用于分类还是回归,一直使用的是CART回归树。GBDT不会因为我们所选择的任务是分类任务就选用分类树,这里的核心原因是GBDT每轮的训练是在上一轮训练模型的负梯度值基础之上训练的。这就要求每轮迭代的时候,真实标签减去弱分类器的输出结果是有意义的,即残差是有意义的。如果选用的弱分类器是分类树,类别相减是没有意义的。对于这样的问题,可以采用两种方法来解决:
- 一是采用指数损失函数,这样GBDT就退化成了Adaboost,能够解决分类的问题;
- 二是使用类似于逻辑回归的对数似然损失函数,如此可以通过结果的概率值与真实概率值的差距当做残差来拟合;
下面我们就通过二分类问题,去看看GBDT究竟是如何做分类的。
2. GBDT二分类算法
2.1 逻辑回归的对数损失函数
逻辑回归的预测函数为:
函数
下面我们根据上式,推导出逻辑回归的对数损失函数
然后取似然函数为:
因为
最大似然估计就是求使
2.2 GBDT二分类原理
逻辑回归单个样本
其中,
其中,第
对于生成的决策树,计算各个叶子节点的最佳残差拟合值为:
由于上式没有闭式解(closed form solution),我们一般使用近似值代替:
补充近似值代替过程:
假设仅有一个样本:
令,则
求一阶导:
求二阶导:
对于的泰勒二阶展开式:取极值时,上述二阶表达式中的c为:
GBDT二分类算法完整的算法过程如下:
(1)初始化第一个弱学习器
其中,
(2)对于建立
a)对
b)对于
c)对于
d)更新强学习器
(3)得到最终的强学习器
从以上过程中可知,除了由损失函数引起的负梯度计算和叶子节点的最佳残差拟合值的计算不同,二元GBDT分类和GBDT回归算法过程基本相似。那二元GBDT是如何做分类呢?
将逻辑回归的公式进行整理,我们可以得到
3. GBDT二分类算法实例
(1)数据集介绍
训练集如下表所示,一组数据的特征有年龄和体重,把身高大于1.5米作为分类边界,身高大于1.5米的令标签为1,身高小于等于1.5米的令标签为0,共有4组数据。
测试数据如下表所示,只有一组数据,年龄为25、体重为65,我们用在训练集上训练好的GBDT模型预测该组数据的身高是否大于1.5米?
(2)模型训练阶段
参数设置:
- 学习率:learning_rate = 0.1
- 迭代次数:n_trees = 5
- 树的深度:max_depth = 3
1)初始化弱学习器:
2)对于建立M棵分类回归树
由于我们设置了迭代次数:n_trees=5,这就是设置了M=5。
首先计算负梯度,根据上文损失函数为对数损失时,负梯度(即伪残差、近似残差)为:
我们知道梯度提升类算法,其关键是利用损失函数的负梯度的值作为回归问题提升树算法中的残差的近似值,拟合一个回归树。这里,为了称呼方便,我们把负梯度叫做残差。
现将残差的计算结果列表如下:
此时将残差作为样本的标签来训练弱学习器
接着寻找回归树的最佳划分节点,遍历每个特征的每个可能取值。从年龄特征值为5开始,到体重特征为70结束,分别计算分裂后两组数据的平方损失(Square Error),
例如:以年龄7为划分节点,将小于7的样本划分为到左节点,大于等于7的样本划分为右节点。左节点包括
以上划分点的总平方损失最小为0.000,有两个划分点:年龄21和体重60,所以随机选一个作为划分点,这里我们选年龄21。现在我们的第一棵树长这个样子:
我们设置的参数中树的深度max_depth=3,现在树的深度只有2,需要再进行一次划分,这次划分要对左右两个节点分别进行划分,但是我们在生成树的时候,设置了三个树继续生长的条件:
- 深度没有到达最大。树的深度设置为3,意思是需要生长成3层。
- 点样本数 >= min_samples_split
- 此节点上的样本的标签值不一样(如果值一样说明已经划分得很好了,不需要再分)(本程序满足这个条件,因此树只有2层)
最终我们的第一棵回归树长下面这个样子:
此时我们的树满足了设置,还需要做一件事情,给这棵树的每个叶子节点分别赋一个参数
根据上述划分结果,为了方便表示,规定从左到右为第1,2个叶子结点,其计算值过程如下:
此时的第一棵树长下面这个样子:
接着更新强学习器,需要用到学习率:learning_rate=0.1,用
为什么要用学习率呢?这是Shrinkage的思想,如果每次都全部加上拟合值
重复此步骤,直到
下面将展示每棵树最终的结构,这些图都是我GitHub上的代码生成的,感兴趣的同学可以去运行一下代码。https://github.com/Microstrong0305/WeChat-zhihu-csdnblog-code/tree/master/Ensemble%20Learning/GBDT_GradientBoostingBinaryClassifier
第一棵树:
第二棵树:
第三棵树:
第四棵树:
第五棵树:
3)得到最后的强学习器:
(3)模型预测阶段
-
- 在
中,测试样本的年龄为25,大于划分节点21岁,所以被预测为2.0000。
- 在
中,测试样本的年龄为25,大于划分节点21岁,所以被预测为1.8187。
- 在
中,测试样本的年龄为25,大于划分节点21岁,所以被预测为1.6826。
- 在
中,测试样本的年龄为25,大于划分节点21岁,所以被预测为1.5769。
- 在
中,测试样本的年龄为25,大于划分节点21岁,所以被预测为1.4927。
最终预测结果为:
4. 手撕GBDT二分类算法
本篇文章所有数据集和代码均在我的GitHub中,地址:https://github.com/Microstrong0305/WeChat-zhihu-csdnblog-code/tree/master/Ensemble%20Learning
4.1 用Python3实现GBDT二分类算法
需要的Python库:
pandas、PIL、pydotplus、matplotlib
其中pydotplus库会自动调用Graphviz,所以需要去Graphviz官网下载graphviz-2.38.msi安装,再将安装目录下的bin添加到系统环境变量,最后重启计算机。
由于用Python3实现GBDT二分类算法代码量比较多,我这里就不列出详细代码了,感兴趣的同学可以去我的GitHub中看一下,地址:https://github.com/Microstrong0305/WeChat-zhihu-csdnblog-code/tree/master/Ensemble%20Learning/GBDT_GradientBoostingBinaryClassifier
4.2 用sklearn实现GBDT二分类算法
import
用sklearn中的GBDT库实现GBDT二分类算法的难点在于如何更好的调节下列参数:
用sklearn实现GBDT二分类算法的GitHub地址:https://github.com/Microstrong0305/WeChat-zhihu-csdnblog-code/tree/master/Ensemble%20Learning/GBDT_Classification_sklearn
5. GBDT分类任务常见的损失函数
对于GBDT分类算法,其损失函数一般有对数损失函数和指数损失函数两种:
(1)如果是指数损失函数,则损失函数表达式为:
其负梯度计算和叶子节点的最佳负梯度拟合可以参看Adaboost算法过程。
(2)如果是对数损失函数,分为二元分类和多元分类两种,本文主要介绍了GBDT二元分类的损失函数。
6. 总结
在本文中,我们首先简单介绍了如何把GBDT回归算法变成分类算法的思路;然后从逻辑回归的对数损失函数推导出GBDT的二分类算法原理;其次不仅用Python3实现GBDT二分类算法,还用sklearn实现GBDT二分类算法;最后介绍了GBDT分类任务中常见的损失函数。GBDT可以完美的解决二分类任务,那它对多分类任务是否有效呢?如果有效,GBDT是如何做多分类呢?这些问题都需要我们不停的探索和挖掘GBDT的深层原理。让我们期待一下GBDT在多分类任务中的表现吧!
7. Reference
【1】Friedman J H. Greedy function approximation: a gradient boosting machine[J]. Annals of statistics, 2001: 1189-1232.
【2】GBDT详细讲解&常考面试题要点,地址:https://mp.weixin.qq.com/s/M2PwsrAnI1S9SxSB1guHdg
【3】机器学习算法GBDT的面试要点总结-上篇,地址:https://www.cnblogs.com/ModifyRong/p/7744987.html
【4】Gradient Boosting Decision Tree,地址:http://gitlinux.net/2019-06-11-gbdt-gradient-boosting-decision-tree/
【5】GBDT算法用于分类问题 - hunter7z的文章 - 知乎,地址:https://zhuanlan.zhihu.com/p/46445201
【6】当我们在谈论GBDT:Gradient Boosting 用于分类与回归 - 余文毅的文章 - 知乎
,地址: https://zhuanlan.zhihu.com/p/25257856
【7】 GBDT原理与Sklearn源码分析-分类篇,地址:https://blog.csdn.net/qq_22238533/article/details/79192579
【8】 《推荐系统算法实践》,黄美灵著。
【9】《百面机器学习》,诸葛越主编、葫芦娃著。
【10】GBDT模型,地址:https://www.jianshu.com/p/0bc32c8e4ca8
【11】代码实战之GBDT,地址:https://louisscorpio.github.io/2018/01/19/%E4%BB%A3%E7%A0%81%E5%AE%9E%E6%88%98%E4%B9%8BGBDT/