「機械学習のパラメータをベイズ最適化でチューニング」をRで超簡単に書けるパッケージを作った
0. 要約
機械学習のハイパーパラメータをベイズ最適化でチューニングするのは既存パッケージの組み合わせで頑張ればできたのですが、頑張らなくても簡単に書けるパッケージを作りました。
これにより、例えば iris データをXGboostの3-foldクロスバリデーション、エラー率評価でフィッティングさせたければ以下のように書くことでハイパーパラメーターである eta, max_depth, nround, subsample, bytree をベイズ最適化でチューニングしてくれます。
res0 <- xgb_cv_opt(data = iris, label = Species, objectfun = "multi:softmax", evalmetric = "merror", classes = 3, n_folds = 3)
データセット名、ラベルの列名、XGboostのモデルを組むのに必要なこと、何回クロスバリデーションするかを書けば勝手にやってくれます。
ベイズ最適化そのものについては、hoxo_mさんの資料が分かりやすいと思います。
1. はじめに
きっかけ
そもそもこのパッケージを作ろうと思ったきっかけは六本木データサイエンティストの方のブログ記事でした。
{rBayesianOptimization}パッケージによるベイズ最適化で機械学習パラメータチューニングをお手軽に - 六本木で働くデータサイエンティストのブログ
{rBayesianOptimization} パッケージと機械学習の諸手法のパッケージ({e1071} や {xgboost}) を組み合わせるとパラメータチューニングをベイズ最適化でお手軽にできるよって話なんですが、いくらお手軽にできるといっても実際には以下の手順が必要でした。
なかなか面倒です。というのも、1 ではパッケージごとにデータの変形の仕方が違ったりします。例えば、 e1071::svm()
にデータを流しこむにはラベルの列を factor 型にしておかなければならないし、 {xgboost} パッケージに流すには Matrix::sparse.model.matrix()
関数や xgboost::xgb.DMatrix()
関数で適切な形に変形してやらなければなりません。
また、いくらお手軽にできるとはいえ現実のデータでやると局所解に引っかかるなどの理由で最適化がうまくいかないことがあります。この場合、 rBayesianOptimization::BayesianOptimization()
関数の中で kappa
を調節したり、獲得関数の最大化戦略の選択など、ベイズ最適化自体にもチューニングのような作業が必要です。
そのたびにあちこち変えながらやっているとエラーになったり、コードの見通しが悪くなるといった問題がありました。
そこで、これを一つの関数にしてしまいたかったというのがパッケージ作成の動機です。
そして、パッケージを作った
パッケージの原型ができたのは実は2017年3月頃で、Tokyo.RのLTなどでちょろっと話はしていたんですがいかんせん機能がしょぼかったのを幾つか改良して現在のバージョン(0.3.3)になっています。
あと、格好をつけたくてヘキサゴンのバッジマークも作ってしまいました笑
2. インストール
CRANに上げたので、 install.packages()
でインストールできます。
install.packages("MlBayesOpt")
開発版はGitHubからインストールできます。
# install.packages("githubinstall") githubinstall::githubinstall("MlBayesOpt") # install.packages("devtools") devtools::install_github("ymattu/MlBayesOpt")
3. 使い方
手法とか
現在対応してるのは以下の機械学習手法です。
- SVM
- ホールド・アウト(
svm_opt()
) - クロスバリデーション (
svm_cv_opt()
)
- ホールド・アウト(
- Random Forest ホールド・アウトのみ (
rf_opt()
) - XGboost
- ホールド・アウト(
xgb_opt()
) - クロスバリデーション (
xgb_cv_opt()
)
- ホールド・アウト(
内部的にはそれぞれ、 {e1071}, {ranger}, {xgboost} を使っているため、これらで使われている引数のうち主なものは使えます。SVMではカーネルの選択もできます。
評価について
基本的には Test Accuracy を返すのですが、XGboostのクロスバリデーションだけは evalmetric
引数で指定したものを返します。さらに、ここで error
, merror
, logloss
, mlogloss
などモデルとしては最小化したいものを選んだ場合はマイナスの値が返ってきます。たとえば merror
でエラー5%であれば、 -0.05
が返ってきます。
細かいことは、パッケージのヘルプを御覧ください。
流し込むデータについて
各モデルの計算では、ラベルを表す列以外全部の変数を学習に使うことになってるので、 data
引数で指定したデータはラベルの列と特徴量だけの状態にしてください。当然、ここまでのデータは自分で作る必要があります。
そこさえできてしまえば、ラベルの列の型が factor 型だとかはあまり気にしなくても関数がよしなに調整してくれます。
細かいチューニングについて
パラメータの探索範囲を変えたい
デフォルトでよく使われる範囲を指定するようになってますが、探索範囲を変えたいときは関数の中で指定してやればOKです。たとえば、RBFカーネルのSVMで gamma
と cost
の探索範囲を変えたいときは以下のように書きます。
res0 <- svm_cv_opt(data = iris, label = Species, n_folds = 3, gamma_range = c(10^(-2), 1), cost_range = c(10^(-2), 1), init_points = 10, n_iter = 1)
ベイズ最適化の引数を変えたい
変えるとしたら、 kappa
, acq
(最大化戦略の方法)あたりでしょうか。
res0 <- svm_cv_opt(data = iris, label = Species, n_folds = 3, init_points = 10, n_iter = 1, acq = "ucb", kappa = 3)
4. 余談
実はCRANにアクセプトされるのに結構苦労しました。その話は後日...