【機械学習】xgboostでグリッドサーチ(GridSearchCV)
<xgboostでグリッドサーチ(GridSearchCV)>*1
※ 2020/04/09にQrunchで書いた記事を移行しました。
scikit-learnのGridSearchCVを利用して、グリッドサーチを行いました。 xgboostにはscikit-learnのWrapperが用意されているため、scikit-learnを使ったことがある人であれば、違和感なく使うことが出来ます。
使い方
データの読み込み等を除いたソースは以下の通りです。
import xgboost as xgb from sklearn.model_selection import StratifiedKFold, GridSearchCV # サーチするパラメータをセット params = {'eta': [0.01, 0.1, 1.0], 'gamma': [0, 0.1], 'n_estimators': [10, 100], 'max_depth':[2, 4], 'min_child_weigh': [1, 2], 'nthread': [2] } # クラス分類用のモデルを作成 model = xgb.XGBClassifier() # StratifiedKFoldでグリッドサーチ skf = StratifiedKFold(n_splits=5, shuffle=True, random_state=1) clf = GridSearchCV(estimator=model, param_grid=params, cv=skf, scoring="accuracy", n_jobs=1, verbose=3) clf.fit(train_x, train_y)
GridSearchCV()
がグリッドサーチのオブジェクトを作成している部分でclf.fit()
で実行します。
各パラメータ(引数)の意味は次の通りです。
パラメータ(引数) | 内容 |
---|---|
estimator | モデル |
param_griddict | サーチするパラメータ |
cv | クロスバリデーションの分割方法(※1) |
scoring | 評価指標("accuracy", "neg_mean_squared_error"等) (※2) |
n_jobs | 並行して実行するジョブの数。 |
verbose | 冗長性(サーチ中のメッセージ表示の種類) (※3) |
cv (※1)
設定できるパラメータは次の通りです。 - None: 自動で5 foldのクロスバリデーションになる - 整数値:指定した分割数のKFoldになる(分類の場合はStratified KFold) - CV splitter (KFoldオブジェクト等) - インデックスのリスト
scoring (※2)
公式に一覧が載っています。
3.3. Metrics and scoring: quantifying the quality of predictions — scikit-learn 0.22.2 documentation
verbose (※3)
公式に正確な情報はありませんが、 3はテスト毎にパラメータ・スコア・経過時間を表示、 2はテスト毎にパラメータ・経過時間を表示、 1はサーチの開始と終了、 0は表示しない。
全ソースコード
データはscikit-learnのdatasetより、load_breast_cancerを使用しました。
[1] データ読み込みと分割
from sklearn.datasets import load_breast_cancer from sklearn.model_selection import train_test_split # 乳がんの診断結果データ cancer = load_breast_cancer() cancer_data = pd.DataFrame(cancer.data, columns=cancer.feature_names) cancer_target = pd.Series(cancer.target) # 80%を学習用、20%をテスト用に使用する。 train_x, test_x, train_y, test_y = \ train_test_split(cancer_data, cancer_target, test_size=0.2, shuffle=True)
[2] グリッドサーチ
import xgboost as xgb from sklearn.model_selection import StratifiedKFold, GridSearchCV # サーチするパラメータをセット params = {'eta': [0.01, 0.1, 1.0], 'gamma': [0, 0.1], 'n_estimators': [10, 100], 'max_depth':[2, 4], 'min_child_weigh': [1, 2], 'nthread': [2] } # クラス分類用のモデルを作成 model = xgb.XGBClassifier() # StratifiedKFoldでグリッドサーチ skf = StratifiedKFold(n_splits=5, shuffle=True, random_state=1) clf = GridSearchCV(estimator=model, param_grid=params, cv=skf, scoring="accuracy", n_jobs=1, verbose=3) clf.fit(train_x, train_y)
[3] グリッドサーチの結果を表示
import pandas as pd # 各パラメータのスコア・標準偏差をDataFrame化 means = clf.cv_results_['mean_test_score'] stds = clf.cv_results_['std_test_score'] params = clf.cv_results_['params'] df = pd.DataFrame(data=zip(means, stds, params), columns=['mean', 'std', 'params']) # スコアの降順に並び替え df = df.sort_values('std', ascending=True) df = df.sort_values('mean', ascending=False) # スコア・標準偏差・パラメータを表示 for index, row in df.iterrows(): print("score: %.3f +/-%.4f, params: %r" % (row['mean'], row['std']*2, row['params'])) # score: 0.963 +/-0.0431, params: {'eta': 1.0, 'gamma': 0, 'max_depth': 4, 'min_child_weigh': 1, 'n_estimators': 100, 'nthread': 2} # score: 0.963 +/-0.0431, params: {'eta': 1.0, 'gamma': 0, 'max_depth': 4, 'min_child_weigh': 2, 'n_estimators': 100, 'nthread': 2} # score: 0.960 +/-0.0531, params: {'eta': 0.1, 'gamma': 0, 'max_depth': 4, 'min_child_weigh': 2, 'n_estimators': 100, 'nthread': 2} # score: 0.960 +/-0.0531, params: {'eta': 0.1, 'gamma': 0, 'max_depth': 4, 'min_child_weigh': 1, 'n_estimators': 100, 'nthread': 2} # score: 0.956 +/-0.0501, params: {'eta': 0.1, 'gamma': 0.1, 'max_depth': 4, 'min_child_weigh': 2, 'n_estimators': 100, 'nthread': 2} # 〜〜〜 (以下省略) 〜〜〜
[4] 最良のパラメータを取得
print("Best score: %.4f" % (clf.best_score_)) print(clf.best_params_) # Best score: 0.9626 # {'eta': 1.0, 'gamma': 0, 'max_depth': 4, 'min_child_weigh': 1, 'n_estimators': 100, 'nthread': 2} model = clf.best_estimator_ pred = model.predict(test_x) score = accuracy_score(test_y, pred) print('score:{0:.4f}'.format(score)) # Score:0.9561
参考資料
sklearn.model_selection.GridSearchCV — scikit-learn 0.22.2 documentation
*1:Darwin LaganzonによるPixabayからの画像