Является ли документация по xgboost неправильной?(ранние остановки и лучшие и последние итерации) - PullRequest
0 голосов
/ 26 ноября 2018

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

В документации по xgboost можно увидетьв разделе scikit узнать API ( ссылка ), что, когда подгонка останавливается из-за параметра ранних остановок:

Активирует раннюю остановку.Ошибка проверки должна уменьшаться, по крайней мере, каждый раунд "early_stopping_rounds", чтобы продолжить обучение.Требуется хотя бы один предмет в уловках.Если есть более одного, будет использовать последний.Возвращает модель из последней итерации (не самой лучшей).

Повторяя это, кажется, что возвращаемая модель, в данном случае, не лучшая, а последняя.По его словам, для получения доступа к лучшему при прогнозировании можно вызвать прогноз с использованием параметра ntree_limit с bst.best_ntree_limit, заданным в конце подбора.

В этом смысле он должен работать так жетаким образом, как поезд xgboost, так как подгонка scikitlearn api, кажется, только вложение поезда и других.

Это хитро обсуждается здесь обсуждение переполнения стека или здесь другое обсуждение

Но когда я попытался решить эту проблему и проверить, как она работает с моими данными, я не нашел поведения, которое, по моему мнению, мне следовало бы иметь.На самом деле поведение, с которым я столкнулся, совсем не было тем, что описано в этих обсуждениях и документации.

Я называю это подходом так:

reg = xgb.XGBRegressor (n_jobs = 6, n_estimators =100, max_depth = 5)

reg.fit(
   X_train, 
   y_train, 
   eval_metric='rmse',    
   eval_set=[(X_train, y_train), (X_valid, y_valid)],
   verbose=True,
   early_stopping_rounds = 6)

и вот что я получаю в итоге:

[71]    validation_0-rmse:1.70071   validation_1-rmse:1.9382
[72]    validation_0-rmse:1.69806   validation_1-rmse:1.93825
[73]    validation_0-rmse:1.69732   validation_1-rmse:1.93803
Stopping. Best iteration:
[67]    validation_0-rmse:1.70768   validation_1-rmse:1.93734

и когда я проверяю значения проверки, которые я использовал:

y_pred_valid = reg.predict(X_valid)
y_pred_valid_df = pd.DataFrame(y_pred_valid)
sqrt(mse(y_valid, y_pred_valid_df[0]))

Я получаю

1.9373418403889535

Если при подборе вернулась последняя итерация вместо лучшей, она должна была дать rmse около 1,93803, но это далосреднеквадратичное значение 1.93734, точно лучший результат.

Я проверил еще раз двумя способами: [Редактировать] Я отредактировал приведенный ниже код в соответствии с ответом @Eran Moshe

y_pred_valid = reg.predict(X_valid, ntree_limit=reg.best_ntree_limit)
y_pred_valid_df = pd.DataFrame(y_pred_valid)
sqrt(mse(y_valid, y_pred_valid_df[0]))

1.9373418403889535

и даже если я назову «подгонку» (зная, что самый лучший иттер - 67-е) только с 68 оценщиками, так что я уверен, что последний является лучшим:

reg = xgb.XGBRegressor(n_jobs=6, n_estimators = 68, max_depth= 5)

reg.fit(
   X_train, 
   y_train, 
   eval_metric='rmse',    
   eval_set=[(X_train, y_train), (X_valid, y_valid)],
   verbose=True,
   early_stopping_rounds = 6)

результат тот же:

1.9373418403889535

Таким образом, это, кажется, приводит к мысли, что, в отличие от документации и этих многочисленных обсуждений, скажем, соответствие xgboost, когда оно останавливается параметром ранней остановки раунда, дает лучший результат, а не последний.

Я не прав, если да, то где и как вы объясните поведение, с которым я встречался?

Спасибо за внимание

Ответы [ 3 ]

0 голосов
/ 01 декабря 2018

Я думаю, это не так, но противоречиво .

Документация по методу predict верна (например, см. здесь ).Чтобы быть на 100% уверенным, лучше заглянуть в код: xgb github , поэтому predict ведет себя так, как указано в его документации, но документация fit устарела.Пожалуйста, опубликуйте это как проблему на github XGB, и они либо исправят документы, либо вы станете участником XGB:)

0 голосов
/ 03 декабря 2018

Чтобы быть более точным, и, соответственно, @Mykhailo Lisovyi, документация в разделе API scikit-learn довольно непоследовательна, так как параграф соответствия говорит о том, что при ранних остановках раундов последняя итерация возвращается не самой лучшей, ноабзац предиката говорит, что когда предикат вызывается без указания ntree_limit, то ntree_limit равен best_ntree_limit.

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

Я опубликовал проблему на github xgboost... подождите и посмотрите

[ОБНОВЛЕНИЕ]: запрос на прием был принят: ссылка

0 голосов
/ 27 ноября 2018

У вас там ошибка кода.

Обратите внимание, как

reg.predict(X_valid, ntree_limit=reg.best_ntree_limit)

должно быть

y_pred_valid = reg.predict(X_valid, ntree_limit=reg.best_ntree_limit)

Так что на самом деле вы делаете то же самое сравнение, когдавычисление

sqrt(mse(y_valid, y_pred_valid_df[0]))

Xgboost работает так же, как вы прочитали.early_stopping_round = x будет тренироваться, пока не улучшится в течение x последовательных раундов.

И при прогнозировании с помощью ntree_limit=y он будет использовать ТОЛЬКО первые y ускорители.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...