今日はグリッドサーチに関して簡単にまとめていきます。
グリッドサーチとは?
モデルを作成していく過程で必ず行うこととしてパラメータのチューニングがあります。
使用するモデルにより設定するパラメーターの数は異なりますが、最適解を探すために何度もパラメータをいじるのは時間がかかるため、自動で行うアルゴリズムが用意されています。
行うことは単純で最初にチェックするパラメータを設定して、イタレーションを回して全てのパラメータの組み合わせを確かめて最適解を記録するだけです。
単純なグリッドサーチ
ここでは例としてカーネル法を用いたSVMを例に実装を見ます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
from sklearn.svm import SVC X_train, X_test, y_train, y_test=train_test_split(iris.data, iris.target, random_state=0) best_score = 0 for gamma in [0.001, 0.01, 0.1, 1, 10, 100]: for C in [0.001, 0.01, 0.1, 1, 10, 100]: svm = SVC(gamma=gamma, C=C) svm.fit(X_train, y_train) score = svm.score(X_test, y_test) if score > best_score: best_score = score best_parameters = {'C': C, 'gamma': gamma} print("best score:{:.2f}".format(best_score)) print("best parameters:{}".format(best_parameters)) |
例ではgamma関数と正則パラメータCの値を組み合わせて最適スコアを記録していて、for文を2つ作成して都度スコアを算出しています。
訓練データをさらに分割する
ただ上で示した例はパラメータ最適化のためにテストデータを使用してしまっています。
テストデータを用いてパラメータの最適化を行ってしまうと汎化性能が落ちるため、モデルを作る時はデータセットを訓練データ、検証データ、テストデータに分割するのが一般的です。

訓練データと検証データを用いて最適なパラメータチューニングした後に、テストデータを用いて汎化性能(新しいデータに対してのモデルの性能)を評価することが可能になります。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
X_trainval, X_test, y_trainval, y_test = train_test_split(iris.data, iris.target, random_state=0) X_train, X_valid, y_train, y_valid = train_test_split(X_trainval, y_trainval, random_state=1) #訓練セットと検証セットにさらに分割を行っている best_score = 0 for gamma in [0.001, 0.01, 0.1, 1, 10, 100]: for C in [0.001, 0.01, 0.1, 1, 10, 100]: svm = SVC(gamma=gamma, C=C) svm.fit(X_train, y_train) score = svm.score(X_valid, y_valid) #検証データを用いてスコアを評価する if score > best_score: best_score = score best_parameters = {'C': C, 'gamma': gamma} |
交差検証を用いたグリッドサーチ
上で紹介した方法ではtrain_test_split関数を用いましたが、これはランダムにデータを分割するため分割されたデータがそれぞれ全く違う分布になる可能性があります。
そこで交差検証を用いてそれぞれのパラメータの組み合わせの際に別々の訓練・検証データを用いてチューニングするのが交差検証を用いたグリッドサーチとなります。
1 2 3 4 5 6 7 8 9 10 11 12 |
for gamma in [0.001, 0.01, 0.1, 1, 10, 100]: for C in [0.001, 0.01, 0.1, 1, 10, 100]: svm = SVC(gamma=gamma, C=C) score = cross_val_score(svm, X_trainval, y_trainval, cv=5) #訓練と検証セットを交差検証するためにcvで分割数を決めている score = np.mean(scores) #それぞれの分割(今回なら5分割)に対してスコアが出るので平均して評価を行う if score > best_score: best_score = score best_parameters = {'C': C, 'gamma': gamma} svm = SVC(**best_parameters) svm.fit(X_trainval, y_trainval) |
交差検証はグリッドサーチを用いたものとして言われることが多く、単に交差検証と言うだけでグリッドサーチのことも指していることが多いそうです。
scikit-learnではGridSearchCVクラスがあり短いコードで実装することができます。
GridSearchCVに最初にパラメータを辞書型で分割数をcvで渡してあげるだけでfitメソッドで訓練セットに対して交差検証を用いてパラメータを学習してくれて、scoreメソッドを用いることでテストセットを評価することができます。(上の一連の動作を全部やってくれます)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
param_grid = {"C": [0.001, 0.01, 0.1, 1, 10, 100], "gamma":[0.001, 0.01, 0.1, 1, 10, 100]} from sklearn.model_selection import GridSearchCV from sklearn.svm import SVC grid_search = GridSearchCV(SVC(), param_grid, cv=5) X_train, X_test, y_train, y_test = train_test_split(iris.data, iris.target, random_state=0) grid_search.fit(X_train, y_train) #訓練データにfitメソッドを用いるだけでパラメーターの組み合わせに対して交差検証が実行されru print("Test set score:{:.2f}".format(grid_search.score(X_test, y_test))) #テストセットに対しての評価の出力 |
この時のパラメータに関してはbest_params_属性に、交差検証精度はbest_score_属性に格納されています。
まとめ
簡単な実装でパラメータチューニングが可能ですが、複雑なモデルだと計算コストが大変なことになってしまうため、予測値を算出するためのグリッドサーチはあまり行われていないように思います。
kaggleでは評価関数の閾値を決める際に用いられているkernelがあったので部分的に使う場所はありそうですね。