スパゲッティ生産所

コードの走り書きとかメモとか日常のこととか

JavaでSVM-SMOを実装する

かなり久しぶりにブログを書きます。

大学の課題で、「SVMを使って何かやってみろ」というものが出されたのでSVM-SMOを自分で実装してみることにしました。

SVMについての説明はもう書きませんので、

kivantium.hateblo.jp

 

とか

 

パターン認識と機械学習 下 (ベイズ理論による統計的予測)

パターン認識と機械学習 下 (ベイズ理論による統計的予測)

 

 の7章とかを参考にして下さい。

要するに

SVMは「各データに対応するαiという値があって、それをある制約の元で最適化する」という問題に落とし込めて、この最適化する方法がSMOという事になります。

SMOについてはこのスライド

www.slideshare.net

を元に実装しました。

データにはIrisデータセットを用いて、実装が正しいのかの確認をします。このデータセットは線形分離可能なデータセットになっています。

今回は以下の様な仕様にしました。

・使用するカーネル関数には線形カーネルを選びました。

・今回の実装では、Irisデータセットの"Petal.Width"をx軸、"Petal.Length"をy軸にとって学習させるのですが、x軸とy軸でrangeが違うのがなんか気持ち悪かったので、データの最大値で各値を割ってrangeが0~1になるようにしています。

・α更新時に選ぶ2点目は1点目以外からランダムで選ぶようにしています。

・α更新時にaiNewやajNewが不正な値になった場合、また更新する値の変化量が微小になった場合更新を行いません。

・ある一定回数更新が行われなかった時点で更新作業を終了します。

・パラメータCにはInteger.MAX_VALUEを入れてます。

この仕様で実装を行い、学習させた結果が以下の様なものです

https://pbs.twimg.com/tweet_video/Ca3z8ijUUAAmbnq.mp4

 思ったよりちゃんと動いているっぽいのでうまく実装できているようです。

今回のSVMソースコード

github.com

 

においてあります。結果のグラフ画像なんかを出力するものが混ざっていますがまあ気にしないでください。

 

 

次は非線形分離なデータを学習できるようにしてみる予定。