在本教程中,你将学习如何使用梯度提升来构建和优化模型。该方法在众多 Kaggle 比赛中占据主导地位,并在各种数据集上取得了最佳结果。
Introduction
在本课程的大部分内容中,您已经使用随机森林方法进行了预测,该方法通过对多棵决策树的预测进行平均,实现了比单棵决策树更好的性能。
我们将随机森林方法称为“集成方法”。根据定义,集成方法会组合多个模型(例如,在随机森林中,是多棵树)的预测。
接下来,我们将学习另一种集成方法,称为梯度提升。
Gradient Boosting
梯度提升 是一种循环迭代地将模型添加到集成中的方法。
它首先用一个模型初始化集成,该模型的预测结果可能非常不准确。(即使它的预测结果非常不准确,后续添加到集成中的模型也会纠正这些错误。)
然后,我们开始循环:
- 首先,我们使用当前集成对数据集中的每个观测值生成预测。为了进行预测,我们将集成中所有模型的预测结果相加。
- 这些预测结果用于计算损失函数(例如 均方误差)。
- 然后,我们使用损失函数拟合一个即将添加到集成中的新模型。具体来说,我们确定模型参数,以便将这个新模型添加到集成中可以降低损失。 (附注:“梯度提升”中的“梯度”指的是我们将在损失函数上使用梯度下降来确定这个新模型的参数。)
- 最后,我们将新模型添加到集成模型中,然后……
- ……重复!

Example
我们首先在“X_train”、“X_valid”、“y_train”和“y_valid”中加载训练和验证数据。
import pandas as pd from sklearn.model_selection import train_test_split
data = pd.read_csv('../input/melbourne-housing-snapshot/melb_data.csv')
cols_to_use = ['Rooms', 'Distance', 'Landsize', 'BuildingArea', 'YearBuilt'] X = data[cols_to_use]
y = data.Price
X_train, X_valid, y_train, y_valid = train_test_split(X, y)
|
在本例中,您将使用 XGBoost 库。XGBoost 代表极端梯度提升,它是梯度提升的一种实现,并添加了几个专注于性能和速度的附加功能。(Scikit-learn 有另一个版本的梯度提升,但 XGBoost 具有一些技术优势。)
在下一个代码单元中,我们导入了 XGBoost 的 scikit-learn API (xgboost.XGBRegressor)。这使我们能够像在 scikit-learn 中一样构建和拟合模型。正如您在输出中看到的,XGBRegressor 类有许多可调参数——您很快就会了解这些参数!
from xgboost import XGBRegressor
my_model = XGBRegressor() my_model.fit(X_train, y_train) XGBRegressor(base_score=0.5, booster='gbtree', callbacks=None, colsample_bylevel=1, colsample_bynode=1, colsample_bytree=1, early_stopping_rounds=None, enable_categorical=False, eval_metric=None, gamma=0, gpu_id=-1, grow_policy='depthwise', importance_type=None, interaction_constraints='', learning_rate=0.300000012, max_bin=256, max_cat_to_onehot=4, max_delta_step=0, max_depth=6, max_leaves=0, min_child_weight=1, missing=nan, monotone_constraints='()', n_estimators=100, n_jobs=0, num_parallel_tree=1, predictor='auto', random_state=0, reg_alpha=0, reg_lambda=1, ...)
|
我们还做出预测并评估模型。
from sklearn.metrics import mean_absolute_error
predictions = my_model.predict(X_valid) print("Mean Absolute Error: " + str(mean_absolute_error(predictions, y_valid))) Mean Absolute Error: 241041.5160392121
|
Parameter Tuning
XGBoost 有一些参数会显著影响准确率和训练速度。您应该首先了解以下参数:
n_estimators
n_estimators 指定执行上述建模周期的次数。它等于我们在集成中包含的模型数量。
- 值过低会导致欠拟合,从而导致对训练数据和测试数据的预测不准确。
- 值过高会导致过拟合,从而导致对训练数据的预测准确,但对测试数据的预测不准确(这才是我们关心的)。
典型值的范围是 100-1000,但这在很大程度上取决于下面讨论的 learning_rate 参数。
以下是设置集成中模型数量的代码:
my_model = XGBRegressor(n_estimators=500) my_model.fit(X_train, y_train) XGBRegressor(base_score=0.5, booster='gbtree', callbacks=None, colsample_bylevel=1, colsample_bynode=1, colsample_bytree=1, early_stopping_rounds=None, enable_categorical=False, eval_metric=None, gamma=0, gpu_id=-1, grow_policy='depthwise', importance_type=None, interaction_constraints='', learning_rate=0.300000012, max_bin=256, max_cat_to_onehot=4, max_delta_step=0, max_depth=6, max_leaves=0, min_child_weight=1, missing=nan, monotone_constraints='()', n_estimators=500, n_jobs=0, num_parallel_tree=1, predictor='auto', random_state=0, reg_alpha=0, reg_lambda=1, ...)
|
early_stopping_rounds
early_stopping_rounds 提供了一种自动找到 n_estimators 理想值的方法。即使 n_estimators 尚未达到硬停止点,提前停止也会导致模型在验证分数停止提升时停止迭代。明智的做法是将 n_estimators 设置为一个较高的值,然后使用 early_stopping_rounds 找到停止迭代的最佳时机。
由于随机因素有时会导致验证分数在某一轮中没有提升,因此您需要指定一个数字,以表示在停止之前允许连续下降的轮数。设置 early_stopping_rounds=5 是一个合理的选择。在本例中,我们会在验证分数连续下降 5 轮后停止迭代。
使用 early_stopping_rounds 时,您还需要预留一些数据用于计算验证分数——这可以通过设置 eval_set 参数来实现。
我们可以修改上面的示例,使其包含提前停止:
my_model = XGBRegressor(n_estimators=500) my_model.fit(X_train, y_train, early_stopping_rounds=5, eval_set=[(X_valid, y_valid)], verbose=False) /opt/conda/lib/python3.7/site-packages/xgboost/sklearn.py:797: UserWarning: `early_stopping_rounds` in `fit` method is deprecated for better compatibility with scikit-learn, use `early_stopping_rounds` in constructor or`set_params` instead. UserWarning, XGBRegressor(base_score=0.5, booster='gbtree', callbacks=None, colsample_bylevel=1, colsample_bynode=1, colsample_bytree=1, early_stopping_rounds=None, enable_categorical=False, eval_metric=None, gamma=0, gpu_id=-1, grow_policy='depthwise', importance_type=None, interaction_constraints='', learning_rate=0.300000012, max_bin=256, max_cat_to_onehot=4, max_delta_step=0, max_depth=6, max_leaves=0, min_child_weight=1, missing=nan, monotone_constraints='()', n_estimators=500, n_jobs=0, num_parallel_tree=1, predictor='auto', random_state=0, reg_alpha=0, reg_lambda=1, ...)
|
如果您稍后想要用所有数据拟合模型,请将 n_estimators 设置为您在使用提前停止算法运行时发现的最佳值。
learning_rate
与其简单地将每个组件模型的预测结果相加,不如先将每个模型的预测结果乘以一个小数(称为学习率),然后再将它们相加。
这意味着我们添加到集成模型中的每棵树对训练集的帮助都更小。因此,我们可以将 n_estimators 设置得更高,而不会出现过拟合。如果我们使用提前停止算法,系统将自动确定合适的树数量。
通常,较小的学习率和较大的估计器数量将产生更准确的 XGBoost 模型,但由于模型在训练过程中会进行更多次迭代,因此训练时间也会更长。默认情况下,XGBoost 设置 learning_rate=0.1。
修改上述示例以更改学习率,代码如下:
my_model = XGBRegressor(n_estimators=1000, learning_rate=0.05) my_model.fit(X_train, y_train, early_stopping_rounds=5, eval_set=[(X_valid, y_valid)], verbose=False) XGBRegressor(base_score=0.5, booster='gbtree', callbacks=None, colsample_bylevel=1, colsample_bynode=1, colsample_bytree=1, early_stopping_rounds=None, enable_categorical=False, eval_metric=None, gamma=0, gpu_id=-1, grow_policy='depthwise', importance_type=None, interaction_constraints='', learning_rate=0.05, max_bin=256, max_cat_to_onehot=4, max_delta_step=0, max_depth=6, max_leaves=0, min_child_weight=1, missing=nan, monotone_constraints='()', n_estimators=1000, n_jobs=0, num_parallel_tree=1, predictor='auto', random_state=0, reg_alpha=0, reg_lambda=1, ...)
|
n_jobs
对于较大的数据集,如果需要考虑运行时间,您可以使用并行性来更快地构建模型。通常将参数“n_jobs”设置为等于机器的核心数。对于较小的数据集,这不会有帮助。
生成的模型不会有任何改进,因此对拟合时间进行微优化通常只会分散注意力。但是,这在大型数据集中很有用,否则您将在“fit”命令中花费很长时间等待。
以下是修改后的示例:
my_model = XGBRegressor(n_estimators=1000, learning_rate=0.05, n_jobs=4) my_model.fit(X_train, y_train, early_stopping_rounds=5, eval_set=[(X_valid, y_valid)], verbose=False) XGBRegressor(base_score=0.5, booster='gbtree', callbacks=None, colsample_bylevel=1, colsample_bynode=1, colsample_bytree=1, early_stopping_rounds=None, enable_categorical=False, eval_metric=None, gamma=0, gpu_id=-1, grow_policy='depthwise', importance_type=None, interaction_constraints='', learning_rate=0.05, max_bin=256, max_cat_to_onehot=4, max_delta_step=0, max_depth=6, max_leaves=0, min_child_weight=1, missing=nan, monotone_constraints='()', n_estimators=1000, n_jobs=4, num_parallel_tree=1, predictor='auto', random_state=0, reg_alpha=0, reg_lambda=1, ...)
|
Conclusion
XGBoost 是一个领先的软件库,用于处理标准表格数据(即存储在 Pandas DataFrame 中的数据类型,而不是图像和视频等更特殊的数据类型)。通过仔细调整参数,您可以训练出高精度的模型。