XGBoost

背景

在GBDT的基础上,有了XGB。XGB"(eXtreme Gradient Boosting极端梯度提升)本质还是 一个GBDT (Gradien tBoosting Decision Tree),XGB (Xtreme Gradient Boosting) 的本质还是一个GBDT, 但是在速度和效率上都发挥到了极致,XGB和GBDT比较大的不同就是目标函数的定义。

原理

XGB使用泰勒展开来近似目标函数。
二阶泰勒展开公式:
在这里插入图片描述
最小化下列损失函数,
在这里插入图片描述
γ \gamma γ λ \lambda λ是预先设定的超参数, T T T是叶子节点的数量, w w w是叶子结点的权重。
在这里插入图片描述
化简后:
在这里插入图片描述
g i = ∂ y ^ ( t − 1 ) l ( y i , y ^ ( t − 1 ) ) g_{i}=\partial_{\hat{y}^{(t-1)}} l\left(y_{i}, \hat{y}^{(t-1)}\right) gi=y^(t1)l(yi,y^(t1)), 表示损失对 y ^ ( t − 1 ) \hat{y}^{(t-1)} y^(t1)求导。
h i = ∂ y ^ ( t − 1 ) 2 l ( y i , y ^ ( t − 1 ) ) h_{i}=\partial_{\hat{y}(t-1)}^{2} l\left(y_{i}, \hat{y}^{(t-1)}\right) hi=y^(t1)2l(yi,y^(t1)), 表示损失对 y ^ ( t − 1 ) \hat{y}^{(t-1)} y^(t1)求导。
可以得到:
g i = ∂ y ^ ( t − 1 ) l ( y i , y ^ ( t − 1 ) ) = ∂ y ^ ( t − 1 ) ( y i − y ^ ( t − 1 ) ) 2 = − 2 y i + 2 y ^ ( t − 1 ) \begin{matrix}{} {{g_i} = {\partial _{{{\hat y}^{(t - 1)}}}}l\left( {{y_i},{{\hat y}^{(t - 1)}}} \right)}\\ {\kern 10pt} = {\partial _{{{\hat y}^{(t - 1)}}}}{({y_i} - {{\hat y}^{(t - 1)}})^2}\\ {\kern -8pt} = {\rm{ - 2}}{y_i} + 2{{\hat y}^{(t - 1)}} \end{matrix} gi=y^(t1)l(yi,y^(t1))=y^(t1)(yiy^(t1))2=2yi+2y^(t1)
h i = ∂ y ^ ( t − 1 ) 2 l ( y i , y ^ ( t − 1 ) ) = 2 {h_i} = \partial _{\hat y(t - 1)}^2l\left( {{y_i},{{\hat y}^{(t - 1)}}} \right) = 2 hi=y^(t1)2l(yi,y^(t1))=2
g i g_i gi h i h_i hi的结果带入公式展开,可以得到和原公式展开相同的结果。
为啥公式的第一行的 f t ( x i ) f_t(\bf{x_i}) ft(xi)消失了,因为这个得到的结果也是对应叶子节点的权重。注解:最后一步的转化思路是从在这个树中,每个样本落在哪个节点上转为了每个节点 上有哪些样本。

在这里插入图片描述
这个是对 w j w_j wj做了求导,将最外层的求和符号去掉,然后就可以得到最后的结果。
在这里插入图片描述
这个是将优化后的 w w w带进去,然后得到的结果。
3. XGBoost在什么地方做的剪枝,怎么做的?

(1) 当引入的分割带来的增益小于一个阈值时,我们就可以减掉这个分割(参考决策树的分割)。
在这里插入图片描述

(2)在模型中加入正则

  1. XGBoost特征重要性实现原理:
    每个特征对应一个模型参数 w i w_i wi,这个参数越大说明这个特征越重要。
    gain :该特征在其出现过的所有树中产生的平均增益(我自己的理解就是目标函数减少值总和的平均值,这里也可以使用增益之和)。

每一个特征的分裂都会产生好多树,那么这些树是会带来增益的。

代码训练

#训练集和验证集数据划分
import xgboost as xgb
#train_x是DataFrame数据,选择对应的列就行
nums = int(train_x.shape[0] * 0.80)

# 训练集验证集划分
trn_x, trn_y, val_x, val_y = train_x[:nums], train_y[:nums], train_x[nums:], train_y[nums:]

#训练集
train_matrix = xgb.DMatrix(trn_x, label=trn_y.values, missing=np.nan)
valid_matrix = xgb.DMatrix(val_x, label=val_y.values, missing=np.nan)
# test_matrix = clf.DMatrix(test_x, label=val_y, missing=np.nan)
test_matrix = xgb.DMatrix(test_x, missing=np.nan)

params = {'booster': 'gbtree',
          'eval_metric': 'mae',
          'min_child_weight': 5,
          'max_depth': 8,
          'subsample': 0.5,
          'colsample_bytree': 0.5,
          'eta': 0.0015,
          'seed': 2020,
          'nthread': 4,
          'silent': True,
          }

watchlist = [(train_matrix, 'train'), (valid_matrix, 'eval')]

model = xgb.train(params, train_matrix, num_boost_round=50000, evals=watchlist, verbose_eval=500,
                  early_stopping_rounds=1000)
#划分的验证集数据
val_pred = model.predict(valid_matrix, ntree_limit=model.best_ntree_limit).reshape(-1, 1)
#需要测试的数据
test_pred = model.predict(test_matrix, ntree_limit=model.best_ntree_limit).reshape(-1, 1)

问题

XGBoost为什么要用二阶泰勒展开
  1. 二阶信息本身就能让梯度收敛更快更准确。这一点在优化算法里的牛顿法里已经证实了。可以简单认为一阶导指引梯度方向,二阶导指引梯度方向如何变化。
  2. 不同损失的求导是不一样的,为了可以统一损失函数求导的形式,所以用二阶泰勒展开。

参考资料

https://zhuanlan.zhihu.com/p/290964953?utm_source=ZHShareTargetIDMore (这个博客里面树模型比较详细)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值