81
84

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

scikit-learnのGridSearchCVでハイパーパラメータ探索

Last updated at Posted at 2018-11-20

###前置き###
scikit-learnにはハイパーパラメータ探索用のGridSearchCVがあって、Pythonのディクショナリでパラメータの探索リストを渡すと全部試してスコアを返してくれる便利なヤツだ。

今回はDeepLearningではないけど、使い方が分からないという声を聞くので、このGridSearchCVの使い方をまとめておこうと思います。
ちなみにKerasだとscikit-learnのAPIもあるので、Kerasで作ったモデルをこのGridSearchCVでパラメータ探索できる。
(やったことないけど・・・)

####GridSearchCV####

sklearn.model_selection.GridSearchCV

###ソースコード全文###
今回は最初にコード全文を載せておく。説明は後程。
データはirisデータセットでサポートベクターマシンを使って分類する。

### ライブラリのインポート
import numpy as np
import pandas as pd
from sklearn.datasets import load_iris
from sklearn.svm import SVC
from sklearn.model_selection import GridSearchCV, train_test_split
from sklearn.metrics import confusion_matrix

### 探索するパラメータ空間
def param():
  ret = {
      'C':[1, 10, 100],
      'kernel':['rbf', 'linear', 'poly'],
      'degree':np.arange(1, 6, 1),
      'gamma':np.linspace(0.01, 1.0, 50)
  }
  return ret

if __name__ == '__main__':
  # データの準備
  x = load_iris().data
  y = load_iris().target

  # 25%分のデータを除けておく
  x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.25)

  # GridSearchCVのインスタンスを作成&学習&スコア記録
  gscv = GridSearchCV(SVC(), param(), cv=4, verbose=2)
  gscv.fit(x_train, y_train)

  # スコアの一覧を取得
  gs_result = pd.DataFrame.from_dict(gscv.cv_results_)
  gs_result.to_csv('gs_result.csv')

  # 最高性能のモデルを取得し、テストデータを分類
  best = gscv.best_estimator_
  pred = best.predict(x_test)

  # 混同行列を出力
  print(confusion_matrix(y_test, pred))

####解説####
#####ライブラリインポート#####

### ライブラリのインポート
import numpy as np
import pandas as pd
from sklearn.datasets import load_iris
from sklearn.svm import SVC
from sklearn.model_selection import GridSearchCV, train_test_split
from sklearn.metrics import confusion_matrix

探索パラメータが数値の時にndarrayでやると楽なのでnumpy、スコア一覧をDataFrameにしてしまえばCSVなどで吐き出すのが楽なのでpandas。
irisデータセットと分類用のサポートベクターマシン(SVC)、データをランダムに分割するtrain_test_split、最後の評価用の混同行列を出力するconfusion_matrixをインポートします。

#####探索するパラメータ空間#####

### 探索するパラメータ空間
def param():
  ret = {
      'C':[1, 10, 100],
      'kernel':['rbf', 'linear', 'poly'],
      'degree':np.arange(1, 6, 1),
      'gamma':np.linspace(0.01, 1.0, 50)
  }
  return ret

メインのソースが綺麗になるので、パラメータ空間は関数で作る。
ディクショナリで渡す必要がある。
キーがサポートベクターマシンのパラメータ名で値が探索する値のリスト
(というか多分iteratorなら何でもOKなんだと思う)

値の最大・最小を指定しておけばいいわけではないので、ここではnumpyが活躍する。
色々あるけど、arangelinspaceを覚えておけば大体OKと思う。
どちらも始点と終点を入れ替えると昇順・降順が入れ替わる。
######Tips######

 # 1以上6未満で1刻みのarrayを作る
 a = np.arange(1, 6, 1)
 >> [1 2 3 4 5]

 # 0.0以上1.0以下を10分割したarrayを作る
 a = np.linspace(0.0, 1.0, 10)
 >> [0.         0.11111111 0.22222222 0.33333333 0.44444444 0.55555556 0.66666667 0.77777778 0.88888889 1.        ]

#####データの準備#####

  # データの準備
  x = load_iris().data
  y = load_iris().target

  # 25%分のデータを除けておく
  x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.25)

説明変数となるx、目的変数となるyを75%と25%にランダムに分ける。
ここでの25%は最後の評価用で、75%を使ってGridSearchCVによるパラメータ探索を行う。

#####GridSearchCVのインスタンスを作成&学習&スコア記録#####

  # GridSearchCVのインスタンスを作成&学習&スコア記録
  gscv = GridSearchCV(SVC(), param(), cv=4, verbose=2)
  gscv.fit(x_train, y_train)

GridSearchCVの第1引数には推定器のインスタンスを渡す。
探索せずに固定したいパラメータがあれば、ここで指定しておけば常にそのパラメータが使われる。
第2引数にはパラメータの探索空間(ディクショナリ)を渡す。ここでは先ほどの関数を渡す。

ここでのパラメータcvは交差検証の手法を指定する。
この例のようにIntで指定するとK-Fold法のn分割のnを指定することになる。 ※省略すると3になる。
Int型以外ではscikit-learnのデータ分割(ShuffleSplit等)を指定することもできる。
verboseは進捗を見たい場合は1や2を指定しておくと標準出力で進捗が見れるけど、プログレスバーみたいな上等な物は出ない。

fitにデータを放り込むと探索が始まる。設定した探索空間次第だが、長くなる。が、自動である。

#####スコアの一覧を取得#####

  # スコアの一覧を取得
  gs_result = pd.DataFrame.from_dict(gscv.cv_results_)
  gs_result.to_csv('gs_result.csv')

ディクショナリで返ってくるので、そのままpandasのDataFrameに入れてCSV出力する。
・・・というのも大抵の場合、大きすぎてEXCELなどじゃないと見れたものじゃないからだ。
キーは全部英語だけど、意味が分からない物はほとんどないと思うが、一番分かりやすいのはrank_test_score
この列をキーに昇順に並べ替えた時、一番上に来るものが未学習データのスコアが一番良かったパラメータの適用例。

#####最高性能のモデルを取得し、テストデータを分類#####

  # 最高性能のモデルを取得し、テストデータを分類
  best = gscv.best_estimator_
  pred = best.predict(x_test)

  # 混同行列を出力
  print(confusion_matrix(y_test, pred))

GridSearchCVのインスタンスからbest_estimator_にアクセスすると最高性能だったパラメータを適用した学習済みのインスタンスを取り出せる。
このまま、最初に除けておいた25%のデータを分類させ、混同行列を出力すると・・・・

output
[[14  0  0]
 [ 0 12  1]
 [ 0  0 11]]

1つだけ間違ってしまうようだが、上々の性能だ。

###最後に###
GridSearchCVの必要最小限の使い方を解説しました。
カスタマイズ性が高いので、これ以上は色々試されると良いと思います。

例えば、評価方法はscikit-learnの場合、回帰問題だと決定係数$R^2$、分類問題だと正解率が適用されて、いずれも高い方が良いように扱われますが、回帰問題で正負反転した平均二乗誤差などを使うこともできます。

81
84
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
81
84

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?