xgboost调参_XGBoost调参小结(持续更新)

from xgboost.sklearn import XGBClassifier
clf = XGBClassifier(max_depth=3, learning_rate=0.1, n_estimators=100, silent=True, objective="binary:logistic", booster='gbtree', n_jobs=1, nthread=None, gamma=0,
                    min_child_weight=1, max_delta_step=0, subsample=1, colsample_bytree=1, colsample_bylevel=1, reg_alpha=0, reg_lambda=1, scale_pos_weight=1,
                    base_score=0.5, random_state=0, seed=None, missing=None, **kwargs)
clf.fit(x, y, sample_weight=None, eval_set=None, eval_metric=None, early_stopping_rounds=None, verbose=True, xgb_model=None, sample_weight_eval_set=None, callbacks=None)

首先谈谈为什么选择XGBoost(以下简称xgb),网上有关说明也挺多,例如:损失函数加了正则项呀,损失函数L对弱学习器f做了二阶泰勒展开来拟合残差呀,支持自定义损失函数呀,支持分布式呀等等这些,本人才疏学浅,只是看看,目前还无法实际体会到其中的妙处,对我来说,能体会到的有如下优势:

  • 默认支持缺失值处理。因为数据非常稀疏,缺失值占比很高,如果一个一个处理,不仅费时,而且效果大概率不好,xgb如果你选择树模型,则自动将缺失值当做一个特征,分别加入不同分裂方向看看哪个效果更好,详见论文3.4节,xgb官网也说了,如果选择了线性模型,则将缺失值看做0:https://xgboost.readthedocs.io/en/latest/faq.html#how-to-deal-with-missing-value
  • 速度快,效果好。用过SVM就知道这个算法有多占内存,多慢,折腾半天效果还没有xgb好。
  • 支持并行。这个也算不上优势了吧,毕竟很多都已经支持了,需要注意的是,xgb是boosting这种串行的,一个弱学习器学习需要基于之前的残差,所以需要一个一个来,不像随机森林这种所有弱学习器可以同时进行学习的,xgb这里的并行是在分裂特征时做并行,这个是耗时热点。

网上介绍参数含义的有很多,例如

  • xgb官方:https://xgboost.readthedocs.io/en/latest/parameter.html
  • 一些博客:https://www.analyticsvidhya.com/blog/2016/03/complete-guide-parameter-tuning-xgboost-with-codes-python/

这里就记录下,我个人的调参过程,事实上,有很多工具可以实现自动调参,比如

from sklearn.model_selection import GridSearchCV

你可以把所有想测试的参数都列出来,网格搜索会帮你运行所有的组合,然后得出一个最优的组合,而且,它是支持并行的。再比如这个还没有用过的

from hyperopt import hp

因为我测试的数据量比较大,训练时间比较长,而且,想自己看看调参对结果有什么样的影响,所以就决定自己手动调参。

训练模型的过程中,我们经常会遇到如下几个问题:

  • 1 训练效果不好
  • 2 训练效果很好,验证效果变差
  • 3 训练效果很好,验证效果也好,测试效果变差

对于1呢,可能因为模型简单而无法很好的拟合数据,这就需要调参来解决,比如增加模型的复杂度,当然,也可能是数据本来就辨识度不高。对于2呢,就是传说中的过拟合,通常是因为模型过于复杂,所以在训练效果上很好,可是验证时候就会露出真相。对于3,工作中已经遇到好多次了,据我分析,应该是训练数据对样本空间的覆盖不足导致的,当新的数据模式和训练验证数据有些差别时候,模型就会失效,这时候,只能通过增加训练样本数量来解决。

接下来就聊聊我最近的调参历程,我是用auc来做评估的,训练数据和测试数据都是2000万左右,正负样本比例1:166。

1 XGBClassifier

  • max_depth:树的最大深度,太小了可能导致欠拟合,太大了又可能导致过拟合,我起初把它设为10,降低到5后模型效果显著提高,再往下降效果就会下降。
  • learning_rate:学习率,也就是论文中说的“Shrinkage”,它可以减小前面的几棵树对结果的影响,从而给后面子树留下更多的发挥空间,我设成了0.1感觉训练还是很慢,升到0.2和降到0.05效果都会略微变差。
  • n_estimators:起初我以为这个是弱学习器的个数,想着越大肯定效果会越好嘛,于是就先设了个10000,可是后面无意中发现,当我把这个数降到8000,再到5000,再到2000,再到1000,最后到800,训练测试结果竟然完全一模一样!中间输出结果都是一样样的,所以我目前觉得,这个只是弱学习期的最大个数,最终实际的个数是小于它的,结合fit函数中有个参数是early_stopping_rounds,就是说如果过了多少轮后验证效果都没有提高,就停止训练,所以我就猜想,应该是每增加一颗子树,做一次验证,如果验证结果不再提高了,那么就不再增加子树而停止,所以最终的子树个数应该是输出里面最优的验证结果所在的行数。当然,这个是个人猜测,有了解的大佬可以指点下。
  • booster:xgb支持树模型和线性模型,树模型除了默认的gbtree还有个dart,我试了下,训练时候结果显著提高,当时还有些激动,可是测试时候效果轻微下降了。
  • n_jobs:如果集群只有你自己用,可以设成-1。
  • subsample,colsample_bytree:这俩一起说,类似随机森林,也是在训练时对行列做一个采样,防止过拟合,做了两次测试,一次将subsample设成0.9,另一次将两个都设为0.9,问题同样是训练结果提高,测试结果下降了,我预感,可能是因为特征比较少,丢掉后对测试结果有影响吧。
  • reg_alpha,reg_lambda:这俩也一起说,就是模型损失函数里面正则项的1次和2次项的系数,文章中明明是gamma,不知道为啥到这里变成了alpha。。。这个也是为了防止过拟合的,reg_alpha起初我也没太在意就用的默认的0,可后来当我把它提高到2,5,8时候,测试结果有了显著提高,然后我一股脑把它设成呢个了15,效果下降了。二次项的reg_lambda调整后感觉变化不大。
  • scale_pos_weight:这个参数应该说比较重要的,它是为了防止正负样本比例相差太大,因为在我的训练样本中,负样本是正样本的166倍,所以我就把它设成了166,如果用默认的1,效果会显著下降。补充:将这个权值变成了0.8*166,不仅auc值提高了,logloss也降低了很多,可如果继续降低权值变成0.6倍,则效果下滑。

2 fit

  • eval_set:验证集合的list,如果你只写了验证集,那么你就看不到在训练集中的表现对比。
  • eval_metric:评估标准,例如logloss,auc这些。
  • early_stopping_rounds:上面说过了,如果后续这么多轮效果依旧没有提高,则停止训练,最终结果取验证最优的那次,我一般设成20。
  • verbose:是否输出验证集效果的信息,默认即可。
  • callbacks:其实这个我还没用,比如在这里可以设置动态的学习率,越往后学习率越低,训练过程前期大步走,后期防止错过最优点所以训练速度慢一些。

顺便说点别的:

  • 对于经常出现的过拟合和数据不平衡的问题,xgb官网给出的建议:https://xgboost.readthedocs.io/en/latest/tutorials/param_tuning.html
  • 其中,scale_pos_weight解释见:https://stats.stackexchange.com/questions/243207/what-is-the-proper-usage-of-scale-pos-weight-in-xgboost-for-imbalanced-datasets
  • max_delta_step解释比较模糊:https://stats.stackexchange.com/questions/233248/max-delta-step-in-xgboost
  • 写一个训练中出现过的问题吧,因为用的是pandas读数据,这些数据都是有表头的,如果直接将df当做x传入xgb训练,则在测试时,如果数据没有表头或者表头不对应,则会报错,其他算法就没有这个问题,为了解决这个问题,最好把df.values当做x。

调了一段时间的参数,效果提升了千分之5,虽然没有那么明显吧,可在这个过程中对算法和参数设置又有了自己的一些体会。因为对论文很多地方理解还不透彻,以后有了新的发现会随时更新进来,也欢迎各位大佬批评指正。

补充一点感想:对于正负样本不均衡的样本,怎么感觉auc和logloss是鱼和熊掌的关系,auc提高时,logloss也会变大,auc降低时,logloss也会变小。除了降低正样本权值时候,auc提高了一点,而logloss突然降低了很多(0.4105->0.3576)。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值