机器学习算法[9]--集成方法之XGBoost原理详解及XGBoost库实现
对机器学习算法-XGBoost进行总结,包括原理详解和XGBoost库的实现
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,ft−1(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=1∑nL(yi,ft−1(xxxi)+ht(xxxi))+γJ+2λj=1∑Jwtj2+αj=1∑J∣wtj∣(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=1∑nL(yi,ft−1(xxxi)+ht(xxxi))+γJ+2λj=1∑Jwtj2=i=1∑n(L(yi,ft−1(xxxi))+∂ft−1(xxxi)∂L(yi,ft−1(xxxi))ht(xxxi)+21∂2ft−1(xxxi)∂2L(yi,ft−1(xxxi))ht2(xxxi))+γJ+2λj=1∑Jwtj2(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=∂ft−1(xxxi)∂L(yi,ft−1(xxxi)),hti=∂2ft−1(xxxi)∂2L(yi,ft−1(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=1∑n(L(yi,ft−1(xxxi))+gtiht(xxxi)+21htiht2(xxxi))+γJ+2λj=1∑Jwtj2(3)
考虑到
L
(
y
i
,
f
t
−
1
(
x
i
)
)
L(y_i,f_{t-1}(\pmb x_i))
L(yi,ft−1(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=1∑J(xi∈Rtj∑gtiwtj+xi∈Rtj∑21htiwtj2)+γJ+2λj=1∑Jwtj2
令:
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=x∈Rtj∑gti,Htj=x∈Rtj∑hti
则最终的损失函数表达式为:
∑
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=1∑J(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=1∑J−21Htj+λ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+λGL2−21HR+λGR2+γ(J+1)))=max(21HL+λGL2+21HR+λGR2−21HL+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)
ft−1(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=1∑ngti,Ht=i=1∑nhti
(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+λGR2−HL+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)=ft−1(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=1∑mft(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...
更多推荐
所有评论(0)