BayesSearchCV で XGBoost の early stopping 機能を使う
BayesSearchCV で XGBoost の early stopping 機能を使う
先日の BayesSearchCV イントロダクションの続きです。
XGBoost には early stopping という、
学習データとは別に、テストデータの Validation error が少なくとも <early_stopping_rounds> 回数連続して減少しないと、学習を停止する。
という機能があります。
early stopping は過学習を防ぐ学習方法として XGBoost だけでなく DeepNeuralNetwork でもよく使われる手法です。 端的にいうと、学習データだけではなくテストデータの Validation Error もモニタリングし、学習エラー(bias)と検証エラー(variance)のトレードオフが起きるところで学習を早期に終了させ、過学習を防ぐというものです。
注意すべきは、これは学習実行時のパラメータであり、いわゆるハイパーパラメータではないというところです。
というところで、sklearn では学習実行時のパラメータは fit_params という形で estimator.fit(X, y, **fit_params) の引数として学習実行時に指定されます。 (対してハイパーパラメータは GridSearch の search_param に引き渡されます)
BayesSearchCV でも学習実行時のパラメータを指定できますが、fit の引数ではなく、コンストラクタにて search_param と同様に引数で fit_params を与えます。
サンプルコードになります。
#!/usr/bin/env python # -*- coding: utf-8 -*- import sys import os import numpy as np import scipy as sp import pandas as pd from skopt import BayesSearchCV from skopt.space import Real, Categorical, Integer from sklearn.model_selection import train_test_split import xgboost as xgb # データセットを読み込み from sklearn.datasets import load_breast_cancer X, y = load_breast_cancer(return_X_y=True) X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.75, random_state=0) estimator = xgb.XGBClassifier( booster='gbtree', silent=True, objective='binary:logistic', base_score=0.5, eval_metric='auc', n_jobs=-1 ) # Early Stopping のパラメータ設定 # eval_set に モニタリングするテストデータ・セットを設定 # early_stopping_rounds 回数メトリクスが減少(増加)しなければ学習を早期終了する # eval_metric モニタリングする指標 - 最小化(RMSE, log loss, etc.) あるいは最大化(MAP, NDCG, AUC)は自動的に選ばれる fit_params = { 'early_stopping_rounds': 5, 'eval_metric':'error', 'verbose':1, 'eval_set':[[X_test, y_test]] } # パラメータ探索範囲設定 from skopt.space import Real, Categorical, Integer param_grid = { 'n_estimators': Integer(1, 4), 'learning_rate': Real(0.01, 0.5, 'log-uniform'), 'max_depth': Integer(0, 3) } clf = BayesSearchCV( estimator=estimator, search_spaces=param_grid, scoring='roc_auc', cv=3, n_jobs=-1, n_iter=10, verbose=1, refit=True, fit_params=fit_params # コンストラクタで設定すると estimator のフィッティング実行時に渡されます ) def status_print(optim_result): ''' ベイズ最適化のイテレーションで呼ばれるコールバック ''' results = pd.DataFrame(clf.cv_results_) new_params = results.tail(1).params.values[0] new_score = results.tail(1).mean_test_score print('Model #%d/%d : ROC-AUC(newest/best) = %.4f / %.4f' % ( len(results), clf.n_iter, new_score, clf.best_score_ )) # BayesSearchCV は sklearn の他の交差検証サーチ系クラス(RandomSearchCVなど)と同じAPIを持っています clf.fit(X, y, callback=status_print) print(pd.DataFrame(clf.cv_results_)) # 検証データのパフォーマンス print(clf.score(X_test, y_test))
以上、Tips でした。