Sklearn передает параметры fit() в xgboost в конвейере

Аналогично Как передать параметр только одной части объекта конвейера в scikit Learn? Я хочу передать параметры только одной части конвейера. Обычно это должно работать нормально, например:

estimator = XGBClassifier()
pipeline = Pipeline([
        ('clf', estimator)
    ])

и выполнен как

pipeline.fit(X_train, y_train, clf__early_stopping_rounds=20)

но он терпит неудачу с:

    /usr/local/lib/python3.5/site-packages/sklearn/pipeline.py in fit(self, X, y, **fit_params)
        114         """
        115         Xt, yt, fit_params = self._pre_transform(X, y, **fit_params)
    --> 116         self.steps[-1][-1].fit(Xt, yt, **fit_params)
        117         return self
        118 

    /usr/local/lib/python3.5/site-packages/xgboost-0.6-py3.5.egg/xgboost/sklearn.py in fit(self, X, y, sample_weight, eval_set, eval_metric, early_stopping_rounds, verbose)
        443                               early_stopping_rounds=early_stopping_rounds,
        444                               evals_result=evals_result, obj=obj, feval=feval,
    --> 445                               verbose_eval=verbose)
        446 
        447         self.objective = xgb_options["objective"]

    /usr/local/lib/python3.5/site-packages/xgboost-0.6-py3.5.egg/xgboost/training.py in train(params, dtrain, num_boost_round, evals, obj, feval, maximize, early_stopping_rounds, evals_result, verbose_eval, learning_rates, xgb_model, callbacks)
        201                            evals=evals,
        202                            obj=obj, feval=feval,
    --> 203                            xgb_model=xgb_model, callbacks=callbacks)
        204 
        205 

    /usr/local/lib/python3.5/site-packages/xgboost-0.6-py3.5.egg/xgboost/training.py in _train_internal(params, dtrain, num_boost_round, evals, obj, feval, xgb_model, callbacks)
         97                                end_iteration=num_boost_round,
         98                                rank=rank,
    ---> 99                                evaluation_result_list=evaluation_result_list))
        100         except EarlyStopException:
        101             break

    /usr/local/lib/python3.5/site-packages/xgboost-0.6-py3.5.egg/xgboost/callback.py in callback(env)
        196     def callback(env):
        197         """internal function"""
    --> 198         score = env.evaluation_result_list[-1][1]
        199         if len(state) == 0:
        200             init(env)

    IndexError: list index out of range

В то время как

estimator.fit(X_train, y_train, early_stopping_rounds=20)

работает просто отлично.


person Georg Heiler    schedule 30.10.2016    source источник


Ответы (3)


Для раундов ранней остановки вы всегда должны указывать набор проверки, заданный аргументом eval_set. Вот как можно исправить ошибку в вашем коде.

pipeline.fit(X_train, y_train, clf__early_stopping_rounds=20, clf__eval_set=[(test_X, test_y)])
person Aashita Kesarwani    schedule 10.02.2018

Вот решение: https://www.kaggle.com/c/otto-group-product-classification-challenge/forums/t/13755/xgboost-early-stopping-and-other-issues Early_stooping_rounds и watchlist/eval_set нужно передать. К сожалению, это не работает для меня, так как для переменных в списке наблюдения потребуется шаг предварительной обработки, который применяется только в конвейере / мне нужно будет применить этот шаг вручную.

person Georg Heiler    schedule 30.10.2016
comment
Я думаю, было бы лучше, если бы вы не приняли этот ответ. Ваш вопрос в основном заключается в том, «как мне сделать [x] в конвейере sklearn», и ответ, на который вы ссылаетесь, не использует конвейер sklearn. и вы даже говорите в своем ответе, что согласились с тем, что это не работает для вас из-за этого. Если бы кто-то пришел с ответом, как это сделать в конвейере, было бы лучше, если бы это было принято. - person Max Power; 16.10.2017

Недавно я выполнил следующие шаги, чтобы использовать метрику eval и параметры eval_set для Xgboost.

1. создайте конвейер с этапами предварительной обработки/преобразования функций:

Это было сделано из конвейера, определенного ранее, который включает модель xgboost в качестве последнего шага.

pipeline_temp = pipeline.Pipeline(pipeline.cost_pipe.steps[:-1])  

2. Установите этот трубопровод

X_trans = pipeline_temp.fit_transform(X_train[FEATURES],y_train)

3. Создайте свой eval_set, применив преобразования к тестовому набору.

eval_set = [(X_trans, y_train), (pipeline_temp.transform(X_test), y_test)]

4. Добавьте шаг xgboost обратно в конвейер

 pipeline_temp.steps.append(pipeline.cost_pipe.steps[-1])

5. Установите новый конвейер, передав Параметры

pipeline_temp.fit(X_train[FEATURES], y_train,
             xgboost_model__eval_metric = ERROR_METRIC,
             xgboost_model__eval_set = eval_set)

6. Сохраните конвейер, если хотите.

joblib.dump(pipeline_temp, save_path)
person gdv820    schedule 16.04.2019
comment
Это кажется лучшим возможным решением среди всех опубликованных ответов. - person Harshith Thota; 23.04.2020
comment
Это не работает с версией 0.23.2 scikit-learn. - person ucsky; 16.12.2020
comment
Привет, @ucsky, можешь подсказать, какая конкретная часть приведенного выше кода не работает? - person gdv820; 22.01.2021