XGBoost的剪枝参数与模型调参实战
Posted Peer Parker
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了XGBoost的剪枝参数与模型调参实战相关的知识,希望对你有一定的参考价值。
剪枝参数
作为 天生过拟合 的模型, XGBoost 应用的核心之一就是减轻过拟合带来的影响。作为树模型,减轻过拟合的方式主要是靠对决策树 剪枝 来降低模型的复杂度,以求降低方差。在之前的博文中,已经介绍了好几个可以用来防止过拟合的参数,包括上一节提到的复杂度控制![](https://image.cha138.com/20220216/7d7d0bc11e834a9d8b3393e4d6a6f386.jpg)
![](https://image.cha138.com/20220216/ef885d2430d74131b60fb22b8fe15468.jpg)
![](https://image.cha138.com/20220216/eee2758ab2314e6a9aeedd3e1df267c7.jpg)
![](https://image.cha138.com/20220216/4bde445775e54d17aea9bcf502bd1ad0.jpg)
![](https://image.cha138.com/20220216/7d7d0bc11e834a9d8b3393e4d6a6f386.jpg)
![](https://image.cha138.com/20220216/7d7d0bc11e834a9d8b3393e4d6a6f386.jpg)
![](https://image.cha138.com/20220216/7d7d0bc11e834a9d8b3393e4d6a6f386.jpg)
![](https://image.cha138.com/20220216/95f4eac375d04b5fa39dd30a6d3e7c82.jpg)
![](https://image.cha138.com/20220216/7d7d0bc11e834a9d8b3393e4d6a6f386.jpg)
调参策略
通常当我们获得了一个数据集后,我们先使用网格搜索找出比较合适的 n_estimators(num_round) 和 eta 组合,然后使用 gamma 或者max_depth 观察模型处于什么样的状态(过拟合还是欠拟合,处于方差 - 偏差图像的左边还是右边?),最后再决定是否要进行剪枝。通常来说,对于XGB 模型,大多数时候都是需要剪枝的。波士顿房价数据集实战
import datetime
import xgboost as xgb
import matplotlib.pyplot as plt
from time import time
from sklearn.datasets import load_boston
# 加载数据
data = load_boston()
X = data.data
y = data.target
# 读取全数据
dfull = xgb.DMatrix(X,y)
# 参数设置
param1 = 'silent':True
,'obj':'reg:linear'
,"subsample":1
,"max_depth":6
,"eta":0.3
,"gamma":0
,"lambda":1
,"alpha":0
,"colsample_bytree":1
,"colsample_bylevel":1
,"colsample_bynode":1
,"nfold":5
,'verbosity':0
num_round = 200
# 计算模型训练时间
time0 = time()
cvresult1 = xgb.cv(param1, dfull, num_round)
print(datetime.datetime.fromtimestamp(time()-time0).strftime("%M:%S:%f"))
# 绘制迭代过程的均方误差
fig,ax = plt.subplots(1,figsize=(15,10))
ax.grid()
ax.plot(range(1,201),cvresult1.iloc[:,0],c="red",label="train,original")
ax.plot(range(1,201),cvresult1.iloc[:,2],c="orange",label="test,original")
ax.legend(fontsize="xx-large")
plt.show()
# 调参结果1
param2 = 'silent':True
,'obj':'reg:linear'
,"subsample":1
,"max_depth":4
,"eta":0.05
,"gamma":20
,"lambda":3.5
,"alpha":0.2
,"colsample_bytree":0.4
,"colsample_bylevel":0.6
,"colsample_bynode":1
,"nfold":5
,'verbosity':0
# 调参结果2
param3 = 'silent':True
,'obj':'reg:linear'
,"subsample":1
,"max_depth":2
,"eta":0.05
,"gamma":0
,"lambda":1
,"alpha":0
,"colsample_bytree":1
,"colsample_bylevel":0.4
,"colsample_bynode":1
,"nfold":5
,'verbosity':0
# 绘制对比图
fig,ax = plt.subplots(1,figsize=(15,8))
ax.set_ylim(top=5)
ax.grid()
ax.plot(range(1,201),cvresult1.iloc[:,0],c="red",label="train,original")
ax.plot(range(1,201),cvresult1.iloc[:,2],c="orange",label="test,original")
ax.plot(range(1,201),cvresult2.iloc[:,0],c="green",label="train,last")
ax.plot(range(1,201),cvresult2.iloc[:,2],c="blue",label="test,last")
ax.plot(range(1,201),cvresult3.iloc[:,0],c="gray",label="train,this")
ax.plot(range(1,201),cvresult3.iloc[:,2],c="pink",label="test,this")
ax.legend(fontsize="xx-large")
plt.show()
从上图可以看到,XGBoost模型通过剪枝,模型的过拟合被削弱,泛化能力增强,且模型的复杂度降低!!!
调参建议
- 可以使用网格搜索进行调参,但是建议至少先使用xgboost.cv来确认参数的范围,否则很可能花很长的时间做了无用功。并且,在使用网格搜索的时候,最好不要一次性将所有的参数都放入进行搜索,最多一次两三个。有一些互相影响的参数需要放在一起使用,比如学习率eta和树的数量n_estimators(num_round)。
- 调参的时候参数的顺序也会影响调参结果,因此在现实中,我们会优先调整那些对模型影响巨大的参数。在这里,我建议的剪枝上的调参顺序是:n_estimators(num_round)与eta共同调节,gamma或者max_depth,采样和抽样参数(纵向抽样影响更大),最后才是正则化的两个参数。当然,可以根据自己的需求来进行调整。
- 若调参之后测试集上的效果还没有原始设定上的效果好,但交叉验证曲线确实显示测试集和训练集上的模型评估效果是更加接近的,推荐使用调参之后的效果。我们希望增强模型的泛化能力,然而泛化能力的增强并不代表着在新数据集上模型的结果一定优秀,因为未知数据集并非一定符合全数据的分布,在一组未知数据上表现十分优秀,也不一定就能够在其他的未知数据集上表现优秀。因此不必过于纠结在现有的测试集上是否表现优秀。当然了,在现有数据上如果能够实现训练集和测试集都非常优秀,那模型的泛化能力自然也会是很强的。
继续加油,我们一定会成功的!!!
以上是关于XGBoost的剪枝参数与模型调参实战的主要内容,如果未能解决你的问题,请参考以下文章
XGBoost模型调参:GridSearchCV方法网格搜索优化参数
机器学习系列调参GridsearchCV随机森林GBDTLightGBM和XGBoost调参顺序,外加一些加速调参的小技巧(主要介绍坐标下降)