GBDT+Xgboost算法与MNIST实践

一、GBDT

GBDT(Gradient Boosting Decision Tree),梯度提升决策树。是一种基于决策树的集成算法。

G B D T = G r a d i e n t B o o s t i n g + D e c i s i o n T r e e GBDT = Gradient Boosting + Decision Tree GBDT=GradientBoosting+DecisionTree

  • 其中Gradient Boosting 是集成方法boosting中的一种算法,通过梯度提升来对新的学习器进行迭代。
  • GBDT中采用的决策树是CART回归树,无论是处理回归还是分类问题,GBDT使用的决策树通通都是都是CART回归树,因为GBDT每次迭代要拟合的是梯度值,是连续值,所以要用回归树。

(一)原理

1、Boosting提升方法:采用
加法模型(即基函数的线性组合):
F ( x ) = ∑ f i ( x ) F(x)=\sum f_i(x) F(x)=fi(x)
前向分布算法:
F t ( x ) = F t − 1 ( x ) + T ( x ; Θ ) F_t(x)=F_{t-1}(x)+T(x;\Theta) Ft(x)=Ft1(x)+T(x;Θ)
通过经验风险最小化确定决策树参数:
Θ ^ m = a r g min ⁡ Θ m ∑ i = 1 N L ( y i , f m − 1 ( x i ) + T ( x i ; Θ m ) ) \hat{\Theta}_m=arg\min\limits_{\Theta_m}\sum_{i=1}^NL(y_i,f_{m-1}(x_i)+T(x_i;\Theta_m)) Θ^m=argΘmmini=1NL(yi,fm1(xi)+T(xi;Θm))

2、学习残差
GBDT每棵加入的新的树,目标就是是学习残差 y − F ( x ) y-F(x) yF(x)
即:假设已学好t-1个弱学习器(树),则第t棵树 f t ( x ) f_t(x) ft(x) 学习的目标就是 y − F t − 1 ( x ) y-F_{t-1}(x) yFt1(x)

3、残差的替代:负梯度

  • 平方损失函数: L ( y , F ) = 1 2 ( y − F ( x ) ) 2 L(y,F)=\frac{1}{2}(y-F(x))^2 L(y,F)=21(yF(x))2
  • 残差: y i − F ( x i ) = − 1 2 ∂ ( y − F ( x ) ) 2 F ( x ) = − ∂ L ( y , F ( x ) ) ∂ F ( x ) y_i-F(x_i)=-\frac{1}{2}\frac{\partial(y-F(x))^2}{F(x)}=-\frac{\partial L(y,F(x))}{\partial F(x)} yiF(xi)=21F(x)(yF(x))2=F(x)L(y,F(x))

按照学习率进行梯度下降迭代:

f m ( x ) = f m − 1 ( x ) − η ∂ L ( y , F ( x ) ) ∂ F ( x ) f_m(x)=f_{m-1}(x)-\eta \frac{\partial L(y,F(x))}{\partial F(x)} fm(x)=fm1(x)ηF(x)L(y,F(x))

f m ( x ) = f m − 1 ( x ) + η T m f_m(x)=f_{m-1}(x)+\eta T_m fm(x)=fm1(x)+ηTm

∴ T m ( x ) = − ∂ L ( y , f m − 1 ( x ) ) ∂ f m − 1 ( x ) \therefore T_m(x)=-\frac{\partial L(y,f_{m-1}(x))}{\partial f_{m-1}(x)} Tm(x)=fm1(x)L(y,fm1(x))

4、负梯度 ≠ \neq =残差
不同问题的梯度提升树学习算法,使用的损失函数不同(其他损失函数时就不是残差)

  • 用平方误差损失函数的回归问题;
  • 用指数损失函数的分类问题;
  • 用一般损失函数的一般决策问题

(二)算法流程

1、训练数据为 { ( x i , y i ) } i = 1 n \{(x_i,y_i)\}_{i=1}^{n} {(xi,yi)}i=1n,损失函数为 L ( y , F ( x ) ) L(y,F(x)) L(y,F(x)),可以是平方损失、绝对值损失、Huber损失函数等。共迭代M次,训练M棵树。

2、算法流程
算法流程

  • 初始学习器: F 0 ( x ) F_0(x) F0(x)在平方损失函数下,就是初始所有y的均值。
  • 残差 r i m r_{im} rim,在进行前一次训练后,拟合的对象为: { ( x i , r i m ) } i = 1 n \{(x_i,r_{im})\}_{i=1}^{n} {(xi,rim)}i=1n,构建CART回归树来拟合。
  • 为了避免过拟合,引入学习率 γ \gamma γ

二、Xgboost算法

(一)目标函数

1、树的集成:
y i ^ ( t ) = y i ^ ( t − 1 ) + f t ( x i ) = ∑ t = 1 T f t ( x i ) \hat{y_i}^{(t)}=\hat{y_i}^{(t-1)}+f_t(x_i)=\sum_{t=1}^Tf_t(x_i) yi^(t)=yi^(t1)+ft(xi)=t=1Tft(xi)

2、目标函数:
O B j = L ( Θ ) + Ω ( Θ )           Θ = { f 1 , f 2 , . . . , f T } OBj = L(\Theta)+\Omega(\Theta) \ \ \ \ \ \ \ \ \ \Theta=\{f_1,f_2,...,f_T\} OBj=L(Θ)+Ω(Θ)         Θ={f1,f2,...,fT}

其中,损失函数 L ( Θ ) L(\Theta) L(Θ)、模型复杂度 Ω ( Θ ) \Omega(\Theta) Ω(Θ)的定义为:
L ( Θ ) = ∑ i = 1 n l ( y i , y i ^ )  ——对所有样本求和 Ω ( Θ ) = ∑ k = 1 K Ω ( f k )  ——对所有树求和 \begin{aligned} L(\Theta)&=\sum_{i=1}^n l(y_i,\hat{y_i}) \ ——对所有样本求和\\ \Omega(\Theta)&=\sum_{k=1}^K\Omega(f_k) \ ——对所有树求和 \end{aligned} L(Θ)Ω(Θ)=i=1nl(yi,yi^) ——对所有样本求和=k=1KΩ(fk) ——对所有树求和

泰勒展开:
f ( x + Δ x ) ≈ f ( x ) + f ′ ( x ) Δ x + 1 2 f ′ ′ ( x ) Δ x 2 f(x+\Delta{x})\approx f(x)+f'(x)\Delta x+\frac{1}{2} f''(x)\Delta x^2 f(x+Δx)f(x)+f(x)Δx+21f′′(x)Δx2

Δ x \Delta x Δx —— f t ( x i ) f_t(x_i) ft(xi)

f ( x + Δ x ) f(x+\Delta x) f(x+Δx) —— l ( y i , y i ^ ( t − 1 ) + f t ( x i ) ) = l ( y i , y i ^ ( t ) ) l(y_i,\hat{y_i}^{(t-1)}+f_t(x_i))=l(y_i,\hat{y_i}^{(t)}) l(yi,yi^(t1)+ft(xi))=l(yi,yi^(t))

f ( x ) f(x) f(x) —— l ( y i , y i ^ ( t − 1 ) ) l(y_i,\hat{y_i}^{(t-1)}) l(yi,yi^(t1))

f ′ ( x ) f'(x) f(x) —— g i = ∂ l ( y i , y i ^ ( t − 1 ) ) ∂ y i ^ ( t − 1 ) g_i=\frac{\partial l(y_i,\hat{y_i}^{(t-1)})}{\partial \hat{y_i}^{(t-1)}} gi=yi^(t1)l(yi,yi^(t1))

f ′ ′ ( x ) f''(x) f′′(x) —— h i = ∂ 2 l ( y i , y i ^ ( t − 1 ) ) ∂ y i ^ ( t − 1 ) 2 h_i=\frac{\partial^2 l(y_i,\hat{y_i}^{(t-1)})}{\partial{ \hat{y_i}^{(t-1)}}^2} hi=yi^(t1)22l(yi,yi^(t1))

代入上式、泰勒展开,目标函数最终形式:
O B j ( t ) = ∑ i = 1 n l ( y i , y i ^ ( t ) ) + ∑ k = 1 K Ω ( f k ) = ∑ i = 1 n l ( y i , y i ^ ( t − 1 ) + f t ( x i ) ) + Ω ( f t ) + C = ∑ i = 1 n [ l ( y i , y i ^ ( t − 1 ) ) + g i f t ( x i ) + 1 2 h i f t 2 ( x i ) ] + Ω ( f t ) + C \begin{aligned} OBj^{(t)}&=\sum_{i=1}^n l(y_i,\hat{y_i}^{(t)}) +\sum_{k=1}^K\Omega(f_k) \\ &= \sum_{i=1}^n l(y_i,\hat{y_i}^{(t-1)}+f_t(x_i)) +\Omega(f_t)+C \\ &= \sum_{i=1}^n [l(y_i,\hat{y_i}^{(t-1)})+g_if_t(x_i)+\frac{1}{2}h_if_t^2(x_i)] +\Omega(f_t)+C \end{aligned} OBj(t)=i=1nl(yi,yi^(t))+k=1KΩ(fk)=i=1nl(yi,yi^(t1)+ft(xi))+Ω(ft)+C=i=1n[l(yi,yi^(t1))+gift(xi)+21hift2(xi)]+Ω(ft)+C
其中 g i = ∂ l ( y i , y i ^ ( t − 1 ) ) ∂ y i ^ ( t − 1 ) , h i = ∂ 2 l ( y i , y i ^ ( t − 1 ) ) ∂ y i ^ ( t − 1 ) 2 g_i=\frac{\partial l(y_i,\hat{y_i}^{(t-1)})}{\partial \hat{y_i}^{(t-1)}},h_i=\frac{\partial^2 l(y_i,\hat{y_i}^{(t-1)})}{\partial{ \hat{y_i}^{(t-1)}}^2} gi=yi^(t1)l(yi,yi^(t1)),hi=yi^(t1)22l(yi,yi^(t1))

前t-1颗树已知,所以 ∑ i = 1 n l ( y i , y i ^ ( t − 1 ) ) \sum_{i=1}^n l(y_i,\hat{y_i}^{(t-1)}) i=1nl(yi,yi^(t1)) 为已知常数项。
O B j ( t ) = ∑ i = 1 n [ g i f t ( x i ) + 1 2 h i f t 2 ( x i ) ] + Ω ( f t ) + C \begin{aligned} OBj^{(t)}&= \sum_{i=1}^n [g_if_t(x_i)+\frac{1}{2}h_if_t^2(x_i)] +\Omega(f_t)+C \end{aligned} OBj(t)=i=1n[gift(xi)+21hift2(xi)]+Ω(ft)+C

(二)模型复杂度:

1、定义:待训练的第t颗树有T个叶子结点,叶子结点的输出向量为 [ ω 1 , ω 2 , . . . , ω T ] [\omega_1,\omega_2,...,\omega_T] [ω1,ω2,...,ωT] q : R d → { 1 , 2 , 3 , . . . , T } q:R^d \rightarrow \{1,2,3,...,T\} q:Rd{1,2,3,...,T}
所以, q ( x ) q(x) q(x)表示对于每一个样本点x,其对应的叶子结点。
所以, w q ( x ) w_{q(x)} wq(x)表示样本点x对应的叶子结点输出值,也就是树最终拟合的 f t ( x i ) f_t(x_i) ft(xi)

2、对于每一个叶子结点 j j j,定义 I j = { i ∣ q ( x i ) = j } I_j=\{i|q(x_i)=j\} Ij={iq(xi)=j},表示每个叶子结点所包含的样本 x i x_i xi

3、所以模型复杂度定义为:
Ω ( f t ) = γ T + 1 2 λ ∑ j = 1 T ω j 2 \Omega(f_t)=\gamma T+\frac{1}{2} \lambda\sum_{j=1}^T \omega_j^2 Ω(ft)=γT+21λj=1Tωj2
T T T为叶子结点数, ω j \omega_j ωj表示叶子结点 j j j的输出, γ \gamma γ为系数

目标函数最终化简为:

O B j ( t ) = ∑ i = 1 n [ g i f t ( x i ) + 1 2 h i f t 2 ( x i ) ] + Ω ( f t ) = ∑ j = 1 T [ ( ∑ i ∈ I j g i ) ω q ( x i ) + 1 2 ( ∑ i ∈ I j h i + λ ) ω q ( x i ) 2 ] + γ T \begin{aligned} OBj^{(t)}&= \sum_{i=1}^n [g_if_t(x_i)+\frac{1}{2}h_if_t^2(x_i)] +\Omega(f_t)\\ &= \sum_{j=1}^T [(\sum_{i\in I_j}g_i) \omega_{q(x_i)}+\frac{1}{2}(\sum_{i\in I_j}h_i+\lambda)\omega_{q(x_i)}^2] +\gamma T \end{aligned} OBj(t)=i=1n[gift(xi)+21hift2(xi)]+Ω(ft)=j=1T[(iIjgi)ωq(xi)+21(iIjhi+λ)ωq(xi)2]+γT
G j = ∑ i ∈ I j g i , H j = ∑ i ∈ I j h i G_j=\sum_{i\in I_j}g_i , H_j=\sum_{i\in I_j}h_i Gj=iIjgiHj=iIjhi

O B j ( t ) = ∑ j = 1 T [ G j ω j + 1 2 ( H i + λ ) ω j 2 ] + γ T \begin{aligned} OBj^{(t)}&= \sum_{j=1}^T [G_j \omega_j+\frac{1}{2}(H_i+\lambda)\omega_j^2] +\gamma T \end{aligned} OBj(t)=j=1T[Gjωj+21(Hi+λ)ωj2]+γT

(三)目标函数优化

目标函数为累加的,相互独立的二次函数,所以对于每一项进行优化。即:
w j = a r g min ⁡ x   G j x + 1 2 ( H j + λ ) x 2 w_j=arg\min\limits_{x} \ G_jx+\frac{1}{2}(H_j+\lambda)x^2\\ wj=argxmin Gjx+21(Hj+λ)x2
解得最优参数: w j ∗ = − G j H j + λ w_j^* = -\frac{G_j}{H_j+\lambda} wj=Hj+λGj

解得目标函数最小值:
O b j ( t ) = − 1 2 ∑ j = 1 T G j 2 H j + λ + γ T Ob_j^{(t)}=-\frac{1}{2}\sum_{j=1}^T\frac{G_j^2}{H_j+\lambda}+\gamma T Obj(t)=21j=1THj+λGj2+γT

(四) 生成树策略

根据决策树的生成策略,再每次分裂节点的时候我们需要考虑能使得损失函数减小最快的节点,也就是分裂后损失函数减去分裂前损失函数我们称之为Gain:
G a i n = 1 2 [ G L 2 H L + λ + G R 2 H R + λ − ( G L + G R ) 2 H L + H R + λ ] − λ Gain=\frac{1}{2}[\frac{G_L^2}{H_L+\lambda}+\frac{G_R^2}{H_R+\lambda}-\frac{(G_L+G_R)^2}{H_L+H_R+\lambda}]-\lambda Gain=21[HL+λGL2+HR+λGR2HL+HR+λ(GL+GR)2]λ
Gain越大越能说明分裂后目标函数值减小越多。

(五)寻找最优节点

1、精确贪心算法
在这里插入图片描述
2、近似算法
在这里插入图片描述

(六)Xgboost 参数

xgboost中XGBClassifier()参数,调参的主要目的为选择合适的方法(分类/回归)、避免过拟合

常规参数

booster
    gbtree 树模型做为基分类器(默认)
    gbliner 线性模型做为基分类器
silent
    silent=0时,输出中间过程(默认)
    silent=1时,不输出中间过程
nthread
    nthread=-1时,使用全部CPU进行并行运算(默认)
    nthread=1时,使用1CPU进行运算。
scale_pos_weight
    正样本的权重,在二分类任务中,当正负样本比例失衡时,设置正样本的权重,模型效果更好。例如,当正负样本比例为1:10时,scale_pos_weight=10

模型参数

n_estimatores
    含义:总共迭代的次数,即决策树的个数
    调参:
early_stopping_rounds
    含义:在验证集上,当连续n次迭代,分数没有提高后,提前终止训练。
    调参:防止overfitting。
max_depth
    含义:树的深度,默认值为6,典型值3-10。
    调参:值越大,越容易过拟合;值越小,越容易欠拟合。
min_child_weight
    含义:叶子结点中样本的数目最小值,默认值为1。
    调参:值越大,避免模型学习到局部的特殊样本,越容易欠拟合;值越小,会出现单个样本成一个叶子结点的情况,越容易过拟合。
subsample
    含义:训练每棵树时,使用的数据占全部训练集的比例。默认值为1,典型值为0.5-1。
    调参:防止overfitting。
colsample_bytree
    含义:训练每棵树时,使用的特征占全部特征的比例。默认值为1,典型值为0.5-1。
    调参:防止overfitting。

学习任务参数

learning_rate
    含义:学习率,控制每次迭代更新权重时的步长,默认0.3。
    调参:值越小,训练越慢。
    典型值为0.01-0.2。
objective 目标函数
    回归任务
        reg:linear (默认)
        reg:logistic
    二分类
        binary:logistic     概率
        binary:logitraw   类别
    多分类
        multi:softmax  num_class=n   返回类别
        multi:softprob   num_class=n  返回概率
    rank:pairwise
eval_metric
    回归任务(默认rmse)
        rmse--均方根误差
        mae--平均绝对误差
    分类任务(默认error)
        auc--roc曲线下面积
        error--错误率(二分类)
        merror--错误率(多分类)
        logloss--负对数似然函数(二分类)
        mlogloss--负对数似然函数(多分类)
gamma
    惩罚项系数,指定节点分裂所需的最小损失函数下降值。
    调参:
alpha
    L1范数的系数,默认为1
lambda
    L2范数的系数,默认为1

示例

model = XGBClassifier(
        booster='gbtree',
        eval_metric='auc',
        n_estimators=140,
        learning_rate =0.05,
        max_depth=7,
        min_child_weight=0.1,
        gamma=20,
        subsample=0.7,
        colsample_bytree=0.7,
        colsample_level=0.7,
        objective= 'binary:logistic',
        nthread=4,
        scale_pos_weight=2,
        reg_alpha=5.4
        reg_lambda=1,
        seed=27,
        alpha=0.1,
        eta= 0.1, 
        silent=0)

三、Xgboost 和 GBDT 的区别:

GBDT:

1、优点:非线性变换比较多,表达能力强,而且不需要做复杂的特征工程和特征变换。
2、缺点:Boost 是一个串行过程,不好并行化,而且计算复杂度高,同时不太适合高维稀疏特征;传统 GBDT 在优化时只用到一阶导数信息。

Xgboost:

1、显式地把树模型复杂度作为正则项加到优化目标中。
2、公式推导中用到了二阶导数,用了二阶泰勒展开。(GBDT 用牛顿法貌似也是二阶信息)
3、实现了分裂点寻找近似算法。
4、利用了特征的稀疏性。
5、数据事先排序并且以 block 形式存储,有利于并行计算。
6、基于分布式通信框架 rabit,可以运行在 MPI 和 yarn 上。(最新已经不基于 rabit 了)
7、实现做了面向体系结构的优化,针对 cache 和内存做了性能优化。

四、代码实例

MNIST手写数字识别数据集——分类问题。

import numpy as np
import pandas as pd
import xgboost as xgb
from sklearn.model_selection import train_test_split
from sklearn import metrics
data = pd.read_csv('../input/digit-recognizer/train.csv')

X, y = data.drop(['label'], axis=1), data['label']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.1, random_state=12)
model = xgb.XGBClassifier(learning_rate =0.3,
 n_estimators=100,
 max_depth=9,
 min_child_weight=1,
 nthread=4,
 seed=27)

model.fit(X_train, y_train)
y_hat = model.predict(X_test)
print(metrics.classification_report(y_test, y_hat))
test = pd.read_csv('../input/digit-recognizer/test.csv')
y_pred = model.predict(test)

index = len(y_pred)
index = [i + 1 for i in range(index)]
y_pred.index = index
y_pred.index.name = 'ImageId'
y_pred = y_pred.rename({0: 'Label'}, axis=1)
y_pred.to_csv('./submission.csv')

在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值