当前位置:   article > 正文

Xgboost算法介绍和XGBClassifier方法的代码实现_xgboost.xgbclassifier

xgboost.xgbclassifier

XGBoost

XGBoost,eXtreme Gradient Boosting,全名叫极端梯度提升,应用机器学习领域一个强有力的工具,其基本思想为:一棵树一棵树逐渐地往模型里面加,每加一棵CRAT决策树时,要使得整体的效果(目标函数有所下降)有所提升。使用多棵决策树(多个单一的弱分类器)构成组合分类器,并且给每个叶子节点赋与一定的权值。

CART 回归树

CART算法是由Breiman等人首先提出,它包括分类树和回归树两种;两者的不同之处是,分类树的样本输出(即响应值)是类的形式;而回归树的样本输出是数值的形式,这时没法用信息增益、信息增益率、基尼系数来判定树的节点分裂了,我们会采用新的方式:预测误差,常用的有均方误差、对数误差等。节点的确定有时用节点内样本均值,有时是最优化算出来的,比如Xgboost。

Boosting 集成学习

目前集成学习方法大致可分为两大类:

  • 个体学习器之间存在强依赖关系、必须串行生成的序列化方法,这种方法的代表是Boosting,由多个相关联的树联合决策;(相关联的意思是:下一棵决策树输入样本会与前面决策树的训练和预测相关)
  • 个体学习器间不存在强依赖关系、可同时生成的并行化方法,它的代表是BaggingRandomForest

简单原理介绍

模型

模型由k棵CART树组成,表示为
模型
这里的K就是树的棵数,F表示所有可能的CART树,f表示一棵具体的CART树

目标函数

目标函数
等式右边第一部分是损失函数,第二部分是正则项,这里的正则化项由K棵树的正则化项相加而来

训练xgboost

训练目的:最小化目标函数
如果K棵树的结构都已经确定,那么整个模型剩下的就是所有K棵树的叶子节点的值,模型的正则化项也可以设为各个叶子节点的值的平方和。此时,整个目标函数其实就是一个K棵树的所有叶子节点的值的函数,我们就可以使用梯度下降或者随机梯度下降来优化目标函数。

加法训练

分步骤优化目标函数,首先优化第一棵树,完了之后再优化第二棵树,直至优化完K棵树。
在这里插入图片描述
假设在第t步时,我们添加了一棵最优的CART树f_t
此时目标函数表示为
目标函数最优
其中constant为前t-1棵树的复杂度。
如果我们选择的损失函数为MSE,则
MSE下的目标函数
这个式子含有 f t ( x i ) f_t(x_i) ft(xi)的一次和二次项,对最优结果的求解很方便,对一般的损失函数,我们只需将其作泰勒二阶展开
泰勒展开
其中
展开式参数
g i g_i gi h i h_i hi可分别理解为前t-1棵树组成的模型对第i个训练样本预测的损失函数的一阶导和二阶导。
同时, g i g_i gi h i h_i hi可以进行并行计算是xgboost为什么这么快的主要原因。(因为 g i g_i gi h i h_i hi不依赖于损失函数的形式,只要损失函数二次可微就行)

模型正则化项

那么模型的正则化项Ω(ft)是如何来衡量的?首先对CART树作另一番定义:
CART定义
定义解释如下:一棵树有T个叶子节点,这T个叶子节点的值组成了一个T维向量 w w w q ( x ) q(x) q(x)是一个映射,用来将样本映射成1到T的某个值,也就是把它分到某个叶子节点, q ( x ) q(x) q(x)其实就代表了CART树的结构。 w q ( x ) w_q(x) wq(x)就是这棵树对样本x的预测值了。

于是xgboost使用了如下的正则化项
xgboost正则化项
说明:xgboost定义了 γ γ γ λ λ λ,可以自定义值, γ γ γ越大,对较多叶子节点的树的惩罚越大,即表示希望获得结构简单的树。 λ λ λ越大也是越希望获得结构简单的树。

最终结果

对一般的损失函数,泰勒展开后忽略告诫无穷小,将正则化项带入目标函数可得:最终目标函数
其中 I j I_j Ij代表一个集合,集合中每个值代表一个训练样本的序号,整个集合就是被第t棵CART树分到了第j个叶子节点上的训练样本,令

在这里插入图片描述

在这里插入图片描述
容易求出各个叶子节点的最佳值以及此时目标函数的值
在这里插入图片描述
在这里插入图片描述
o b j ∗ obj* obj表示了这棵树的结构有多好,值越小,代表这样结构越好!也就是说,它是衡量第t棵CART树的结构好坏的标准。但是这个值仅仅是用来衡量结构的好坏的,与叶子节点的值可是无关的。

找出最优的树结构

逐步学习出最佳的树结构,找出各个特征的切分点,衡量切分好坏的标准定义如下
Gain
即:单节点的 o b j ∗ obj* obj减去切分后的两个节点的树 o b j ∗ obj* obj,Gain的值越大越值得切分;Gain的左半部分如果小于右侧的 γ γ γ,则Gain就是负的,表明切分后 o b j obj obj反而变大了。 γ γ γ在这里实际上是一个临界值,它的值越大,表示我们对切分后obj下降幅度要求越严。这个值也是可以在xgboost中设定的。如果切分,对切分出来的两个节点,递归地调用这个切分过程,我们就能获得一个相对较好的树结构。同时,xgboost在切分的时候就已经考虑了树的复杂度,就是那个 γ γ γ参数。所以,它不需要进行单独的剪枝操作。

XGBClassifier 方法

xgboost.XGBClassifier 方法是用于XGBoost分类的scikit-learn API实现:

xgboost.XGBClassifier(max_depth=3, learning_rate=0.1, n_estimators=100, verbosity=1, objective='binary:logistic',
				booster='gbtree', tree_method='auto',n_jobs=1, gpu_id=-1, gamma=0,min_child_weight=1,
				max_delta_step=0, subsample=1, colsample_bytree=1, colsample_bylevel=1,colsample_bynode=1,
				reg_alpha=0,reg_lambda=1,scale_pos_weight=1,base_score=0.5,random_state=0,missing=None,**kwargs)
  • 1
  • 2
  • 3
  • 4

参数配置

 参数含义
max_depth (int)树最大深度
learning_rate (float)学习率
n_estimators (int)树的个数
verbosity (int)当这个参数的值为1时,输出模型的很多信息,这有助于帮助我们更好的理解模型
objective (string or callable)目标函数(可自定义函数)
booster (string)指定使用的助推器: gbtree, gblinear or dart
tree_method (string)要使用的树方法,默认为自动:XGBoost选择最保守的选项
n_jobs (int)并行线程数
gamma (float)惩罚项系数,指定节点分裂所需的最小损失函数下降值
min_child_weight (int)最小叶子结点权重,值越大,越容易欠拟合;值越小,越容易过拟合
max_delta_step (int)允许树重量估计的最大增量步长
subsample (float)训练每棵树时,使用的数据占全部训练集的比例
colsample_bytree (float)随机选择多少样本特征建立决策树
colsample_bylevel (float)每个级别的列子采样率
colsample_bynode (float)各个拆分列的子采样率
reg_alpha (float )L1正则化系数
reg_lambda (float)L2正则化系数
scale_pos_weight (float)解决样本个数不平衡问题,设置正样本的权重,当正负样本比例为1:10时,值为10
base_score所有实例和全局偏差的初始预测得分
random_state (int)随机种子数(取定可以固定训练结果)
missing (float, optional)数据中需要以缺失值形式显示的值。如果为None,则默认为np.nan
num_parallel_tree (int)用于增强随机森林
importance_type (string)属性的特征重要性类型:“ gain”,“ weight”,“ cover”,“ total_gain”或“ total_cover”
kwargs (dict, optional)其他参数,参数的完整文档

以数据集为例的代码实现

使用到的函数
  • 载入数据:load_digits()
  • 数据拆分:train_test_split()
  • 建立模型:XGBClassifier()
  • 模型训练:fit()
  • 模型预测:predict()
  • 性能度量:accuracy_score()
  • 特征重要性:plot_importance()
实例
# 导入库
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from xgboost import XGBClassifier
from xgboost import plot_importance
 
### 载入数据
digits = datasets.load_digits()
 
### data analysis
print(digits.data.shape)
print(digits.target.shape)
 
### 划分训练集测试集
x_train,x_test,y_train,y_test = train_test_split(digits.data, digits.target, test_size = 0.3,random_state = 33)
### 训练模型
model = XGBClassifier(learning_rate=0.1,
                      n_estimators=100,         # 树的个数--100棵树建立xgboost
                      max_depth=6,               # 树的深度
                      min_child_weight = 1,      # 叶子节点最小权重
                      gamma=0.,                  # 惩罚项中叶子结点个数前的参数
                      subsample=0.8,             # 随机选择80%样本建立决策树
                      colsample_btree=0.8,       # 随机选择80%特征建立决策树
                      objective='multi:softmax', # 指定损失函数
                      scale_pos_weight=1,        # 解决样本个数不平衡的问题
                      random_state=27            # 随机数
                      )
# 拟合
model.fit(x_train, y_train, eval_set = [(x_test,y_test)], eval_metric = "mlogloss", early_stopping_rounds = 10,
          verbose = True)
 
### 特征重要性
fig,ax = plt.subplots(figsize=(15,15))
plot_importance(model, height=0.5, ax=ax, max_num_features=64)
plt.show()
 
### 预测
y_pred = model.predict(x_test)
 
### 模型正确率
accuracy = accuracy_score(y_test,y_pred)
print("准确率: %.2f%%" % (accuracy*100.0))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
准确率
(1797, 64)   #数据总共1797条,每条64个变量
(1797,)      #目标值个数对应数据条数
准确率: 95.37%
  • 1
  • 2
  • 3
特征重要性图

在这里插入图片描述
简单来说:f21变量有最高的特征重要性。

交叉验证

这里使用 xgboost 库自带的函数 xgb.cv,实现方式如下:

xgb.cv(params = list(), data, nrounds, nfold, label = NULL, missing = NA, prediction = FALSE, showsd = TRUE,
	metrics = list(), obj = NULL, feval = NULL, stratified = TRUE, folds = NULL, verbose = TRUE
	print_every_n = 1L, early_stopping_rounds = NULL, maximize = NULL, callbacks = list(), ...
  • 1
  • 2
  • 3
参数配置
 参数含义
 paramsxgboost任务任务的参数设置
 data待训练的数据集(一般是经过处理后的稀疏矩阵)
 nrounds迭代次数
 nfold原始数据集被随机分割成n倍相等大小的子样本。
 label训练样本的标签
metrics在交叉验证中使用的评估度量列表,当它没有被指定时,根据目标函数来选择评估度量。待选项:error(二分类错误率,阈值为0.5)、mae(平均绝对误差)、rmse(均方根误差)、logloss(负对数似然函数值)、auc(曲线下面积,两分类)、merror(多分类错误率) 或 mlogloss(多分类logloss损失函数)
 early_stopping_rounds如果为NULL,则不会触发早期停止功能。 如果设置为整数k,则如果性能在第k轮中不提高,则使用验证集的训练将停止。 设置此参数将调用cb.early.stop回调
 stratified布尔值,指示是否应根据结果标签的值对折叠样本进行分层。
 missing仅在输入是密集矩阵时才使用。 默认情况下,设置为NA,这意味着算法应该将NA值视为“丢失”。 有时,可能会使用0或其他极值来表示缺失值。
 prediction指示是否从每个CV模型返回测试折叠预测的逻辑值。 此参数与cb.cv.predict回调有关。
 showsd布尔值,是否显示交叉验证的标准差
 obj定制目标函数。 用给定的预测和应变返回梯度和二阶梯度
 feval定制的评估功能。 用给定的预测和应变返回列表(metric =’metric-name’,value =’metric-value’)
 folds列表提供了使用预定义的CV折叠列表的可能性(每个元素必须是测试折叠索引的向量)。 当提供折叠时,将忽略nfold和分层参数,因此一般自定义设置的时候不需要这个参数
 verbose布尔值,在这个过程中打印统计信息
 print_every_n当verbose> 0时,打印每个第n次迭代评估消息。 默认值是1,表示打印所有消息。 这个参数被传递给cb.print.evaluation回调函数。
 maximize如果设置了feval和early_stopping_rounds,那么也必须设置此参数。 当它为真时,意味着评价分数越大越好。 该参数被传递给cb.early.stop回调。
使用交叉验证获取最好的参数
import xgboost as xgb

xgb_param = model.get_xgb_params()
xgtrain = xgb.DMatrix(x_train, label=y_train)
cvresult = xgb.cv(xgb_param, xgtrain, num_boost_round=5000, nfold=5, metrics=['mlogloss'], 
     early_stopping_rounds=50, stratified=True, seed=1301)
#交叉验证后最好的树
print('Best number of trees = {}'.format(cvresult.shape[0]))
model.set_params(n_estimators=cvresult.shape[0])#把model的参数设置成最好的树对应的参数
# 下面进行相同方式的结果展现
fig,ax = plt.subplots(figsize=(15,15))
plot_importance(model, height=0.5, ax=ax, max_num_features=64)
plt.show()
 
### 预测
y_pred = model.predict(x_test)
 
### 模型正确率
accuracy = accuracy_score(y_test,y_pred)
print("准确率: %.2f%%" % (accuracy*100.0))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
交叉验证结果
numtrain-mlogloss-meantrain-mlogloss-stdtest-mlogloss-meantest-mlogloss-std
01.9375680.0021231.9703170.006346
11.6804790.0030201.7403040.005007
21.4805790.0031791.5609210.006292
31.3191240.0038461.4140360.008654
41.1829350.0044311.2905410.009105
8450.0055340.0000300.1201270.026743
8460.0055340.0000300.1200940.026715
8470.0055340.0000300.1200940.026701
8480.0055330.0000300.1200790.026694
8490.0055330.0000300.1200300.026675

850 rows × 4 columns

准确率
准确率: 95.74%
  • 1
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/604603
推荐阅读
相关标签
  

闽ICP备14008679号