GridSearchCV - XGBoost - Ранняя остановка

Я пытаюсь выполнить поиск гиперпареметра с помощью scikit-learn GridSearchCV на XGBoost. Во время gridsearch я хотел бы, чтобы он был на ранней стадии, поскольку он значительно сокращает время поиска и (ожидает) имеет лучшие результаты в моей задаче предсказания/регрессии. Я использую XGBoost через свой Scikit-Learn API.

    model = xgb.XGBRegressor()
    GridSearchCV(model, paramGrid, verbose=verbose ,fit_params={'early_stopping_rounds':42}, cv=TimeSeriesSplit(n_splits=cv).get_n_splits([trainX, trainY]), n_jobs=n_jobs, iid=iid).fit(trainX,trainY)

Я попытался дать ранние параметры остановки с помощью fit_params, но затем он выдает эту ошибку, которая в основном из-за отсутствия набора проверки, который требуется для ранней остановки:

/opt/anaconda/anaconda3/lib/python3.5/site-packages/xgboost/callback.py in callback(env=XGBoostCallbackEnv(model=<xgboost.core.Booster o...teration=4000, rank=0, evaluation_result_list=[]))
    187         else:
    188             assert env.cvfolds is not None
    189 
    190     def callback(env):
    191         """internal function"""
--> 192         score = env.evaluation_result_list[-1][1]
        score = undefined
        env.evaluation_result_list = []
    193         if len(state) == 0:
    194             init(env)
    195         best_score = state['best_score']
    196         best_iteration = state['best_iteration']

Как я могу применить GridSearch на XGBoost с помощью early_stopping_rounds?

note: модель работает без gridsearch, также GridSearch работает без 'fit_params = {' early_stopping_rounds ': 42}

Ответ 1

Обновление ответа @glao и ответа на комментарий/вопрос @Vasim, начиная с sklearn 0.21.3 (обратите внимание, что fit_params был удален из экземпляра GridSearchCV и перемещен в метод fit(); также импорт специально извлекает модуль оболочки sklearn из xgboost):

import xgboost.sklearn as xgb
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import TimeSeriesSplit

cv = 2

trainX= [[1], [2], [3], [4], [5]]
trainY = [1, 2, 3, 4, 5]

# these are the evaluation sets
testX = trainX 
testY = trainY

paramGrid = {"subsample" : [0.5, 0.8]}

fit_params={"early_stopping_rounds":42, 
            "eval_metric" : "mae", 
            "eval_set" : [[testX, testY]]}

model = xgb.XGBRegressor()

gridsearch = GridSearchCV(model, paramGrid, verbose=1,             
         cv=TimeSeriesSplit(n_splits=cv).get_n_splits([trainX, trainY]))

gridsearch.fit(trainX, trainY, **fit_params)

Ответ 2

При использовании early_stopping_rounds вам также нужно предоставить eval_metric и eval_set качестве входного параметра для метода подгонки. Ранняя остановка выполняется путем вычисления ошибки в оценочном наборе. Ошибка должна уменьшать каждую early_stopping_rounds иначе генерация дополнительных деревьев будет остановлена раньше.

Подробнее см. Документацию по методу соответствия xgboosts.

Здесь вы видите минимальный полностью рабочий пример:

import xgboost as xgb
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import TimeSeriesSplit

cv = 2

trainX= [[1], [2], [3], [4], [5]]
trainY = [1, 2, 3, 4, 5]

# these are the evaluation sets
testX = trainX 
testY = trainY

paramGrid = {"subsample" : [0.5, 0.8]}

fit_params={"early_stopping_rounds":42, 
            "eval_metric" : "mae", 
            "eval_set" : [[testX, testY]]}

model = xgb.XGBRegressor()
gridsearch = GridSearchCV(model, paramGrid, verbose=1 ,
         fit_params=fit_params,
         cv=TimeSeriesSplit(n_splits=cv).get_n_splits([trainX,trainY]))
gridsearch.fit(trainX,trainY)