1 XGBoost二分类算法简介
XGBoost(Extreme Gradient Boosting)算法是陈天奇博士于2016年发表的论文《 XGBoost:A Scalable Tree Boosting System》中正式提出的。XGBoost在GBDT算法的基础上作出了一系列的优化,如在损失函数的计算中增加了二阶导数,增加了正则项,一定程度上的并行计算等。
XGBoost算法支持回归算法与分类算法。其中的回归算法在《XGBoost回归算法原理与应用》中有着比较详细的讲解。本文讲解分类算法中的二分类算法。XGBoost二分类算法与回归算法的主要区别在于损失函数的构造。
为保证文章结构的完整性,本文沿袭了前一篇文章的相关内容。
2 关于目标函数
2.1 损失函数
以表示第
轮预测值,
表示第
棵树在样本
处的取值(权重),
表示第
轮的损失函数,损失函数
二阶可导。
将二阶泰勒展开:
记,
在XGBoost二分类算法中,一般可选择指数损失函数和经改造的对数损失函数。这里使用经改造的对数损失函数。
,其中
,可见
,对比逻辑回归函数可以发现,
为正样本事件发生的概率。
对损失函数进行变化:
具体推导过程见前一篇文章。
损失函数关于的一阶、二阶导数分别为:
,由于
,故
故当时,损失函数取得极小值。
则,
其中
2.2 目标函数
针对样本构造目标函数,在第轮时,
在第轮迭代时,
已知,
为常数,要使得目标函数最小,仅需要上式中第2、3项的和最小即可。因此,可将目标函数改造成:
2.3 添加正则项
在第棵树中,第
个叶子节点对应的样本序号的集合
,在
时,
。
利用树的复杂度定义正则项,在第轮迭代时,
,其中
表示第
棵树叶子节点的个数,
表示第
棵树第
个叶子节点的取值(权重);
为设定的参数,且均大于0。
考虑到模型的泛化能力,在目标函数中增加正则项,则
将正则项代入目标函数:
则
记,则
2.4 目标函数最优解
从目标函数的表达式可以看出,在第个叶子节点时的表达式是关于
的一元二次函数,在
时目标函数取得极值。
此时,
3 树的生成
XGBoost树的节点分裂,支持贪心算法和近似算法,这里介绍贪心算法。
3.1 节点分裂
假设叶子节点继续分裂分成左右()两个叶子节点。分裂前叶子节点的个数
为1,分裂后变为2。在第
棵树中,分裂后的
分别记为
,分裂后的
分别记为
。
则可计算分裂前后的目标函数增益:
对于所有可能的分裂,计算上述增益,以增益最大的分裂作为本次的节点分裂。
对于分裂后的叶子节点,继续按照上述贪心算法进行分裂,直至无法分裂或满足停止条件(如增益小于指定值、叶子节点的样本数量限制、树的深度达到指定值等),生成本轮决策树。
3.2 样本取值
在上述生成树的叶子节点中,在第个叶子节点的取值
4 XGBoost回归算法过程
4.1 输入输出
1)输入
训练样本集:,其中
2)输出
最终决策树,并可将其转化为正样本事件发生概率
,以及据此进行样本分类。
4.2 模型初始化
设定。
假设初始化的弱学习器,代价函数
,
则。
当损失函数是上述对数损失函数时,
其推导过程见《GBDT之二分类算法》。
模型的初始化会影响迭代效率。
4.3 进行迭代
对于轮迭代:
1)计算负梯度
在时,其负梯度为
对于第个样本,其负梯度
2)利用负梯度生成回归树
利用负梯度构建新的数据集。
计算,计算
。
按照前述“树的生成”中的方法,生成本轮决策树。
叶子节点的区域为,其取值
。
3)更新强学习器
在不满足停止条件时,继续迭代。
在模型实现过程中,一般会增加一个学习率。
4) 得到最终学习器
在第轮迭代时:当目标函数小于指定值或满足其它设定的停止条件(如迭代次数、分类器在训练集或测试集上的性能等)时,迭代停止。
5 算法代码实现
import pandas as pd
import numpy as np
from xgboost import XGBClassifier
from sklearn.datasets import load_iris
#选择sklearn中的数据集
from sklearn.datasets import load_breast_cancer
data = datasets.load_breast_cancer()
X,y = data.data,data.target
#选择默认参数训练模型
xgb = XGBClassifier()
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, ...)
#模型预测
xgb.predict(X[100:110])
array([0, 1, 1, 1, 1, 0, 1, 1, 0, 1])
6 算法说明
XGBoost二分类算法与XGBoost回归算法的最大区别在于损失函数。对于回归算法,损失函数一般选择平方损失函数;对于二分类算法,损失函数一般选择对数损失函数。