# Xgboost调参

## Xgboost的参数

XGBoost的作者把所有的参数分成了三类:

* 通用参数: 宏观函数控制
* Booster参数: 控制每一棵树(Booster)的表现
* 学习任务参数: 控制训练目标的表现

### 通用参数

#### booster

默认值为`'gbtree'`. 有两种选择:

* gbtree: 基模型是树决策树模型
* gbliner: 基模型是线性模型

决策树的表现往往比线性模型好很多, 因此这项基本使用默认值.

#### silent

默认值为`0`. 模型训练过程中, 是否输出过程信息, 为`1`时不输出, 因此默认为输出.

#### nthread

控制线程数量的参数. 如果想使用最大算力, 就不要设置这个参数, 让框架自动检测

### Booster参数

#### eta

**shrinkage参数**, 用于更新叶子节点权重时, 乘以该系数, 避免步长过大, 降低一棵基学习器的权重, 增加模型整体的鲁棒性. 大的值可能导致模型无法收敛.

默认值为`0.3`, 取值范围在\[0, 1]之间, 典型范围为`0.01~0.2`.

另外在sklearn风格中, 该参数记为**learning\_rate**.

#### min\_child\_weight

叶子节点样本权重和的最小值, 权重指的就是每个样本的**二次梯度**. 控制分裂过程, 只有分裂后对应所有样本的权值之和大于这个值时, 才会进行本次分裂.

这个参数对结果的影响很大, 如果值太大, 分裂会被阻止, 导致欠拟合; 值太小, 分裂无节制, 又容易过拟合.

另外这个在遇到**不均衡数据集**时, 该参数的调参也非常重要. 这种情况下, 往往会有一类样本的权重很小, 意味着一个叶子节点中可能包含很多的样本. 这种现象好坏因情况而异, 但对模型的表现是有很重要的影响的.

参数的默认值是`1`.

#### max\_depth

树的最大深度, max\_depth越大, 模型会学到更具体更局部的样本, 更容易过拟合.

默认值为`6`, 典型范围为`3~10`.

#### gamma

在节点分裂时, 只有分裂后损失函数的值下降了, 才会分裂这个节点, gamma指定了节点分裂所需的最小损失函数下降值. 参数值越大, 越容易欠拟合.

默认值为`0`.

在sklearn风格中, 该参数记为**min\_split\_loss**.

#### max\_delta\_step

这参数限制每棵树权重(叶子节点输出)改变的最大步长, 如果这个参数的值为0, 那就意味着没有约束. 如果它被赋予了某个正值, 那么它会让这个算法更加保守.

通常, 这个参数不需要设置. 但是当各类别的样本十分不平衡时, 是很有帮助的.

默认值为`0`, 典型范围为`1~10`.

#### subsample

生成每棵树时, 样本随机采样的比例, 用来防止过拟合. 但如果值过小, 也容易欠拟合.

默认值为`1`, 即不进行采样, 典型范围为`0.5~1`.

#### colsample\_bytree

生成每棵树时, 随机采样的特征比例, 也是用来增强泛化性的参数.

默认值为`1`, 即不进行采样, 典型范围为`0.5~1`.

#### alpha

控制模型复杂程度的权重值的L1正则项参数, 值越大, 越不容易过拟合.

默认值为`0`.

在sklearn风格中, 该参数记为**reg\_alpha**.

#### lambda

控制模型复杂度的权重值的L2正则化项参数, 值越大, 模型越不容易过拟合.

默认值为`1`.

在sklearn风格中, 该参数记为**reg\_lambda**.

#### scale\_pos\_weight

控制正样本和负样本的权值比例, 在各类别样本十分不平衡时, 把这个参数设定为一个正值, 可以使算法更快收敛.

默认值为`1`, 一个典型值为`正样本数量/负样本数量`.

### 学习任务参数

#### objective

损失函数. 不同的任务选择不同的损失函数:

**回归任务**

* **reg:squarederror**: 也是默认值, 最常用的回归任务损失函数, 平方损失
* **reg:squaredlogerror**: squared log loss, $$\frac{1}{2}\[\log (\text { pred }+1)-\log (\text { label }+1)]^{2}$$, 要求所有的label值都大于-1.

**二分类任务**

* **binary:logistic**: 对数损失函数,  模型返回的值是分类为正样本的概率值

**多分类任务**

* **multi:softmax**: 使用softmax的多分类器, 返回预测的类别, 而非概率
* **multi:softprob**: 与multi:softmax对应, 返回的是概率

所有可选的损失函数类型参考[官方文档](https://xgboost.readthedocs.io/en/latest/parameter.html#learning-task-parameters).

#### eval\_metric

度量方法, 根据`objective`参数的取值而定

**回归任务**

* **rmse**: 回归任务的默认值, $$R M S E=\sqrt{\frac{1}{n} \sum\_{i=1}^{n}\left(y\_{i}-\hat{y}\_{i}\right)^{2}}$$
* **mae**: Mean absolute error

**二分类任务**

* **error**: 二分类任务默认度量方法, 分类的错误率
* **logloss**: negative log-likelihood

**多分类任务**

* **merror**: 多分类的错误率, 错分样本数量 / 总样本数量
* **mlogloss**: Multiclass logloss

#### seed

随机种子, 默认为`0`, 设置它可以复现随机数据的结果.

### 调参方法

Xgboost一般使用网格搜索法, 搜索出一组最优的超参数. 但由于Xgboost的超参数很多, 且相互之间有影响, 每个超参数都要划分细致, 从而产生很多组参数. 这样的搜索的空间是很大的.

因此一般将Xgboost的参数分为几组, 分组调参, 最后组合再微略调整. 过程为:

* 选择**较高学习率** **learning\_rate**, 并在其他超参数为默认值的情况下, 根据此学习率选择**合适的决策树数量**, 即**n\_estimators**参数. 这一步的目的是较高学习率下使用的决策树的数量少, 整体收敛快, 适合在接下来对决策树超参数调整的**快速验证**.
* 调整对基学习器表现影响最大的两个参数**max\_depth**和**min\_child\_weight**
* 然后调整控制分裂过程的**gamma**参数
* 调整采样参数**subsample**及**colsample\_bytree**
* 调整正则项参数**alpha**和**lambda**
* 最后减小学习率**learning\_rate**, 同时需要增加基学习器**n\_estimators**的数量, 得到最优的结果

## 参考资料

* [XGBoost Parameters](https://xgboost.readthedocs.io/en/latest/parameter.html#general-parameters)
* [XgBoost推导与总结](https://www.cnblogs.com/fisherinbox/p/6519910.html)
* [XGBoost参数调优完全指南](https://www.cnblogs.com/lvpengbo/p/8822318.html)
* [XGboost数据比赛实战之调参篇(完整流程)](https://segmentfault.com/a/1190000014040317)
