【问题标题】:Grid Search and Early Stopping Using Cross Validation with XGBoost in SciKit-Learn在 SciKit-Learn 中使用 XGBoost 交叉验证进行网格搜索和提前停止
【发布时间】:2017-10-07 13:20:56
【问题描述】:

我对 sci-kit learn 还很陌生,并且一直在尝试对 XGBoost 进行超参数调整。我的目标是使用提前停止和网格搜索来调整模型参数,并使用提前停止来控制树的数量并避免过度拟合。

由于我对网格搜索使用交叉验证,我希望在早期停止条件中也使用交叉验证。到目前为止,我的代码如下所示:

import numpy as np
import pandas as pd
from sklearn import model_selection
import xgboost as xgb

#Import training and test data
train = pd.read_csv("train.csv").fillna(value=-999.0)
test = pd.read_csv("test.csv").fillna(value=-999.0)

# Encode variables
y_train = train.price_doc
x_train = train.drop(["id", "timestamp", "price_doc"], axis=1)

# XGBoost - sklearn method
gbm = xgb.XGBRegressor()

xgb_params = {
'learning_rate': [0.01, 0.1],
'n_estimators': [2000],
'max_depth': [3, 5, 7, 9],
'gamma': [0, 1],
'subsample': [0.7, 1],
'colsample_bytree': [0.7, 1]
}

fit_params = {
'early_stopping_rounds': 30,
'eval_metric': 'mae',
'eval_set': [[x_train,y_train]]
}

grid = model_selection.GridSearchCV(gbm, xgb_params, cv=5, 
fit_params=fit_params)
grid.fit(x_train,y_train)

我遇到的问题是“eval_set”参数。我知道这需要预测变量和响应变量,但我不确定如何使用交叉验证数据作为提前停止标准。

有谁知道如何解决这个问题?谢谢。

【问题讨论】:

    标签: python scikit-learn cross-validation xgboost grid-search


    【解决方案1】:

    在 GridSearchCV 中包含提前停止没有多大意义。提前停止用于快速找到训练/有效情况下的最佳 n_rounds。如果我们不关心“快速”,我们可以调整 n_rounds。假设 GridSearchCV 具有为每个折叠执行提前停止 n_rounds 的功能,那么对于每组超参数,我们将有 N(折叠数) n_rounds。也许 n_rounds 的平均值可以用于最终的最佳超参数集,但当 n_rounds 彼此相差太大时,它可能不是一个好的选择。因此,在 GridSearchCV 中包含提前停止可能会提高 Trianing 的速度,但结果可能不是最好的。

    接受的答案中建议的方法更像是调整 n_rounds 参数而不是提前停止,因为作者承认“它不会节省评估所有可能的 n_rounds 所需的计算时间”。

    【讨论】:

      【解决方案2】:

      使用xgboost原创。

      从数据Dmatrix 生成并使用xgboost.cv

      tutorial

      【讨论】:

        【解决方案3】:

        您可以将 early_stopping_rounds 和 eval_set 作为额外的 fit_params 传递给 GridSearchCV,这实际上是可行的。但是,GridSearchCV 不会更改不同折叠之间的 fit_params,因此您最终会在所有折叠中使用相同的 eval_set,这可能不是您所说的 CV。

        model=xgb.XGBClassifier()
        clf = GridSearchCV(model, parameters,
                                 fit_params={'early_stopping_rounds':20,\
                                 'eval_set':[(X,y)]},cv=kfold)  
        

        经过一些调整,我发现整合 early_stopping_rounds 和sklearn API 最安全的方法是自己实现 early_stopping 机制。如果您使用 n_rounds 作为要调整的参数执行GridSearchCV,则可以这样做。然后,您可以随着n_rounds 的增加观察不同模型的 mean_validation_score。然后,您可以为提前停止定义自定义启发式。它不会节省评估所有可能的n_rounds 所需的计算时间

        我认为这也是一种更好的方法,然后为此目的使用单个拆分保持。

        【讨论】:

        • @Martijn Pieters 当这个被接受时,我会将另一个标记为重复。我不能,因为这还没有回答
        • @00_00_00 你能具体说明'eval_set':[(X,y)] 是做什么的吗?我认为当我们 clf.fit(X_total,y_total) 时,数据X_total 将分为训练集和测试集。如果我们将ealy_stopping_rounds 设置为fit_params,则模型将在训练集上进行训练并在测试集上进行评估。因此,我们不需要为 early_stopping 传递额外的'eval_set':[(X,y)]。我说得通吗?
        • 如果我们不将 'eval_set':[(X,y)] 传递给fit_params,代码将引发类似this 的错误。似乎我们做了一个网格搜索,将 X_total 分成 n 次折叠,并将模型从折叠 n 次中拟合出来,每次都使用 eval_set':[(X,y)] 拟合模型早期停止。所以我认为它不符合 CV 的想法,这意味着建立模型并在每个折叠上进行评估。
        • @Travis,我不太明白你的意思。提前停止总是根据为所有 cv 折叠提供的 (X,y) 完成。只要在保留数据集上计算准确度指标,我们最终将获得正确的“平均测试”分数,从而获得最佳 XGB。我不明白这里有什么不一致的地方。你能解释一下吗?
        猜你喜欢
        • 2013-01-29
        • 2017-12-29
        • 2016-03-29
        • 2017-04-12
        • 2020-10-28
        • 2021-10-25
        • 2017-06-19
        • 2018-05-17
        • 2021-12-11
        相关资源
        最近更新 更多