参数调优注意事项
参数调优在机器学习中是一门“黑暗艺术”,模型的最佳参数可能取决于许多情况。因此,不可能创建一个全面的指南来指导调优。
本文档试图为 XGBoost 中的参数提供一些指导。
理解偏差-方差权衡
如果你学习过机器学习或统计学课程,这可能是最重要的概念之一。当我们允许模型变得更复杂(例如,增加深度)时,模型对训练数据有更好的拟合能力,从而得到偏差较小的模型。然而,如此复杂的模型需要更多数据来拟合。
XGBoost 中的大多数参数都与偏差-方差权衡有关。最好的模型应该仔细权衡模型复杂性和预测能力。参数文档会告诉你每个参数是否会让模型更保守。这可以帮助你在复杂模型和简单模型之间进行调整。
控制过拟合
当你观察到训练精度很高,但测试精度很低时,很可能是遇到了过拟合问题。
在 XGBoost 中,通常有两种方法可以控制过拟合
第一种方法是直接控制模型的复杂度。
这包括
max_depth
,min_child_weight
,gamma
,max_cat_threshold
以及其他类似的正则化参数。请参阅 XGBoost 参数 以了解完整的参数集。根据你自己的标准设置一个常数
base_score
。更多信息请参阅 截距。
第二种方法是增加随机性,使训练对噪声具有鲁棒性。
这包括
subsample
和colsample_bytree
,可以与 boosting RF 的num_parallel_tree
一起使用。你还可以减小步长
eta
,可能结合训练回调。当你这样做时,请记住增加num_round
。
处理不平衡数据集
对于常见的用例,例如广告点击日志,数据集非常不平衡。这会影响 XGBoost 模型的训练,有两种方法可以改进。
如果你只关心预测的整体性能指标 (AUC)
通过
scale_pos_weight
平衡正负样本权重使用 AUC 进行评估
如果你关心预测正确的概率
在这种情况下,你不能重新平衡数据集
将参数
max_delta_step
设置为一个有限的数值(例如 1)以帮助收敛
使用超参数优化 (HPO) 框架
模型调优是一项复杂的任务,有许多高级框架可以帮助你。例如,一些 scikit-learn 中的元估计器,如 sklearn.model_selection.HalvingGridSearchCV
,可以帮助指导搜索过程。Optuna 是另一个很好的选择,还有许多基于不同统计学分支的框架。
了解你的数据
理解数据的重要性再怎么强调也不为过,有时这足以获得一个好的模型。许多解决方案使用一个简单的 XGBoost 树模型,无需太多调优,而更侧重于数据预处理步骤。XGBoost 可以通过提供全局特征重要性得分和使用 SHAP 值提供样本特征重要性来帮助进行特征选择。此外,还有专门针对类别特征以及生存分析和排序等任务的参数。欢迎探索它们。
减少内存使用
如果你正在使用像 sklearn.model_selection.GridSearchCV
这样的 HPO 库,请控制它可使用的线程数。最好让 XGBoost 并行运行,而不是让 GridSearchCV 同时运行多个实验。例如,为交叉验证创建数据折叠可能会消耗大量内存
# This creates a copy of dataset. X and X_train are both in memory at the same time.
# This happens for every thread at the same time if you run `GridSearchCV` with
# `n_jobs` larger than 1
X_train, X_test, y_train, y_test = train_test_split(X, y)
df = pd.DataFrame()
# This creates a new copy of the dataframe, even if you specify the inplace parameter
new_df = df.drop(...)
array = np.array(...)
# This may or may not make a copy of the data, depending on the type of the data
array.astype(np.float32)
# np by default uses double, do you actually need it?
array = np.array(...)
你可以在文档中找到更多分散的特定内存减少实践。例如:基于 Dask 的分布式 XGBoost, XGBoost GPU 支持。然而,在深入了解这些之前,注意数据复制是一个很好的起点。它通常会消耗比人们预期多得多的内存。