ところでサポートベクターマシンって何なの?

銀河高原ビールの店

最近、機械学習とか、そのアルゴリズムのひとつであるサポートベクターマシンとかやってるわけですが、そもそも機械学習ってなんなんでしょか?
機械学習ってのは、なんとなく与えられた点の分類から、新たに与えられた点の分類を推測するのですが、ようするに、点が与えられたときにそこから分類の領域を推測しておいて、新たな点がきたときにはどの領域に入るかを判別するのです。


ニューラルネットワークは、名前にニューロンとかついてて、とてもステキな響きがするのですが、あれは関数のあてはめを行っているのです。そうやって関数をあてはめることで、領域の境界面を求めます。
NN法は、学習とかせず、一番近いデータが同じ分類になるはずという戦略でやってます。
サポートベクターマシンも考え方としてはNN法と同じで、新しい点がやってくると、学習したそれぞれの点までの近さを計算して、一番ちかい分類を求めます。そのため、学習データが増えると、学習に時間がかかるようになります。ただ、NN法と違うのは、学習した点のうち、境界面を形作るものだけをサポートベクターとして残して、判別にはそのサポートベクターだけを使うところです。そうすると、学習結果はサポートベクターとそれに対応する係数だけを覚えておけばいいことになります。そのため、実際の判別では、限られた数のサポートベクターとの比較を行えばよくなり、メモリも食わず時間もかからないということになります。


どんな点がサポートベクターになるかを見てみると、こんな感じになりました。大きい点がサポートベクターです。いい感じに、境界付近の点だけがサポートベクターになっています。サポートベクターではない点は、データ判別の段階では捨ててしまってもかまいません。


ところで、SVMではカーネルを使って非線形分離を行うのですが、そこで大切なのがカーネル固有のパラメタです。今回はガウシアンカーネルを使うのですが、ここでもひとつパラメータを与える必要があります。Math.expの引数の分母になってる数ですね。σの二乗を指定することになってます。
このパラメータがなにかを見てみるために、いろいろいじってみました。上の画像のときには1500を指定してるので、σはだいたい40程度ということになります。
これをσ^2=100、つまりσ=10とするとこんな感じになります。


境界面がガタガタになっています。ほとんどの点がサポートベクターになっています。この境界面は、学習データに適合しすぎて、学習データが変われば判別面は大きく変わるし、ちょっとデータがずれると判別結果が変わることになってしまいます。
機械学習で大切なことは、既知の学習データから未知のデータを分類することですが、これでは既知の学習データはうまく分類できるけど、未知のデータがうまく分類できるかどうかは学習データに強く依存することになってしまします。未知のデータをうまく分類できるかどうかのことを汎化能力といいます。
σ=5くらいにしてMath.exp(-n/30)とすると、もっとひどいことに。


学習データはうまく判別できてるのですが、おそらく未知データはまったく判別できない境界面になっています。数個の点を除いて、すべてがサポートベクターになっているという感じです。そうすると、近い学習点があるかどうかで判別をすることになってしまいます。
で、わかったことは、ガウシアンカーネルのσは、学習データの影響範囲で、判別面はその影響範囲をつなぎ合わせたものになるということです。今回のサンプルでは、σは学習データの影響するドット数と言えます。
ガウシアンカーネルのパラメータσは少なすぎるよりは大きすぎる方がよさそうです。


サポートベクターマシンの本はこの本が参考になります。

サポートベクターマシン入門

サポートベクターマシン入門


ということで、今回のプログラム。単独で動きます。

続きを読む