機械学習とその他

機械学習したいマン

scikit-learnのgrid_search使ってみた

アドベントカレンダー11日目です。
adventar.org
今日はgrid_searchについて書いていきたいと思います。

grid_searchとは?

最適なパラメータの探索を行うメソッドです。
探索を行いたいパラメータをセットしておくと、最適なパラメータを見つけ出してくれます。何も考えずにSVMとか動かすと精度はあまり良い数値になりません。ただ、手動で探すのはとても大変なので、そこでgrid_searchを使います。

使い方

まず分類器を使う準備をしましょう。
必要なものをインポートします。

from sklearn.model_selection import GridSearchCV
from sklearn.svm import SVC
from sklearn.cross_validation import train_test_split
from sklearn.datasets import load_digits
from sklearn.metrics import classification_report
import numpy as np
import time

今回使うデータは、以前も使った数字のデータです。ついでに訓練データとテストデータに分けます。

digits = load_digits()
X_train, X_test, y_train, y_test = train_test_split(digits.data, digits.target)

SVMでgrid_searchを試して見る前に、何もパラメータをセットしないときの精度を確認しましょう。

clf = SVC()
clf.fit(X_train, y_train)

>>> 
SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0,
  decision_function_shape='ovr', degree=3, gamma='auto', kernel='rbf',
  max_iter=-1, probability=False, random_state=None, shrinking=True,
  tol=0.001, verbose=False)

学習は一瞬で終わります。精度を見てみましょう。
芳しくないですね。

np.mean(y_test == clf.predict(X_test))
>>> 0.45777777777777778

次にgrid_searchを試してみましょう。パラメータは以下のように記述することができます。順に試しながら最適なものを探索してくれます。GridSearchでは、Accでスコアを、交差検定を5回に設定しました。

params = {
    "C":np.arange(0.1,1,0.05),
    "kernel":["linear", "poly", "rbf", "sigmoid"],
    "gamma":np.arange(0.0001,0.1,0.05)
}
grid = GridSearchCV(clf, params,scoring="accuracy", cv=5)

あとはこれを実行するだけです。
まあまあ時間がかかることが予測されるので、ついでに時間を測ります。

start = time.time()
grid.fit(X_train, y_train)
print("time",time.time() - start)
>>> time 113.73304891586304

best_params_で指定したパラメータの中で、最適だったパラメータを見れます。ちょっと楽しいですね。

grid.best_params_
>>>  {'C': 0.10000000000000001, 'gamma': 0.050100000000000006, 'kernel': 'poly'}

best_score_で最もよかったパラメータの際の精度が見れます。こんな精度いいの?本当なのかなあ。

grid.best_score_
>>> 0.98069784706755758

best_estimatorで最もよかった際の学習のパラメータが表示できます。

grid.best_estimator_
>>>
SVC(C=0.10000000000000001, cache_size=200, class_weight=None, coef0=0.0,
  decision_function_shape='ovr', degree=3, gamma=0.050100000000000006,
  kernel='poly', max_iter=-1, probability=False, random_state=None,
  shrinking=True, tol=0.001, verbose=False)

せっかくなのでclassification reportも使いましょう。

pred = grid.predict(X_test)
print(classification_report(y_test, pred))

>>>
             precision    recall  f1-score   support

          0       1.00      1.00      1.00        39
          1       0.98      1.00      0.99        46
          2       1.00      1.00      1.00        43
          3       0.98      0.98      0.98        41
          4       1.00      1.00      1.00        55
          5       1.00      1.00      1.00        43
          6       1.00      1.00      1.00        46
          7       1.00      1.00      1.00        48
          8       0.97      0.97      0.97        39
          9       1.00      0.98      0.99        50

avg / total       0.99      0.99      0.99       450

これを見る限り、ちゃんと良いパラメータだったみたいですね。テストデータでもいい精度が出ています。

まとめ

grid_searchすごい、とても便利