当前位置:   article > 正文

XGBoost之二分类算法_xgboost二分类

xgboost二分类

1 XGBoost二分类算法简介

XGBoost(Extreme Gradient Boosting)算法是陈天奇博士于2016年发表的论文《 XGBoost:A Scalable Tree Boosting System》中正式提出的。XGBoost在GBDT算法的基础上作出了一系列的优化,如在损失函数的计算中增加了二阶导数,增加了正则项,一定程度上的并行计算等。

XGBoost算法支持回归算法与分类算法。其中的回归算法在《XGBoost回归算法原理与应用》中有着比较详细的讲解。本文讲解分类算法中的二分类算法。XGBoost二分类算法与回归算法的主要区别在于损失函数的构造。

为保证文章结构的完整性,本文沿袭了前一篇文章的相关内容。

2 关于目标函数

2.1 损失函数

f_{t}(x)表示第t轮预测值,w_{t}(x)表示第t棵树在样本x处的取值(权重),L(y,f_{t}(x))表示第t轮的损失函数,损失函数L(y,f_{t}(x))二阶可导。

L(y,f_{t}(x))二阶泰勒展开:

L(y,f_{t}(x))=L(y,f_{t-1}(x)+w_{t}(x))=L(y,f_{t-1}(x))+\frac{\partial L(y,f(x))}{\partial f(x)}|_{f(x)=f_{t-1}(x)}w_{t}(x)+\frac{\partial^2 L(y,f(x))}{2\partial f^2(x)}|_{f(x)=f_{t-1}(x)}w_{t}^{2}(x)+constant

g_{t}=\frac{\partial L(y,f(x))}{\partial f(x)}|_{f(x)=f_{t-1}(x)}h_{t}=\frac{\partial^2 L(y,f(x))}{\partial f^2(x)}|_{f(x)=f_{t-1}(x)}

在XGBoost二分类算法中,一般可选择指数损失函数和经改造的对数损失函数。这里使用经改造的对数损失函数。

L(y,f(x))=-y\ln p-(1-y)\ln(1-p),其中p=\frac{1}{1+e^{-f(x)}},可见0<p<1,对比逻辑回归函数可以发现,p为正样本事件发生的概率。

对损失函数进行变化:

L(y,f(x))=-y\ln p-(1-y)\ln(1-p)=-y\ln \frac{1}{1+e^{-f(x)}}-(1-y)\ln(1-\frac{1}{ 1+e^{-f(x)}})

=-yf(x)+ln(1+e^{f(x)})

具体推导过程见前一篇文章。

损失函数关于f(x)的一阶、二阶导数分别为:

{L}'=-y+\frac{1}{1+e^{-f(x)}}=-y+p

{L}''=-(1+e^{-f(x)})^{-2}*e^{-f(x)}*(-1)=\frac{e^{-f(x)}}{(1+e^{-f(x)})^{2}}=(\frac{1}{p}-1)p^{2}=p(1-p),由于0<p<1,故{L}''>0

故当{L}'=0时,损失函数取得极小值。

g_{t,i}=-y_{i}+p_{i}h_{t,i}=p_{i}(1-p_{i})

其中p_{i}=-y_{i}+\frac{1}{1+e^{-f_{t-1}(x_{i})}}

2.2 目标函数

针对样本构造目标函数,在第t轮时,

Obj=\sum_{i=1}^{N}L(y_{i},f_{t}(x_{i}))

=\sum_{i=1}^{N}(L(y_{i},f_{t-1}(x_{i}))+\frac{\partial L(y_{i},f(x))}{\partial f(x)}|_{f(x)=f_{t-1}(x_{i})}w_{t}(x_{i})+\frac{\partial^2 L(y_{i},f(x))}{2\partial f^2(x)}|_{f(x)=f_{t-1}(x_{i})}w_{t}^{2}(x_{i})+constant)

=\sum_{i=1}^{N}(L(y_{i},f_{t-1}(x_{i}))+\sum_{i=1}^{N}\frac{\partial L(y_{i},f(x))}{\partial f(x)}|_{f(x)=f_{t-1}(x_{i})}w_{t}(x_{i})+\sum_{i=1}^{N}\frac{\partial^2 L(y_{i},f(x))}{\partial f^2(x)}|_{f(x)=f_{t-1}(x_{i})}w_{t}^{2}(x_{i})+constant

=\sum_{i=1}^{N}(L(y_{i},f_{t-1}(x_{i}))+\sum_{i=1}^{N}g_{t,i}w_{t}(x_{i})+\frac{1}{2}\sum_{i=1}^{N}h_{t,i}w_{t}^{2}(x_{i})+constant
在第t轮迭代时,f_{t-1}(x_{i})已知, constant为常数,要使得目标函数最小,仅需要上式中第2、3项的和最小即可。因此,可将目标函数改造成:

Obj=\sum_{i=1}^{N}[g_{t,i}w_{t}(x_{i})+\frac{1}{2}h_{t,i}w_{t}^{2}(x_{i})]

2.3 添加正则项

在第t棵树中,第j个叶子节点对应的样本序号的集合I_{j}=\left \{ i|q(x_{i})=j \right \},在i\in I_{j}时,w_{t}(x_{i})=w_{j}

利用树的复杂度定义正则项,在第t轮迭代时,

\Omega =\gamma J_{t}+\frac{1}{2}\lambda \sum_{j=1}^{J_{t}}w_{j}^{2},其中J_{t}表示第t棵树叶子节点的个数,w_{j}表示第t棵树第j个叶子节点的取值(权重);\gamma,\lambda为设定的参数,且均大于0。

考虑到模型的泛化能力,在目标函数中增加正则项\Omega,则

Obj=\sum_{i=1}^{N}[g_{t,i}w_{t}(x_{i})+\frac{1}{2}h_{t,i}w_{t}^{2}(x_{i})]+\Omega

将正则项代入目标函数:

Obj=\sum_{i=1}^{N}[g_{t,i}w_{t}(x_{i})+\frac{1}{2}h_{t,i}w_{t}^{2}(x_{i})]+(\gamma J_{t}+\frac{1}{2}\lambda \sum_{j=1}^{J_{t}}w_{j}^{2})

Obj=\sum_{j=1}^{J_{t}}[\sum_{i\in I_{j}}^{}(g_{t,i}w_{t}(x_{i})+\frac{1}{2}h_{t,i}w_{t}^{2}(x_{i}))]+(\gamma J_{t}+\frac{1}{2}\lambda \sum_{j=1}^{J_{t}}w_{j}^{2})

=\sum_{j=1}^{J_{t}}\left [ (\sum_{i\in I_{j}}^{}g_{t,i})w_{j}+\frac{1}{2}(\sum_{i\in I_{j}}^{}h_{t,i})w_{j}^{2}\right ]+\gamma J_{t}+\frac{1}{2}\lambda \sum_{j=1}^{J_{t}}w_{j}^{2}

=\sum_{j=1}^{J_{t}}\left [ (\sum_{i\in I_{j}}^{}g_{t,i})w_{j}+\frac{1}{2}(\sum_{i\in I_{j}}^{}h_{t,i}+\lambda )w_{j}^{2}\right ]+\gamma J_{t}

G_{j}=\sum_{i\in I_{j}}^{}g_{t,i},H_{j}=\sum_{i\in I_{j}}^{}h_{t,i},则

Obj=\sum_{j=1}^{J_{t}}\left [ G_{j}w_{j}+\frac{1}{2}(H_{j}+\lambda )w_{j}^{2}\right ]+\gamma J_{t}

2.4 目标函数最优解

从目标函数的表达式可以看出,在第j个叶子节点时的表达式是关于w_{j}的一元二次函数,在w_{j}=w_{j}^{*}=-\frac{G_{j}}{2*\frac{1}{2}(H_{j}+\lambda )}=-\frac{G_{j}}{H_{j}+\lambda }时目标函数取得极值。

此时,Obj=-\frac{1}{2}\sum_{j=1}^{J_{t}}\frac{G_{j}^{2}}{H_{j}+\lambda }+\gamma J_{t}

3 树的生成

XGBoost树的节点分裂,支持贪心算法和近似算法,这里介绍贪心算法。

3.1 节点分裂

假设叶子节点继续分裂分成左右(L,R)两个叶子节点。分裂前叶子节点的个数J_{t}为1,分裂后变为2。在第t棵树中,分裂后的G_{j}分别记为G_{L},G_{R},分裂后的H_{j}分别记为H_{L},H_{R}

则可计算分裂前后的目标函数增益:

Gain=Obj_{L+R}-(Obj_{L}+Obj_{R})

=-\frac{1}{2}\frac{(G_{L}+G_{R})^{2}}{H_{L}+H_{R}+\lambda }+\gamma -(-\frac{1}{2}\frac{G_{L}^{2}}{H_{L}+\lambda }+\gamma -\frac{1}{2}\frac{G_{R}^{2}}{H_{R}+\lambda }+\gamma)

=\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 })-\gamma

对于所有可能的分裂,计算上述增益,以增益最大的分裂作为本次的节点分裂。

对于分裂后的叶子节点,继续按照上述贪心算法进行分裂,直至无法分裂或满足停止条件(如增益小于指定值、叶子节点的样本数量限制、树的深度达到指定值等),生成本轮决策树。

3.2 样本取值

在上述生成树的叶子节点中,在第j个叶子节点的取值w_{j}=w_{j}^{*}=-\frac{G_{j}}{H_{j}+\lambda }

4 XGBoost回归算法过程

4.1 输入输出

1)输入

训练样本集:D=\left \{ (x_{1},y_{1}),(x_{2},y_{2}),...,(x_{N},y_{N}) \right \},其中y_{i}\in \left \{ 0,1 \right \},i=1,2,...,N

2)输出

最终决策树f(x),并可将其转化为正样本事件发生概率p(x)=\frac{1}{1+e^{-f(x)}},以及据此进行样本分类。

4.2 模型初始化

设定\lambda ,\gamma

假设初始化的弱学习器f_{0}(x_{i})=c,代价函数cost(c)=\sum_{i=1}^{N}L(y_{i},c)

c=\underset{c}{arg\min }\sum_{i=1}^{N}L(y_{i},c)

当损失函数是上述对数损失函数时,c=ln\frac{\sum_{i=1}^{N}y_{i}}{\sum_{i=1}^{N}(1-y_{i})}

其推导过程见《GBDT之二分类算法》。

模型的初始化会影响迭代效率。

4.3 进行迭代

对于t=1,2,...,T轮迭代:

1)计算负梯度

f(x)=f_{t-1}(x)时,其负梯度为

-\left [ \frac{\partial L(y,f(x))}{\partial f(x)}\right ]_{f(x)=f_{t-1}(x)}=-{L}'_{f(x)=f_{t-1}(x)}=y-\frac{1}{1+e^{-f_{t-1}(x)}}

 对于第i个样本,其负梯度r_{t,i}=-\frac{\partial L(y_{i},f(x))}{\partial f(x)}|_{f(x)=f_{t-1}(x_{i})} 

=y_{i}-\frac{1}{1+e^{-f_{t-1}(x_{i})}}=y_{i}-p_{i},i=1,2,...,N

2)利用负梯度生成回归树

利用负梯度构建新的数据集D_{t}=\left \{ (x_{1},r_{t,1}),(x_{2},r_{t,2}),...,(x_{N},r_{t,N}) \right \}

计算g_{t,i},h_{t,i},i=1,2,...,N,计算G_{j},H_{j}

按照前述“树的生成”中的方法,生成本轮决策树w_{t}(x)

叶子节点的区域为R_{t,j},j=1,2,...,J_{t},其取值w_{t,j}=-\frac{G_{j}}{H_{j}+\lambda }

3)更新强学习器

f_{t}(x)=f_{t-1}(x)+w_{t}(x)=f_{t-1}(x)+\sum_{j=1}^{J_{t}}w_{t,j}I(x\in R_{t,j})

在不满足停止条件时,继续迭代。

在模型实现过程中,一般会增加一个学习率。

   4) 得到最终学习器

在第T轮迭代时:当目标函数小于指定值或满足其它设定的停止条件(如迭代次数、分类器在训练集或测试集上的性能等)时,迭代停止。

f(x)=f_{T}(x)=f_{0}(x)+\sum_{t=1}^{T}\sum_{j=1}^{J_{t}}w_{t,j}I(x\in R_{t,j})

5 算法代码实现

  1. import pandas as pd
  2. import numpy as np
  3. from xgboost import XGBClassifier
  4. from sklearn.datasets import load_iris
  1. #选择sklearn中的数据集
  2. from sklearn.datasets import load_breast_cancer
  3. data = datasets.load_breast_cancer()
  4. X,y = data.data,data.target
  1. #选择默认参数训练模型
  2. xgb = XGBClassifier()
  3. xgb.fit(X,y)
XGBClassifier(base_score=0.5, booster='gbtree', callbacks=None,
              colsample_bylevel=1, colsample_bynode=1, colsample_bytree=1,
              early_stopping_rounds=None, enable_categorical=False,
              eval_metric=None, gamma=0, gpu_id=-1, grow_policy='depthwise',
              importance_type=None, interaction_constraints='',
              learning_rate=0.300000012, max_bin=256, max_cat_to_onehot=4,
              max_delta_step=0, max_depth=6, max_leaves=0, min_child_weight=1,
              missing=nan, monotone_constraints='()', n_estimators=100,
              n_jobs=0, num_parallel_tree=1, objective='binary:logistic',
              predictor='auto', random_state=0, reg_alpha=0, ...)
  1. #模型预测
  2. xgb.predict(X[100:110])
array([0, 1, 1, 1, 1, 0, 1, 1, 0, 1])

6 算法说明

XGBoost二分类算法与XGBoost回归算法的最大区别在于损失函数。对于回归算法,损失函数一般选择平方损失函数;对于二分类算法,损失函数一般选择对数损失函数。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/473246
推荐阅读
相关标签
  

闽ICP备14008679号