Почему XGBoost не показывает правильные значения best_iteration и ntree_limit? - PullRequest
2 голосов
/ 16 января 2020

Я создаю двоичную классификационную модель с использованием XGBoostClassifier, но у меня возникают некоторые проблемы с получением правильного значения best_iteration и ntree_limit.

Приведенный ниже код является моей собственной метрикой оценки c :

def xgb_f1(y, t):
    t = t.get_label()
    y_bin = [1. if y_cont > 0.5 else 0. for y_cont in y]
    return 'f1', f1_score(t, y_bin, average='macro')

Вот как я создаю и подгоняю Классификатор:

classifier = xgb.XGBClassifier(n_estimators=10000)
classifier.fit(X_train, y_train, 
               eval_metric=xgb_f1, 
               eval_set=[(X_test, y_test)], 
               verbose=True)

Вот некоторые результаты, которые XGBoost показывает мне во время подгонки:

[1007]  validation_0-error:0.181395 validation_0-f1:0.731411
[1355]  validation_0-error:0.183721 validation_0-f1:0.735139
[1396]  validation_0-error:0.183721 validation_0-f1:0.736116
[1426]  validation_0-error:0.182558 validation_0-f1:0.737302
[3568]  validation_0-error:0.186047 validation_0-f1:0.737557
[3791]  validation_0-error:0.184884 validation_0-f1:0.7378
[9999]  validation_0-error:0.210465 validation_0-f1:0.708715

И как Вы можете видеть, что лучшая итерация - это номер 3791 из-за наибольшего значения f1, но когда я вызываю classifier.get_booster().best_iteration, это показывает, что номер 9999 (последняя итерация) является лучшим, но это не так. И когда я звоню classifier.get_booster().best_ntree_limit, он говорит мне, что лучший лимит - 10000, но я так не думаю, потому что он дает мне более низкий показатель f1, чем более низкие итерации.

1 Ответ

0 голосов
/ 28 января 2020

Я думаю, вам следует использовать параметр early_stopping_rounds. Однако вы все равно получите модель последней итерации. Проверьте xgboost документы для метода xgboost.XGBRegressior.fit(), в начале early_stopping_rounds говорится:

Метод возвращает модель из последней итерации (не самой лучшей) .

Обходной путь должен был бы создать новый классификатор после первого раунда обучения и установить n_estimators так, чтобы он останавливался именно там, где он делал ранее.

classifier = xgb.XGBClassifier(
    n_estimators=10000,
    early_stopping_rounds=50
    )
classifier.fit(X_train, y_train, 
               eval_metric=xgb_f1, 
               eval_set=[(X_test, y_test)], 
               verbose=True)
classifier_new = xgb.XGBClassifier(
    n_estimators=classifier.best_iteration
    )
classifier_new.fit(X_train, y_train,
                   eval_metric=xgb_f1, 
                   eval_set=[(X_test, y_test)], 
                   verbose=True)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...