机器学习XGBoost模型调参技巧和代码实现

常规操作,先吹一下XGBoost:

XGBoost的核心思想是不断地添加树,不断地进行特征分裂来生长一棵树,每次添加一个树,其实是学习一个新函数f(x),去拟合上次预测的残差。当我们训练完成得到k棵树,我们要预测一个样本的分数,其实就是根据这个样本的特征,在每棵树中会落到对应的一个叶子节点,每个叶子节点就对应一个分数。最后只需要将每棵树对应的分数加起来就是该样本的预测值。

XGBoost对GBDT进行了一系列优化,比如损失函数进行了二阶泰勒展开、目标函数加入正则项、支持并行和默认缺失值处理等,在可扩展性和训练速度上有了巨大的提升,但其核心思想没有大的变化。

XGBoost官方文档:传送门


目录

 

一、Xgboost的优势

二、Xgboost的参数

 三、Xgboost参数调优实例


一、Xgboost的优势

1、Regularization(正则化)

2、Parallel Processing(并行处理):

3、High Flexibility(高度灵活)

4、Handling Missing Values(处理缺失值)值,并作为参数传递。

5、Tree Pruning(树剪枝)

6、Built-in Cross-Validation(内置的交叉验证)

7、Continue on Existing Model(继续现有模型)

二、Xgboost的参数

Xgboost将工具分成了三大类:

-- General Parameters(通用参数):设置整体功能,宏观函数控制

-- Booster Parameters(提升参数):选择你每一步的booster(tree/regression),booster参数一般可以调控模型的效果和计算代价。我们所说的调参,很这是大程度上都是在调整booster参数。

-- Learning Task Parameters(学习目标参数):指导优化任务的执行,控制训练目标的表现。我们对于问题的划分主要体现在学习目标参数上。比如我们要做分类还是回归,做二分类还是多分类,这都是目标参数所提供的。

1、通用参数

--booster [default=gbtree]
选择每次迭代过程中需要运行的模型,一共有两种选择:
gbtree: tree-based models,采用树的结构来运行数据;
gblinear:基于线性模型;

--silent [default=0]
设置模型是否有logo打印:
0:有打印
1:无打印

--nthread [default to maximum number of threads available if not set]
这个主要用于并行处理的,如果不指定值,工具会自动检测。一般我们设置成-1,使用所有线程。
剩余两个参数是Xgboost自动指定的,无需设置

2、提升参数

虽然有两种类型的booster,但是我们这里只介绍tree。因为tree的性能比线性回归好得多,因此我们很少用线性回归。

--eta [default=0.3, alias: learning_rate]
学习率,可以缩减每一步的权重值,使得模型更加健壮:
典型值一般设置为:0.01-0.2

--min_child_weight [default=1]
定义了一个子集的所有观察值的最小权重和。
这个可以用来减少过拟合,但是过高的值也会导致欠拟合,因此可以通过CV来调整min_child_weight。
 
 --max_depth [default=6]
树的最大深度,值越大,树越复杂。
这个可以用来控制过拟合,典型值是3-10。

--gamma [default=0, alias: min_split_loss]
这个指定了一个结点被分割时,所需要的最小损失函数减小的大小。
这个值一般来说需要根据损失函数来调整。

--max_delta_step(默认= 0)
这个参数通常并不需要。

--subsample [default=1]
样本的采样率,如果设置成0.5,那么Xgboost会随机选择一半的样本作为训练集。

--colsample_bytree [default=1]
构造每棵树时,列采样率(一般是特征采样率)。

--colsample_bylevel [default=1]
每执行一次分裂,列采样率。这个一般很少用,有subsample、colsample_bytree 就可以。

--lambda [default=1, alias: reg_lambda]
L2正则化(与岭回归中的正则化类似:传送门)这个其实用的很少。

--alpha [default=0, alias: reg_alpha]
L1正则化(与lasso回归中的正则化类似:传送门)这个主要是用在数据维度很高的情况下,可以提高运行速度。

--scale_pos_weight, [default=1]
在类别高度不平衡的情况下,将参数设置大于0,可以加快收敛。

3、学习任务参数

这类参数主要用来明确学习任务和相应的学习目标的

--objective [default=reg:linear]
这个主要是指定学习目标的:而分类,还是多分类or回归
“reg:linear” –linear regression:回归
“binary:logistic”:二分类
“multi:softmax” :多分类,这个需要指定类别个数

--eval_metric [default according to objective]
*评估方法,主要用来验证数据,根据一个学习目标会默认分配一个评估指标
“rmse”:均方根误差(回归任务)
“error”:分类任务
“map”:Mean average precision(平均准确率,排名任务)

--seed [default=0]
随机数种子,可以用来生成可复制性的结果,也可用来调参

 三、Xgboost参数调优实例

调参的通用方法:

-- 选择一个相对较高的学习率。通常来说学习率设置为0.1。但是对于不同的问题可以讲学习率设置在0.05-0.3。通过交叉验证来寻找符合学习率的最佳树的个数。

-- 当确定好学习率与最佳树的个数时,调整树的某些特定参数。比如:max_depth, min_child_weight, gamma, subsample, colsample_bytree

-- 调整正则化参数 ,比如: lambda, alpha。这个主要是为了减少模型复杂度和提高运行速度的。适当地减少过拟合。

1、首先我们设置一些参数的初始值(你可以设置不同的值):

#Choose all predictors except target & IDcols
predictors = [x for x in train.columns if x not in [target, IDcol]]
xgb1 = XGBClassifier(
 learning_rate =0.1,
 n_estimators=20,
 max_depth=5,
 min_child_weight=1,
 gamma=0,
 subsample=0.8,
 colsample_bytree=0.8,
 objective= 'binary:logistic',
 nthread=4,
 scale_pos_weight=1,
 seed=27)
modelfit(xgb1, train, predictors)

2、调整max_depth 和min_child_weight

我们调整这两个参数是因为这两个参数对输出结果的影响很大。我们首先将这两个参数设置为较大的数,然后通过迭代的方式不断修正,缩小范围。

param_test1 = {
 'max_depth':list(range(3,10,2)),
 'min_child_weight':list(range(1,6,2))
}
gsearch1 = GridSearchCV(estimator = XGBClassifier( learning_rate =0.1, n_estimators=20, max_depth=5,
 min_child_weight=1, gamma=0, subsample=0.8, colsample_bytree=0.8,
 objective= 'binary:logistic', nthread=4, scale_pos_weight=1, seed=27), 
 param_grid = param_test1, scoring='roc_auc',n_jobs=4,iid=False, cv=5)
gsearch1.fit(train[predictors],train[target])
gsearch1.grid_scores_, gsearch1.best_params_, gsearch1.best_score_

接下来缩小范围,将两个序列范围约束在[8,9,10];[1,2,3]

param_test2 = {
 'max_depth':[8,9,10],
 'min_child_weight':[1,2,3]
}
gsearch2 = GridSearchCV(estimator = XGBClassifier( learning_rate=0.1, n_estimators=20, max_depth=5,
 min_child_weight=2, gamma=0, subsample=0.8, colsample_bytree=0.8,
 objective= 'binary:logistic', nthread=4, scale_pos_weight=1,seed=27), 
 param_grid = param_test2, scoring='roc_auc',n_jobs=4,iid=False, cv=5)
gsearch2.fit(train[predictors],train[target])
gsearch2.grid_scores_, gsearch2.best_params_, gsearch2.best_score_

3、调整gamma

param_test3 = {
 'gamma':[i/10.0 for i in range(0,5)]
}
gsearch3 = GridSearchCV(estimator = XGBClassifier( learning_rate =0.1, n_estimators=20, max_depth=10,
 min_child_weight=1, gamma=0, subsample=0.8, colsample_bytree=0.8,
 objective= 'binary:logistic', nthread=4, scale_pos_weight=1,seed=27), 
 param_grid = param_test3, scoring='roc_auc',n_jobs=4,iid=False, cv=5)
gsearch3.fit(train[predictors],train[target])
gsearch3.grid_scores_, gsearch3.best_params_, gsearch3.best_score_

 这里gamma已经从我们前面默认的0,变成了0.2了。

最后我们用最优参数再次运行一下程序:

xgb1 = XGBClassifier(
 learning_rate =0.1,
 n_estimators=20,
 max_depth=10,
 min_child_weight=1,
 gamma=0.2,
 subsample=0.8,
 colsample_bytree=0.8,
 objective= 'binary:logistic',
 nthread=4,
 scale_pos_weight=1,
 seed=27)
modelfit(xgb1, train, predictors)

4、调整subsample 和colsample_bytree

param_test5 = {
 'subsample':[i/100.0 for i in range(75,90,5)],
 'colsample_bytree':[i/100.0 for i in range(75,90,5)]
}
gsearch5 = GridSearchCV(estimator = XGBClassifier( learning_rate =0.1, n_estimators=20, max_depth=10,
 min_child_weight=1, gamma=0.2, subsample=0.8, colsample_bytree=0.8,
 objective= 'binary:logistic', nthread=4, scale_pos_weight=1,seed=27), 
 param_grid = param_test5, scoring='roc_auc',n_jobs=4,iid=False, cv=5)
gsearch5.fit(train[predictors],train[target])
gsearch5.grid_scores_, gsearch5.best_params_, gsearch5.best_score_

 5、调整正则化参数

param_test6 = {
 'reg_alpha':[1e-5, 1e-2, 0.1, 1, 100]
}
gsearch6 = GridSearchCV(estimator = XGBClassifier( learning_rate =0.1, n_estimators=20, max_depth=10,
 min_child_weight=1, gamma=0.2, subsample=0.8, colsample_bytree=0.8,
 objective= 'binary:logistic', nthread=4, scale_pos_weight=1,seed=27), 
 param_grid = param_test6, scoring='roc_auc',n_jobs=4,iid=False, cv=5)
gsearch6.fit(train[predictors],train[target])
gsearch6.grid_scores_, gsearch6.best_params_, gsearch6.best_score_

6、减小学习率

param_test6 = {
 'reg_alpha':[1e-5, 1e-2, 0.1, 1, 100]
}
gsearch6 = GridSearchCV(estimator = XGBClassifier( learning_rate =0.1, n_estimators=20, max_depth=10,
 min_child_weight=1, gamma=0.2, subsample=0.8, colsample_bytree=0.8,
 objective= 'binary:logistic', nthread=4, scale_pos_weight=1,seed=27), 
 param_grid = param_test6, scoring='roc_auc',n_jobs=4,iid=False, cv=5)
gsearch6.fit(train[predictors],train[target])
gsearch6.grid_scores_, gsearch6.best_params_, gsearch6.best_score_

最后补充的是:

数据和特征工程决定了模型效果的上限,而模型的调参只是逼近这个上限。

特征工程传送门在此

欢迎关注我的公众号!

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值