机器学习入门:极度舒适的GBDT原理拆解

机器学习入门:极度舒适的GBDT拆解

本文旨用小例子+可视化的方式拆解GBDT原理中的每个步骤,使大家可以彻底理解GBDT

BoostingGradient Boosting

Boosting是集成学习的一种基分类器(弱分类器)生成方式,核心思想是通过迭代生成了一系列的学习器,给误差率低的学习器高权重,给误差率高的学习器低权重,结合弱学习器和对应的权重,生成强学习器。

前文我们讲过的AdaBoost就是典型的Boosting算法

Boosting算法要涉及到两个部分,加法模型和前向分步算法。
加法模型就是说强分类器由一系列弱分类器线性相加而成。一般组合形式如下:
F_M(x;P)=\sum_{m=1}^n\beta_mh(x;a_m)
其中,h(x;a_m)就是一个个的弱分类器,a_m是弱分类器学习到的最优参数,β_m就是弱学习在强分类器中所占比重,P是所有α_mβ_m的组合。这些弱分类器线性相加组成强分类器。

前向分步就是说在训练过程中,下一轮迭代产生的分类器是在上一轮的基础上训练得来的。也就是可以写成这样的形式:
F_m (x)=F_{m-1}(x)+ \beta_mh_m (x;a_m)

Gradient Boosting = Gradient Descent + Boosting

Boosting 算法(以AdaBoost为代表)用错分数据点来识别问题,通过调整错分数据点的权重来改进模型。Gradient Boosting通过负梯度来识别问题,通过计算负梯度来改进模型。

Gradient Boosting每次迭代的目标是为了减少上一次的残差,在残差减少的梯度(Gradient)方向上建立一个新的模型,每个新的模型的建立是使之前模型的残差往梯度方向减少。

第t轮的第i个样本的损失函数的负梯度为:
\large {r_{mi}} = -\left[\frac{\partial L(y_i,f(x_i))}{\partial f(x_i)} \right]_{f(x)=f_{m-1}(x)}

此时不同的损失函数将会得到不同的负梯度,如果选择平方损失
L(y_i,f(x_i)) = \frac{1}{2}(y_i - f(x_i))^2

负梯度为r_{mi} = y_i - f(x_i)

此时我们发现GBDT的负梯度就是残差,所以说对于回归问题,我们要拟合的就是残差。


image

GBDT回归算法

输入是训练集样本T=\{(x_,y_1),(x_2,y_2), ...(x_m,y_m)\}, 最大迭代次数T, 损失函数L。
输出是强学习器f(x)

  1. 初始化弱学习器
  2. 对迭代轮数t=1,2,...T有:
    f_0(x) = \underbrace{arg\; min}_{c}\sum\limits_{i=1}^{m}L(y_i, c)

a)对样本i=1,2,...m,计算负梯度
r_{ti} = -\bigg[\frac{\partial L(y_i, f(x_i)))}{\partial f(x_i)}\bigg]_{f(x) = f_{t-1}\;\;(x)}
b)利用(x_i,r_{ti})\;\; (i=1,2,..m), 拟合一颗CART回归树,得到第t颗回归树,其对应的叶子节点区域为R_{tj}, j =1,2,..., J。其中J为回归树t的叶子节点的个数。

c) 对叶子区域j =1,2,..J,计算最佳拟合值
c_{tj} = \underbrace{arg\; min}_{c}\sum\limits_{x_i \in R_{tj}} L(y_i,f_{t-1}(x_i) +c)
d)更新强学习器
f_{t}(x) = f_{t-1}(x) + \sum\limits_{j=1}^{J}c_{tj}I(x \in R_{tj})

  1. 得到强学习器f(x)的表达式
    f(x) = f_T(x) =f_0(x) + \sum\limits_{t=1}^{T}\sum\limits_{j=1}^{J}c_{tj}I(x \in R_{tj})

二元GBDT分类算法

对于二元GBDT,如果用类似于逻辑回归的对数似然损失函数,则损失函数为:
L(y, f(x)) = log(1+ exp(-yf(x)))
其中y∈{?1,+1}。则此时的负梯度误差为
r_{ti} = -\bigg[\frac{\partial L(y, f(x_i)))}{\partial f(x_i)}\bigg]_{f(x) = f_{t-1}\;\; (x)} = y_i/(1+exp(y_if(x_i)))
    对于生成的决策树,我们各个叶子节点的最佳负梯度拟合值为
c_{tj} = \underbrace{arg\; min}_{c}\sum\limits_{x_i \in R_{tj}} log(1+exp(-y_i(f_{t-1}(x_i) +c)))
    由于上式比较难优化,我们一般使用近似值代替
c_{tj} = \sum\limits_{x_i \in R_{tj}}r_{ti}\bigg / \sum\limits_{x_i \in R_{tj}}|r_{ti}|(1-|r_{ti}|)
除了负梯度计算和叶子节点的最佳负梯度拟合的线性搜索,二元GBDT分类和GBDT回归算法过程相同。

小例子+可视化理解GBDT

上面对原理进行了分析之后,大致对GBDT有了一定的认识,为了更加形象的解释GBDT的内部执行过程,这里引用《统计学习方法》中adaboost一节中的案例数据来进行进一步分析。强烈建议大家对比学习,看一下Adaboost和 GBDT 的区别和联系。
数据集如下:

image

采用GBDT进行训练,为了方便,我们采用MSE作为损失函数,并且将树的深度设为1,决策树个数设为5,其他参数使用默认值

import numpy as np
import pandas as pd
from sklearn import tree
import matplotlib.pyplot as plt
from sklearn.ensemble import GradientBoostingRegressor
from sklearn.model_selection import train_test_split 

X = np.arange(1,11)
y = np.array([5.56, 5.70, 5.91, 6.40, 6.80, 7.05, 8.90, 8.70, 9.00, 9.05])
display(X,y)

gbdt = GradientBoostingRegressor(n_estimators=5,max_depth=1)
gbdt.fit(X.reshape(-1,1),y)

其中GradientBoostingRegressor主要参数如下

GradientBoostingRegressor(alpha=0.9, criterion='friedman_mse', init=None,
                          learning_rate=0.1, loss='ls', max_depth=1,
                          max_features=None, max_leaf_nodes=None,
                          min_impurity_decrease=0.0, min_impurity_split=None,
                          min_samples_leaf=1, min_samples_split=2,
                          min_weight_fraction_leaf=0.0, n_estimators=5,
                          n_iter_no_change=None, presort='auto',
                          random_state=None, subsample=1.0, tol=0.0001,
                          validation_fraction=0.1, verbose=0, warm_start=False)
image

其他参数为决策树参数,大家应该已经很熟悉了,不再赘述。

下面我们根据GBDT回归算法原理,开始分步硬核拆解:

第一步:根据初始化公式
f_0(x) = \underbrace{arg\; min}_{c}\sum\limits_{i=1}^{m}L(y_i, c)
可以计算出F_{0}(x)=7.307(本例中,恰好为yi均值)

第二步:计算损失函数的负梯度值:
r_{ti} = -\bigg[\frac{\partial L(y_i, f(x_i)))}{\partial f(x_i)}\bigg]_{f(x) = f_{t-1}\;\; (x)}
由于是MSE损失,上式等于\hat{y}_i = y_i - F_{m-1}(x_i),结果如下:

#计算残差
y - y.mean()
[out]:
array([-1.747, -1.607, -1.397, -0.907, -0.507, -0.257,  1.593,  1.393,
        1.693,  1.743])

第三步:对上面残差拟合第一棵树
根据所给的数据,可以考虑的切分点为1.5、2.5、3.5、4.5、5.5、6.5、7.5、8.5、9.5分别计算y_i - F_{0}(x_i)的值,并计算出切分后的左右两侧加和MSE最小的切分,最后得到的是6.5

找到最佳的切分点之后,我们可以得到各个叶子节点区域,并计算出R_{jm}\gamma_{jm}.此时,R_{11}x小于6.5的数据,R_{21}为x大于6.5的数据。同时,
<p>r_{11} = \frac{1}{6} \sum_{x_i \in R_{11}} y_{i}=-1.0703</p>
<p>r_{21} = \frac{1}{4} \sum_{x_i \in R_{21}} y_{i}=1.6055</p>

print((y - y.mean())[:6].mean(),
(y - y.mean())[6:10].mean())
[out]:-1.07 1.605
#计算mse
print(
((y - y.mean())**2).mean(),
((y[:6] - y[:6].mean())**2).mean(),
((y[6:10] - y[6:10].mean())**2).mean())
[out]
1.911421 0.309689 0.0179686

第一棵树的可视化

tree.plot_tree(gbdt[0,0],filled=True)
image

最后:更新F_{1}(x_i)的值
F_1(x_i)=F_{0}(x_i)+ \rho_m \sum^2_{j=1} \gamma_{j1} I(x_i \in R_{j1}),其中\rho_m为学习率,或称shrinkage,目的是防止预测结果发生过拟合,默认值是0.1。

至此第一轮迭代完成,后面的迭代方式与上面一样,
本例中我们生成了5棵树,大家可以用tree.plot_tree可视化其他树

第二棵树

课后作业,大家可以思考一下,第二棵树中的value是如何计算出来的?其实很简单哈????

迭代m次后,第m次的F_{m}(x)即为最终的预测结果。</p>
<p><br>F_{m}(x) = F_{m-1}(x) + \rho_{m} h(x; a_m)</p>

参考

https://www.cnblogs.com/pinard/p/6140514.html
https://blog.csdn.net/u014168855/article/details/105481881
https://www.csuldw.com/2019/07/12/2019-07-12-an-introduction-to-gbdt/

image
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,222评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,455评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,720评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,568评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,696评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,879评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,028评论 3 409
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,773评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,220评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,550评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,697评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,360评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,002评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,782评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,010评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,433评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,587评论 2 350