1. XGBoost

1.1 原理

XGBoost(Extreme Gradient Boosting)通过串行的方式迭代训练多个相互依赖的决策树回归模型,最后综合多个简单模型共同作用产生输出,在GBDT作出全面优化改进,其中主要改进思想:

(1)GBDT中将简单模型限定为只能使用决策树回归模型;而XGBoost支持使用其他的简单模型(一般多采用决策树回归模型),如线性回归

(2)GBDT未考虑正则项,在算法优化方面使用负梯度(一阶泰勒)拟合残差;而XGBoost为实现精确度与复杂度之间的平衡在损失函数部分加入正则项,在算法优化方面使用二阶负梯度(二阶泰勒)拟合带正则项损失函数的残差,因此XGBoost可使用任意二阶可导的损失函数

(3)GBDT通过决策树回归模型拟合残差得出叶子节点后求解最佳拟合值;而XGBoost合并决策树模型叶子节点和最佳拟合值的求解,并且考虑结构复杂度引入了全新的决策分支准则:结构分数增益

(4)使用估计贪婪算法,平行学习等方法引入并行处理优化模型运行效率,使用感知缓存访问技术与核外计算技术等提升硬件上的运算性能引入Droupout技术,为模型建立过程增加更多的随机性增加对缺失特征值样本的自动学习

1.1.1 算法解析

假设给定一个大小为 n n n的数据集:
D = { ( x 1 , y 1 ) , ( x 2 , y 2 ) , . . . . . , ( x n , y n ) } \boldsymbol{D} = \{ (\pmb{x_1},y_1), (\pmb{x_2}, y_2),.....,(\pmb{x_n}, y_n) \} D={(x1x1x1,y1),(x2x2x2,y2),.....,(xnxnxn,yn)}

XGBoost的思想与GBDT类似,通过拟合残差得到第t次模型 h t ( x ) h_t(\pmb x) ht(xxx)使得第t次XGBoost模型损失函数 L ( y , f t − 1 ( x ) + h t ( x ) ) L(y,f_{t - 1}(\pmb x) + h_t(\pmb x)) L(y,ft1(xxx)+ht(xxx))最小,再此基础上加入正则项如下:
∑ i = 1 n L ( y i , f t − 1 ( x i ) + h t ( x i ) ) + γ J + λ 2 ∑ j = 1 J w t j 2 + α ∑ j = 1 J ∣ w t j ∣ (1) \sum_{i=1}^nL(y_i,f_{t - 1}(\pmb x_i) + h_t(\pmb x_i))+\gamma J + \frac{\lambda}{2}\sum_{j=1}^Jw_{tj}^{2} + \alpha \sum_{j=1}^J|w_{tj}|\tag{1} i=1nL(yi,ft1(xxxi)+ht(xxxi))+γJ+2λj=1Jwtj2+αj=1Jwtj(1)

其中 L L L代表任意二阶可导的损失函数, J J J为第t次模型叶子节点的个数, w t j w_{tj} wtj和GBDT中 c t ( j ) c_t^{(j)} ct(j)意义相同代表叶子节点的回归值, γ , λ , α \gamma, \lambda, \alpha γ,λ,α代表正则化惩罚系数

对式(1)进行二阶泰勒展开(为方便计算,假设 α \alpha α取0):
∑ i = 1 n L ( y i , f t − 1 ( x i ) + h t ( x i ) ) + γ J + λ 2 ∑ j = 1 J w t j 2 = ∑ i = 1 n ( L ( y i , f t − 1 ( x i ) ) + ∂ L ( y i , f t − 1 ( x i ) ) ∂ f t − 1 ( x i ) h t ( x i ) + 1 2 ∂ 2 L ( y i , f t − 1 ( x i ) ) ∂ 2 f t − 1 ( x i ) h t 2 ( x i ) ) + γ J + λ 2 ∑ j = 1 J w t j 2 (2) \begin{aligned} & \quad \sum_{i=1}^nL(y_i,f_{t - 1}(\pmb x_i) + h_t(\pmb x_i))+\gamma J + \frac{\lambda} {2}\sum_{j=1}^Jw_{tj}^{2} \\ & =\sum_{i=1}^n\big(L(y_i,f_{t - 1}(\pmb x_i)) + \frac{\partial L(y_i, f_{t - 1}(\pmb x_i))}{\partial f_{t-1}(\pmb x_i)}h_t(\pmb x_i) + \frac {1}{2}\frac{\partial ^ 2L(y_i, f_{t - 1}(\pmb x_i))}{\partial ^2 f_{t-1}(\pmb x_i)}h_t^2(\pmb x_i) \big)+\gamma J + \frac{\lambda}{2}\sum_{j=1}^Jw_{tj}^{2} \tag{2} \end{aligned} i=1nL(yi,ft1(xxxi)+ht(xxxi))+γJ+2λj=1Jwtj2=i=1n(L(yi,ft1(xxxi))+ft1(xxxi)L(yi,ft1(xxxi))ht(xxxi)+212ft1(xxxi)2L(yi,ft1(xxxi))ht2(xxxi))+γJ+2λj=1Jwtj2(2)
令:
g t i = ∂ L ( y i , f t − 1 ( x i ) ) ∂ f t − 1 ( x i ) , h t i = ∂ 2 L ( y i , f t − 1 ( x i ) ) ∂ 2 f t − 1 ( x i ) g_{ti}= \frac{\partial L(y_i, f_{t - 1}(\pmb x_i))}{\partial f_{t-1}(\pmb x_i)},\quad h_{ti}=\frac{\partial ^ 2L(y_i, f_{t - 1}(\pmb x_i))}{\partial ^2 f_{t-1}(\pmb x_i)} gti=ft1(xxxi)L(yi,ft1(xxxi)),hti=2ft1(xxxi)2L(yi,ft1(xxxi))

式(2)为:
∑ i = 1 n ( L ( y i , f t − 1 ( x i ) ) + g t i h t ( x i ) + 1 2 h t i h t 2 ( x i ) ) + γ J + λ 2 ∑ j = 1 J w t j 2 (3) \sum_{i=1}^n\big(L(y_i,f_{t - 1}(\pmb x_i)) + g_{ti}h_t(\pmb x_i) +\frac{1}{2}h_{ti}h_t^2(\pmb x_i) \big)+\gamma J + \frac{\lambda}{2}\sum_{j=1}^Jw_{tj}^{2} \tag{3} i=1n(L(yi,ft1(xxxi))+gtiht(xxxi)+21htiht2(xxxi))+γJ+2λj=1Jwtj2(3)

考虑到 L ( y i , f t − 1 ( x i ) ) L(y_i,f_{t-1}(\pmb x_i)) L(yi,ft1(xxxi))为常数,对最小化损失函数无影响,同时对于决策树回归模型 h t ( x i ) h_t(\pmb x_i) ht(xxxi)取决于最终叶子节点的回归值 w t j w_{tj} wtj,则式(3)可简化为:
∑ j = 1 J ( ∑ x i ∈ R t j g t i w t j + ∑ x i ∈ R t j 1 2 h t i w t j 2 ) + γ J + λ 2 ∑ j = 1 J w t j 2 \sum_{j=1}^J\big(\sum_{x_i \in R_{tj}}g_{ti}w_{tj} +\sum_{x_i \in R_{tj}}\frac{1}{2}h_{ti}w^2_{tj}\big)+\gamma J + \frac{\lambda}{2}\sum_{j=1}^Jw_{tj}^{2} j=1J(xiRtjgtiwtj+xiRtj21htiwtj2)+γJ+2λj=1Jwtj2

令:
G t j = ∑ x ∈ R t j g t i , H t j = ∑ x ∈ R t j h t i G_{tj}=\sum_{x \in R_{tj}}g_{ti}, \quad H_{tj}=\sum_{x \in R_{tj}}h_{ti} Gtj=xRtjgti,Htj=xRtjhti

则最终的损失函数表达式为:
∑ j = 1 J ( G t j w t j + 1 2 ( H t j + λ ) w t j 2 ) + γ J (4) \sum_{j=1}^J\big(G_{tj}w_{tj} +\frac{1}{2} (H_{tj}+\lambda)w^2_{tj}\big)+\gamma J \tag{4} j=1J(Gtjwtj+21(Htj+λ)wtj2)+γJ(4)

为求解 w t j w_{tj} wtj对最终损失函数(4)关于 w t j w_{tj} wtj求导令其为0,得:
w t j = − G t j H t j + λ w_{tj} = -\frac{G_{tj}}{H_{tj}+\lambda} wtj=Htj+λGtj
将其带入损失函数,则原损失函数表达式变为:
∑ j = 1 J − 1 2 G t j 2 H t j + λ + γ J \sum_{j=1}^J-\frac {1} {2}\frac{G_{tj}^2}{H_{tj}+\lambda}+\gamma J j=1J21Htj+λGtj2+γJ
假设决策树为二叉树模型,为了在决策树回归模型生成过程中最大程度的减小损失函数, G L , H L , G R , H R G_L,H_L,G_R,H_R GL,HL,GR,HR为左右子树的一阶及二阶导数和,则期望最大化分裂左右子树前后的损失函数差:
max ⁡ ( − 1 2 ( G L + G R ) 2 H L + H R + λ + γ J − ( − 1 2 G L 2 H L + λ − 1 2 G R 2 H R + λ + γ ( J + 1 ) ) ) = max ⁡ ( 1 2 G L 2 H L + λ + 1 2 G R 2 H R + λ − 1 2 ( G L + G R ) 2 H L + H R + λ − γ ) \begin{aligned} & \quad \max \Big(-\frac {1}{2}\frac{(G_L+G_R)^2}{H_L+H_R+\lambda} +\gamma J - (-\frac {1}{2}\frac{G_L^2}{H_L+\lambda}-\frac {1}{2}\frac{G_R^2}{H_R+\lambda}+\gamma(J+1))\Big) \\ &=\max \Big( \frac {1}{2}\frac{G_L^2}{H_L+\lambda}+\frac {1}{2}\frac{G_R^2}{H_R+\lambda}-\frac {1}{2}\frac{(G_L+G_R)^2}{H_L+H_R+\lambda} -\gamma\Big) \\ \end{aligned} max(21HL+HR+λ(GL+GR)2+γJ(21HL+λGL221HR+λGR2+γ(J+1)))=max(21HL+λGL2+21HR+λGR221HL+HR+λ(GL+GR)2γ)

因此引入全新的决策分支准则,最大化结构分数增益:
G i a n = 左 节 点 结 构 分 数 + 右 节 点 结 构 分 数 − 父 节 点 结 构 分 数 Gian=左节点结构分数+右节点结构分数-父节点结构分数 Gian=+
其中结构分数定义为:
G t j 2 H t j + λ \frac{G_{tj}^2}{H_{tj}+\lambda} Htj+λGtj2

1.1.2 算法流程

(1)计算输入数据基于 f t − 1 ( x i ) f_{t-1}(\pmb x_i) ft1(xxxi)的一阶导数之和 G t G_t Gt及二阶导数之和 H t H_t Ht
G t = ∑ i = 1 n g t i , H t = ∑ i = 1 n h t i G_t = \sum_{i=1}^ng_{ti}, \quad H_t =\sum_{i=1}^nh_{ti} Gt=i=1ngti,Ht=i=1nhti

(2)计算各特征结构分数,将所有的样本都放在右子树,然后从小到大迭代依次放入左子树,根据最大化结构分数增益划分特征和特征值
G a i n = G L 2 H L + λ + G R 2 H R + λ − ( G L + G R ) 2 H L + H R + λ Gain=\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} Gain=HL+λGL2+HR+λGR2HL+HR+λ(GL+GR)2

(3)当结构分数增益为0时,当前t轮决策树模型建立完成,计算所有叶子区域 w t j w_{tj} wtj
w t j = − G t j H t j + λ w_{tj} = -\frac{G_{tj}}{H_{tj}+\lambda} wtj=Htj+λGtj

(4)根据 w t j w_{tj} wtj,更新第t次决策树回归模型:
f t ( x ) = f t − 1 ( x ) + h t ( x ) f_t(\pmb x) = f_{t - 1}(\pmb x) + h_t(\pmb x) ft(xxx)=ft1(xxx)+ht(xxx)

(5)当达到模型训练的最大迭代次数,则组合得到最终的XGBoost模型:
f ( x ) = ∑ t = 1 m f t ( x ) f(\pmb x)=\sum_{t=1}^{m} f_{t}(\pmb x) f(xxx)=t=1mft(xxx)
其中 m m m为模型训练迭代次数

1.2 XGBoost库实现

sklearn库没有封装XGBoost类,使用XGBoost需要手动安装,可使用pip install xgboost直接安装

XGboost库包含了多种接口,这里仅介绍有关sklearn接口,即Scikit-Learn API
参考官方文档:点击查看

XGBoost回归可通过xgboost库中的XGBRegressor类实现
在这里插入图片描述
有关参数

  • n_estimators:迭代更新次数,即回归模型数量
  • max_depth:决策树的最大深度
  • max_leaves:最大的叶子节点数量
  • max_bin:基于直方图算法中的每个特征最大容器数量
  • grow_policy:决策树建立的准则,0-按距离最近的节点进行拆分,即按深度方向增长;1-按损失变化最大的节点进行拆分
  • learning_rate:每次迭代过程中更新模型的附加权重(正则化方法)
  • verbosity:控制输出的详细程度
  • objective:指定相关损失函数的定义
  • booster:选择迭代过程中的模型,gbtree-决策树模型(CART),gblinear-线性模型,dart-带droupout的决策树模型
  • tree_method:建立树模型时使用的算法
  • n_jobs:计算过程当中的并行数量
  • gamma:正则化惩罚系数,γ
  • min_child_weight:叶子节点的权重总和中需要的最小加权分数
  • max_delta_step:叶子节点的最大权重
  • subsample:针对样本的下采样比例
  • sample_method:选择采样方法
  • colsample_bytree:每个树模型所用特征的下采样比例
  • colsample_bylevel:树模型每层所用特征的下采样比例
  • colsample_bynode:树模型分裂时所用特征的下采样比例
  • reg_alpha:L1正则化系数
  • reg_lambda:L2正则化系数
  • scale_pose_weight:平衡样本权重
  • base_score:每个样本的初始预测分数(全局偏差)
  • random_state:控制迭代更新过程中的随机性
  • missing:当数据缺失时填补的缺失值
  • num_parallel_tree:用于随机森林的Boosting操作
  • monotone_constraints:变量单调性约束
  • interaction_constraints:变量允许交互约束
  • importance_type:选择计算特征重要程度的类型
  • gpu_id:设备号
  • validate_parameters:是否对未知参数发出警告
  • predictor:选择预测器类型(gpu,cpu)
  • enable_categorical:对分类数据类型的支持
  • max_cat_to_onehot:对分割分类数据类型是否使用onehot编码的阈值
  • eval_metric:评价模型最终结果的准则
  • early_stopping_rounds:控制提前停止迭代更新
  • callbacks:每次迭代结束时调用的函数包
  • kwargs:XGboost对象的keyword参数字典

有关属性

  • best_iteration:迭代过程中最好模型的迭代次数
  • best_score:迭代过程中最好模型的得分
  • coef_:回归系数,仅使用线性模型
  • intercept_:常数项,仅使用线性模型
  • feature_importances_:基于特征计算类型的各特征重要程度
  • n_features_in_:特征的个数
  • feature_names_in_:特征的名称,仅当输入特征有(字符)名称时可用

有关方法

  • apply:获取XGboost中各决策树模型上每个叶子节点对应输入数据的索引
  • evals_result:返回模型评估结果
  • fit:生成XGBoost模型
  • get_booster:获取迭代过程中的模型
  • get_num_boosting_rounds:获取迭代更新次数
  • get_params:获取模型参数
  • get_xgb_params:获取XGBoost模型特定参数
  • load_model:加载模型
  • predict:预测回归值
  • save_model:保存模型
  • score:获取模型预测的确定系数
  • set_params:设置对应模型参数

使用案例

>>> import numpy as np
>>> from xgboost import XGBRegressor

>>> reg = XGBRegressor() #实例化XGBoost回归模型对象
>>> X = np.array([[1, 1], [3, 2], [4, 7], [2, 5]]) #数据
>>> y = np.array([3, 6, 11, 8]) #类别
>>> reg.fit(X, y) #拟合求解
>>> reg.n_features_in_
2
>>> reg.feature_importances_
[0.69..., 0.308...]
>>> reg.get_params()
{'objective': 'reg:squarederror', '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, 
'predictor': 'auto', 'random_state': 0, 'reg_alpha': 0, 'reg_lambda': 1, 'sampling_method': 'uniform', 
'scale_pos_weight': 1, 'subsample': 1, 'tree_method': 'exact', 'validate_parameters': 1, 'verbosity': None}
>>> reg.predict([[1, 0]])
[3.00...]
>>> reg.score(X, y)
0.99...

更多推荐