[Pythonコードあり] サポートベクター回帰(Support Vector Regression, SVR)のハイパーパラメータを高速に最適化する方法

サポートベクター回帰 (Support Vector Regression, SVR) は、こちら:サポートベクター回帰(Support Vector Regression, SVR)~サンプル数10000以下ならこれを使うべし!~ にあるように、とても強力な手法です。推定性能の高い回帰モデルを構築することができます。カーネルトリックにより簡単に非線形のモデルに拡張できます。カーネル関数としては、実用上はガウシアンカーネル (RBFカーネル) 一択でしょう。

SVRのハイパーパラメータを決めるのに時間がかかる

SVRの弱点をあげるとすれば、SVRモデルを完成させるまでに時間がかかること、です。特に、SVRにはモデルを構築する前に決めておかなければならないパラメータ (ハイパーパラメータ) が3つもあります。 3つのハイパーパラメータの候補は下の通りです。

  • C の候補: 2-5, 2-4, …, 29, 210 (16通り)
  • ε (イプシロン) の候補: 2-10, 2-9, …, 2-1, 20 (11通り)
  • γ (ガンマ) の候補: 2-20, 2-19, …, 29, 210 (31通り)

基本的には、グリッドサーチを行い、クロスバリデーションの推定結果が最もよくなるハイパーパラメータを選択します。つまり、C・ε・γ のすべての組み合わせ (16×11×31 = 5456 通り) でクロスバリデーションを行い、クロスバリデーション推定値で計算された r2 の値が最も大きいC・ε・γ の組み合わせを選ぶわけです。クロスバリデーションと r2 についてはこちらをご覧ください。

そうです、5456回もクロスバリデーションをしなくてはいけないのです!時間もかかるわけです。

そこで、クロスバリデーションの回数を劇的に減らして、ハイパーパラメータの最適化にかかる時間を大幅に短縮化する方法を紹介します。

ちなみに、Pythonコード・プログラムはこちらから入手できます。

GitHub - hkaneko1985/fastoptsvrhyperparams: Fast optimization of SVR hyperparameters with Gaussian kernel
Fast optimization of SVR hyperparameters with Gaussian kernel - GitHub - hkaneko1985/fastoptsvrhyperparams: Fast optimiz...

 

[New] こちらの DCEKit で、便利に SVR の高速ハイパーパラメータ最適化をご利用いただけます。

DCEKit (Data Chemical Engineering toolKit) を PyPI にリリース!
これまで化学データ・化学工学データのデータ解析に役立つツールや金子研で開発された手法に関する Python コードを Github にて公開してきました。このたびは、これらのツール・手法 (の一部) に加えて、新たな機能を追加して、DCEK...

 

SVRのハイパーパラメータの高速最適化

最初に着目するのは、ガウシアンカーネルのパラメータ γ です。γ だけ先に決めます。そもそも、目的変数y を説明するためには、説明変数 X はばらついている必要があります。つまり、グラム行列 (各サンプル間のカーネル関数の値) のばらつきが大きいと、よいわけです。そこで、γ の候補の中から、グラム行列の分散が最大になるものを選びます。

次に、C について、こちらの論文には、yの平均+標準偏差×3の絶対値か、yの平均ー標準偏差×3の絶対値の大きい方の値がCとして適しているとしています。つまり、yが標準化 (オートスケーリング) されているとき、C = 3 がよいというわけです。

そこで、C = 3、γ をグラム行列の分散が最大になるように選んだ値と固定して、ε だけクロスバリデーションで最適化します。ε を変えて11回クロスバリデーションを行い、その中で最も結果のよい ε を選ぶわけです。これを ε の最適値とします。

そして、ε を上の最適値、γ をグラム行列の分散が最大になるように選んだ値と固定して、C だけクロスバリデーションで最適化します。C を変えて16回クロスバリデーションを行い、その中で最も結果のよい C を選ぶわけです。これを C の最適値とします。

最後に、γ をクロスバリデーションで最適化します。実は、γ は先ほどのグラム行列の分散が最大になるように選んだ値を最適値としてもよいのですが、もしクロスバリデーションで最適化したい場合は、C・ε を上の最適値として固定して、γ だけクロスバリデーションで最適化します。γ を変えて31回クロスバリデーションを行い、その中で最も結果のよい γ を選ぶわけです。これを γ の最適値とします。31回もクロスバリデーションしたくない!という方は、グラム行列の分散が最大になるように選んだ値をγ の最適値としてもよいです。

この方法により、クロスバリデーションの回数を、5456回 → 58回 (=11+16+31) に減らせます。

わたしのパソコンでは、説明変数の数が100、サンプルの数が1000のときに、C・ε・γ の最適化が 90秒程度で終了しました。この最適化にかかる時間は、こちらのPythonコードで確認することができます。

ちなみに、γ をグラム行列の分散が最大になるように選ぶ、というのは、support vector machine (SVM) や one-class support vector machine (OCSVM) でも活用できます

以上です。今回の手法は、こちらの論文に記載されている方法です。

質問やコメントなどありましたら、twitter, facebook, メールなどでご連絡いただけるとうれしいです。

タイトルとURLをコピーしました