はじめに
グリッドサーチを行うにあたり細かい制御を行う必要があり、パラメータの組み合わせ生成等が面倒だったため調べたときのメモ
環境
- Windows 10
- Python 3.6
- scikit-learn 0.20
やり方
グリッドサーチをやる場合、各パラメータの探索範囲をDictで定義し、それをGridSearchCVの引数に与えると思う。同じ形のDictをインプットとして、グリッドサーチを自力でやろうとした場合、Dictからモデルのset_paramsの引数に与えられる形式で、全パラメータの組み合わせを生成する必要があるが、この実装がかなり面倒くさい。
scikit-learnのGridSearchCVクラスのソース等をいろいろ調べたところ、ParameterGridクラスを用いると簡単にできることが分かった。
百聞は一見に如かず、とりあえずソースを見てみよう。まずは必要なものをインポートする。
import pandas as pd
import numpy as np
from sklearn.model_selection import ParameterGrid
from sklearn.model_selection import KFold
from sklearn.metrics import matthews_corrcoef
from sklearn.metrics import roc_auc_score
from sklearn.ensemble import ExtraTreesClassifier
from sklearn import metrics
次にモデルおよびGridSearh用のDictの定義。そして、ParameterGridを用いてDictに対する全パラメータの組み合わせのリストを生成。
clf = ExtraTreesClassifier()
param_grid = {
"class_weight" : ["balanced", "balanced_subsample", None],
"max_features" : ["sqrt", 0.3, 0.6, 0.9],
"n_estimators" : [10]
}
param_dicts = list(ParameterGrid(param_grid))
そして、全パラメータの組み合わせのリスト毎にモデルの評価を実施することで、自前のグリッドサーチを実施。
auc_all = []
for i, param_dict in enumerate(param_dicts):
auc_cvs = []
for train_index, test_index in KFold(n_splits=10, random_state=42, shuffle=True).split(X):
X_train, X_test = X[train_index], X[test_index]
y_train, y_test = y[train_index], y[test_index]
clf.set_params(**param_dict)
clf.fit(X_train, y_train)
y_predict = clf.predict(X_test)
y_predict_score = clf.predict_proba(X_test)[:, 1]
auc_cvs.append(metrics.roc_auc_score(y_test, y_predict_score))
auc_all.append(np.array(auc_cvs).mean())
print(auc_all)
decision threshold等を変化させて指標を最適化するなど、より細かいグリッドサーチを行う場合は、こんな感じグリッドサーチを実装すればでできますよ、という話でした。