xgboost 调参策略

1. Xgboost 参数说明

XGBoost 本身的核心是基于梯度提升树实现的集成算法,整体来说可以有三个核心部分1
1. 集成算法本身
2. 用于集成的 弱评估器
3. 应用中的其他过程

1.1. 基础设置

1.1.1. 基分类器

1.1.2. 目标函数


reg:squarederror:损失平方回归。

reg:squaredlogerror:对数损失平方回归 12[log(pred+1)−log(label+1)]2。所有输入标签都必须大于-1。

reg:logistic:逻辑回归

reg:gamma:使用对数链接进行伽马回归。输出是伽马分布的平均值。例如,对于建模保险索赔严重性或对可能是伽马分布的任何结果,它可能很有用。

reg:tweedie:使用对数链接进行Tweedie回归。它可能有用,例如,用于建模保险的总损失,或用于可能是Tweedie-distributed的任何结果。

binary:logistic:二元分类的逻辑回归,输出概率

binary:logitraw:用于二进制分类的逻辑回归,逻辑转换之前的输出得分

binary:hinge:二进制分类的铰链损失。这使预测为0或1,而不是产生概率。

count:poisson –计数数据的泊松回归,泊松分布的输出平均值

survival:cox:针对正确的生存时间数据进行Cox回归(负值被视为正确的生存时间)。请注意,预测是按危险比等级返回的(即,比例危险函数中的HR = exp(marginal_prediction))。h(t) = h0(t) * HR

multi:softmax:设置XGBoost以使用softmax目标进行多类分类,还需要设置num_class(类数)

multi:softprob:与softmax相同,但输出向量,可以进一步重整为矩阵。结果包含属于每个类别的每个数据点的预测概率。ndata * nclassndata * nclass

rank:pairwise:使用LambdaMART进行成对排名,从而使成对损失(Pairwise Classification Loss)最小化, 构建树使得 Max(Map(Rank(y), Rank(y_hat))). However, output is always y_hat.

rank:ndcg:使用LambdaMART进行列表式排名,使标准化折让累积收益(NDCG)最大化

rank:map:使用LambdaMART进行列表平均排名,使平均平均精度(MAP)最大化

base_score [默认值= 0.5]

所有实例的初始预测得分,整体偏差
对于足够的迭代次数,更改此值不会有太大影响。

1.1.3. 模型评价

下面列出了这些选择:
rmse:均方根误差
rmsle:均方根对数误差:
mae:平均绝对误差
logloss:负对数似然
error:二进制分类错误率。计算公式为$error=\frac{wrong cases}{all cases}$。对于预测,评估会将预测值大于0.5的实例视为肯定实例,而将其他实例视为否定实例。
error@t:可以通过提供't'的数值来指定不同于0.5的二进制分类阈值。
merror:多类分类错误率。计算公式为。#(wrong cases)/#(all cases)
mlogloss:多类logloss。
auc:曲线下面积
aucpr:PR曲线下的面积
ndcg:归一化累计折扣
map:平均平均精度
ndcg@nmap@n:'n'可以被指定为整数,以切断列表中的最高位置以进行评估。
ndcg-map-ndcg@n-map@n-:在XGBoost,NDCG和MAP将评估清单的比分没有任何阳性样品为1加入-在评价指标XGBoost将评估这些得分为0,是在一定条件下一致“”。
poisson-nloglik:泊松回归的负对数似然
gamma-nloglik:伽马回归的对数似然率
cox-nloglik:Cox比例风险回归的负对数似然率
gamma-deviance:伽马回归的残余偏差
tweedie-nloglik:Tweedie回归的负对数似然(在tweedie_variance_power参数的指定值处)

1.2. 计算过程设置

1.3. 集成算法设置

子采样的方法有两种:行子采样(row subsampling)与列子采样(column subsampling)。这里主要指的是行子采样(row subsampling)

1.4. 弱评估器设置

2

2. 调参实践指南

主要参考资料:Complete Guide to Parameter Tuning in XGBoost with codes in Python

2.1. 一般性的调参路径3

  1. 选择相对较高的学习率lr
  2. 通常设定学习率为0.1。但是对于不同的问题,在0.05~0.3的范围内也有效。
  3. 确定此学习率的下最佳决策树数量tree_num
  4. XGBoost具有一个非常实用的功能--cv,该功能在每次增强迭代时执行交叉验证,从而返回所需的最佳树数。
  5. 在确定lr、tree_num 后调整树特定的参数。
  6. max_depth, min_child_weight, gamma, subsample, colsample_bytree
  7. 调整 xgboost的正则化参数(lambda,alpha),可以帮助降低模型复杂性并提高性能。
  8. 降低学习率并确定最佳参数。
  9. ...loop

2.2. 可用的调参工具

2.2.1. 遍历

问如果数据量不大的话可否用parm_grid罗列所有可能的参数,使用sklearn.GridSearchCV来验证。将所有可能的组合都尝试一下?

2.2.2. 自带CV

一般自己写CV ,xgb.cv() 内存消耗太大。

As uses all the data training in its "black box" cross validation process, one's can have problems with huge data sets.

cv_results = xgboost.cv
    params
    dtrain
    num_boost_round = num_boost_round
    seed = 42
    nfold = 5
    metrics = {'mae'}
    early_stopping_rounds = 10 

cv_results

2.2.3. 其他

参考自动调参工具

## 一般性的参数范围

树的参数
max_depth=5 : [4-6] 可以作为好的起始值
min_child_weight = 1 : 对于高度不平衡问题,可以设的更小
gamma = 0 : 像[0.1-0.2] 这样的小的数值也可以设置为起始值,通常改值在后期进行调整。

subsample=0.8:通常在[0.5-0.9] 之间设置起始值
colsample_bytree = 0.8 :通常在[0.5-0.9] 之间设置起始值

scale_pos_weight = 1: 通常可以将其设置为负样本的数目与正样本数目的比值。

3. Q&A

3.1. 为什么近似分割算法比精确贪心算法要快?

首先我们得捋一下这两个寻找最佳分裂点的时候都有哪些公共的时间开销
1. 预排序。 每个特征都是按照排序好的顺序存储的,这一部分在存储的时候就已经完成了
2. 计算所有样本的一阶导G和二阶导L。这个过程只需要进行一次
3. 对样本的G和L累加求和,这个过程也只需要进行一次,为了后续做差加速
- 精确贪心算法中是将所有样本G、L累加
- 近似分割算法中是按桶累加
4. 算法中的两个for循环,
1. 第一个循环是遍历所有特征(这一步两个算法相同)
2. (关键差异点)不同的开销在于,两个算法中第二个for循环中。因为桶的数目远小于样本数,所以得以加速

# 精确贪心算法O(samples_counts)
for i in range(samples_counts):
    do...
# 近似贪心算法 O(bins_counts)
for i in range(bins_counts):
    do...
# bins_counts<=samples_counts

3.2. 不平衡数据问题 怎么处理

XGBoost中的官方文档(https://xgboost.readthedocs.io/en/latest/parameter.html)大致这么说的:
对于一些case,比如:广告点击日志,数据集极不平衡。这会影响xgboost模型的训练,有两个方法来改进它。
1. 如果你关心的预测的ranking order(AUC):
1. 通过scale_pos_weight来平衡正负类的权重 ,只对目标函数为binary:logistic 有效
2. 使用AUC进行评估

  1. 如果你关心的是预测的正确率:
  2. 这种情形下,不能再平衡(re-balance)数据集
  3. 将参数max_delta_step设置到一个有限的数(比如:1)可以获得效果提升.

此外 有人建议:
All the documentation says that is should be:

scale_pos_weight = count(negative examples)/count(Positive examples)

In practice, that works pretty well, but if your dataset is extremely unbalanced I'd recommend using something more conservative like:

scale_pos_weight = sqrt(count(negative examples)/count(Positive examples)) 

This is useful to limit the effect of a multiplication of positive examples by a very high weight.

3.3. 如何控制模型复杂度

max_depth
gamma
alpha
lambda
min_child_weight

3.4. 如何增加随机性

sample: 行采样、列采样
eta(learning rate)
max_depth

4. 参考资料


  1. xgboost 参数 https://github.com/dmlc/xgboost/blob/master/doc/parameter.rst 

  2. xgboost 中文https://www.bookstack.cn/read/xgboost-doc-zh/docs-5.md 

  3. Complete Guide to Parameter Tuning in XGBoost with codes in Python
     


如果你觉得这篇文章对你有帮助,不妨请我喝杯咖啡,鼓励我创造更多!