赞
踩
XGBoost,eXtreme Gradient Boosting,全名叫极端梯度提升,应用机器学习领域一个强有力的工具,其基本思想为:一棵树一棵树逐渐地往模型里面加,每加一棵CRAT决策树时,要使得整体的效果(目标函数有所下降)有所提升。使用多棵决策树(多个单一的弱分类器)构成组合分类器,并且给每个叶子节点赋与一定的权值。
CART算法是由Breiman等人首先提出,它包括分类树和回归树两种;两者的不同之处是,分类树的样本输出(即响应值)是类的形式;而回归树的样本输出是数值的形式,这时没法用信息增益、信息增益率、基尼系数来判定树的节点分裂了,我们会采用新的方式:预测误差,常用的有均方误差、对数误差等。节点的确定有时用节点内样本均值,有时是最优化算出来的,比如Xgboost。
目前集成学习方法大致可分为两大类:
模型由k棵CART树组成,表示为
这里的K就是树的棵数,F表示所有可能的CART树,f表示一棵具体的CART树
等式右边第一部分是损失函数,第二部分是正则项,这里的正则化项由K棵树的正则化项相加而来
训练目的:最小化目标函数
如果K棵树的结构都已经确定,那么整个模型剩下的就是所有K棵树的叶子节点的值,模型的正则化项也可以设为各个叶子节点的值的平方和。此时,整个目标函数其实就是一个K棵树的所有叶子节点的值的函数,我们就可以使用梯度下降或者随机梯度下降来优化目标函数。
分步骤优化目标函数,首先优化第一棵树,完了之后再优化第二棵树,直至优化完K棵树。
假设在第t步时,我们添加了一棵最优的CART树f_t
此时目标函数表示为
其中constant为前t-1棵树的复杂度。
如果我们选择的损失函数为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树作另一番定义:
定义解释如下:一棵树有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定义了
γ
γ
γ和
λ
λ
λ,可以自定义值,
γ
γ
γ越大,对较多叶子节点的树的惩罚越大,即表示希望获得结构简单的树。
λ
λ
λ越大也是越希望获得结构简单的树。
对一般的损失函数,泰勒展开后忽略告诫无穷小,将正则化项带入目标函数可得:
其中
I
j
I_j
Ij代表一个集合,集合中每个值代表一个训练样本的序号,整个集合就是被第t棵CART树分到了第j个叶子节点上的训练样本,令
得
容易求出各个叶子节点的最佳值以及此时目标函数的值
o
b
j
∗
obj*
obj∗表示了这棵树的结构有多好,值越小,代表这样结构越好!也就是说,它是衡量第t棵CART树的结构好坏的标准。但是这个值仅仅是用来衡量结构的好坏的,与叶子节点的值可是无关的。
逐步学习出最佳的树结构,找出各个特征的切分点,衡量切分好坏的标准定义如下
即:单节点的
o
b
j
∗
obj*
obj∗减去切分后的两个节点的树
o
b
j
∗
obj*
obj∗,Gain的值越大越值得切分;Gain的左半部分如果小于右侧的
γ
γ
γ,则Gain就是负的,表明切分后
o
b
j
obj
obj反而变大了。
γ
γ
γ在这里实际上是一个临界值,它的值越大,表示我们对切分后obj下降幅度要求越严。这个值也是可以在xgboost中设定的。如果切分,对切分出来的两个节点,递归地调用这个切分过程,我们就能获得一个相对较好的树结构。同时,xgboost在切分的时候就已经考虑了树的复杂度,就是那个
γ
γ
γ参数。所以,它不需要进行单独的剪枝操作。
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)
参数 | 含义 |
---|---|
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) | 其他参数,参数的完整文档 |
# 导入库 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))
(1797, 64) #数据总共1797条,每条64个变量
(1797,) #目标值个数对应数据条数
准确率: 95.37%
简单来说: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(), ...
参数 | 含义 |
---|---|
params | xgboost任务任务的参数设置 |
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))
num | train-mlogloss-mean | train-mlogloss-std | test-mlogloss-mean | test-mlogloss-std |
---|---|---|---|---|
0 | 1.937568 | 0.002123 | 1.970317 | 0.006346 |
1 | 1.680479 | 0.003020 | 1.740304 | 0.005007 |
2 | 1.480579 | 0.003179 | 1.560921 | 0.006292 |
3 | 1.319124 | 0.003846 | 1.414036 | 0.008654 |
4 | 1.182935 | 0.004431 | 1.290541 | 0.009105 |
… | … | … | … | … |
845 | 0.005534 | 0.000030 | 0.120127 | 0.026743 |
846 | 0.005534 | 0.000030 | 0.120094 | 0.026715 |
847 | 0.005534 | 0.000030 | 0.120094 | 0.026701 |
848 | 0.005533 | 0.000030 | 0.120079 | 0.026694 |
849 | 0.005533 | 0.000030 | 0.120030 | 0.026675 |
850 rows × 4 columns
准确率: 95.74%
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。