参数调优说明
参数调优在机器学习中是一门玄学,模型的最佳参数可能取决于多种情况。因此,不可能为此创建一个全面的指南。
本文档试图为 XGBoost 中的参数提供一些指导。
理解偏差-方差权衡
如果你上过机器学习或统计学课程,这很可能是最重要的概念之一。当我们允许模型变得更复杂(例如,更深的深度)时,模型更好地拟合训练数据的能力,从而导致偏差更小的模型。然而,这种复杂的模型需要更多的数据来拟合。
XGBoost 中的大多数参数都与偏差-方差权衡有关。最好的模型应该仔细权衡模型的复杂性与其预测能力。参数文档将告诉你每个参数是否会使模型更保守。这可以帮助你在复杂模型和简单模型之间进行调整。
控制过拟合
当你观察到较高的训练准确性但较低的测试准确性时,很可能遇到了过拟合问题。
XGBoost 中控制过拟合通常有两种方法
第一种方法是直接控制模型复杂度。
这包括
max_depth
、min_child_weight
、gamma
、max_cat_threshold
和其他类似的正则化参数。有关全面的参数集,请参阅XGBoost 参数。根据你的标准设置一个常量
base_score
。有关更多信息,请参阅截距。
第二种方法是增加随机性,使训练对噪声具有鲁棒性。
这包括
subsample
和colsample_bytree
,它们可以与提升 RFnum_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 值的样本特征重要性来帮助特征选择。此外,还有专门针对分类特征以及生存和排序等任务的参数。请随意探索它们。
减少内存使用
如果你正在使用 HPO 库,例如sklearn.model_selection.GridSearchCV
,请控制它可以使用的线程数。最好让 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 支持。然而,在深入研究这些之前,注意避免数据复制是一个很好的起点。它通常比人们预期的消耗更多的内存。