参数调整的注意事项

参数调优是机器学习中的一门暗艺术,模型的最佳参数可能取决于许多场景。因此,不可能为此创建一个全面的指南。

本文档试图为 XGBoost 中的参数提供一些指导。

理解偏差-方差权衡

如果你参加机器学习或统计课程,这很可能是其中最重要的概念之一。当我们允许模型变得更复杂(例如,更深)时,模型能更好地拟合训练数据,从而得到一个偏差较小的模型。然而,这种复杂的模型需要更多的数据来拟合。

XGBoost 中的大多数参数都与偏差-方差权衡有关。最佳模型应在模型复杂度和预测能力之间谨慎权衡。参数文档 将告诉你每个参数是否会使模型更加保守。这可以帮助你在复杂模型和简单模型之间调整。

控制过拟合

当你观察到高训练准确率,但低测试准确率时,很可能遇到了过拟合问题。

在XGBoost中,通常有两种方法可以控制过拟合:

  • 第一种方法是直接控制模型复杂度。

    • 这包括 max_depthmin_child_weightgamma

  • 第二种方法是增加随机性,使训练对噪声具有鲁棒性。

    • 这包括 subsamplecolsample_bytree

    • 你也可以减少步长 eta。记得在这样做的时候增加 num_round

处理不平衡数据集

对于广告点击日志等常见情况,数据集极度不平衡。这会影响XGBoost模型的训练,有两种方法可以改进。

  • 如果你只关心预测的整体性能指标(AUC)

    • 通过 scale_pos_weight 平衡正负权重

    • 使用AUC进行评估

  • 如果你关心预测正确的概率

    • 在这种情况下,你无法重新平衡数据集

    • 将参数 max_delta_step 设置为一个有限数值(例如1)以帮助收敛

减少内存使用

如果你使用的是像 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 的分布式 XGBoostXGBoost GPU 支持。然而,在深入这些之前,意识到减少数据拷贝是一个好的起点。它通常比人们预期的消耗更多的内存。