機械学習で使われるモデルには多かれ少なかれ分析者が設定しなければならないパラメータがあります。機械学習で学習されない、機械学習の上にある(ハイパーな)パラメータなのでハイパーパラメータと呼ばれます。この調整をするとモデルの当てはまり(精度)が良くなったり悪くなったりするので、この調整はモデルを作成するときにかなり重要です。
ハイパーパラメータを調整する方法はシンプルです。だいたい良さそうな値を総当たりで入れてみてモデルを作り、その結果を比較して、良さそうな値の中からさらに良さそうな値を選び出すことで可能になります。
グリッドサーチ
とは言っても、ハイパーパラメータのチューニングを人間がやると悲劇になるので、この部分の計算を自動でやってもらいたいです。「だいたい良さそうな値を総当たりで入れてみてモデルを作り、その結果を比較して、良さそうな値の中からさらに良さそうな値を選び出すこと」をグリッドサーチと呼びます。
例えば2つのパラメータα,λα,λを持つ機械学習モデルを考えます。ααは値(0,0.5,1.0)(0,0.5,1.0)をとり、λλは値(0,0.2,0.4,0.6,0.8,1.0)(0,0.2,0.4,0.6,0.8,1.0)をとるとします。この時、グリッドサーチで探索するハイパーパラメータの範囲はα×λ=(0,0),(0,0.2),(0,0.4),…,(1.0,0.2),(1.0,0.4),…,(1.0,1.0)α×λ=(0,0),(0,0.2),(0,0.4),…,(1.0,0.2),(1.0,0.4),…,(1.0,1.0)の18通りです。この18通りのパラメータの組をモデルのパラメータとして代入し、モデルを動かします。そうして得られた18個のモデル出力を比較して、最も精度が高かった出力を与えたパラメータをモデルのハイパーパラメータとして採用します。
モデルが持つハイパーパラメータの数が3個、4個…と増えていってもやることは同じです。全ハイパーパラメータの全範囲の組を探索し、最適なハイパーパラメータの組を発見します。グリッドサーチの「グリッド」は格子とか焼き網とかそういう意味ですが、これは全ハイパーパラメータを軸として考えたとき、その交点に当たる組み合わせについて探索するというところから来ています。
本稿でやること
基本的に福島先生の『データ分析プロセス』の内容をトレースしています。以下では、上記本に記載がなかったelastic netのハイパーパラメータのグリッドサーチをC50パッケージに入っているchurnデータセットを題材に書いてみました。
glmnetにデータを読み込ませる際にはデータをmatrix型にしないといけないです。churnデータセットは親切にも訓練データとテストデータが分かれているのですが、敢えてガッチャンコして必要な処理をまとめて行っています。
データセットの準備
目的変数についてはベクトルにしたいのでunlistを使いました。説明変数は普通にmatrixにしました。
では、グリッドサーチをしていきます。
グリッドサーチ
グリグリしている感じが伝わってきたでしょうか。
glmnetパッケージのめんどくさいところはデータフレームをマトリックスにしないといけない点です。これ非常にめんどくさいです。この問題を解決しつつ、グリッドサーチをいい感じにしてくれるパッケージがcaretパッケージです。正確には、グリッドサーチをいい感じにしてくれつつ、この問題を解決してくれるのがcaretパッケージです。
ここから、いまグリッドサーチした内容をcaretパッケージで書き直します。このページを参考に、動くように微修正しました。
caretパッケージを使用した場合
まずはモデルの評価関数を作ります。これは上のコードでいうところの
##予測モデルの評価
res.eval <- res %>% mutate(Prec = tp/(tp + fp),
Rec = tp/(tp + fn),
Acc = (tp + tn)/(tp + fp + tn + fn))
にあたります。
続いて、caretの学習に指定できる引数を記載し、学習させます。
グリグリしている感はだいぶ薄くなったのですが、これでもしっかり予測できています。混同行列を表示すると
と出ます。
今後の展望
グリッドサーチの問題点は、「だいたい良さそうな値」の範囲を分析者が決めることです。そのため、その範囲に「本当の」良い値がない場合、指定した範囲内のベストまでしかわかりません。 ハイパーパラメータの範囲の指定を間違えるとモデルの精度を引き出すことはできません。かといって−∞から∞までグリッドサーチしても大変なことになります。
というわけで、次回は分析者が範囲指定をしないハイパーパラメータの調整方法であるベイズ最適化について書きたいと思います。