サポートベクターマシン(以下 SVM) とは
・ニューラルネットワークの一種
・教師ありクラスタリング
SVM の基本的な考え方
・元々2クラスの線形分離手法として提案される
・単層パーセプトロンに似ているが、SVM はマージン最大化という手法をとっているのがポイント。
・マージン最大化とは、超平面と学習データの隙間となるマージンをなるべく大きく取ろうというもの。
(ここでいう超平面とは、2つのクラスにぶった切る平面のこと)
・ちなみに超平面と、ちょうどマージンの分だけ離れている学習データをサポートベクトルという。
・このマージン最大化という考えを取り入れることによって、テストデータの識別精度を高めている。
SVM の発展
・線形分離不可能な問題への対応
- ソフトマージン(学習データが多少マージンにくい込んだり、反するクラスの空間にくい込んだりしても許す)で対応
(↑まだ、超平面自体は線形であることに注意)
・非線形問題への対応
- カーネルトリックにより非線形な問題も対応
(ちなみに、PCA(主成分分析)や部分空間法もカーネルトリックにより、非線形に拡張可能)
- このカーネルトリックにより SVM の精度が飛躍的に向上し、SVM がメジャーになった。
・2クラスより多いクラスタリング問題への対応
- 複数のSVMを組み合わせることにより対応
SVM の利点
・データの特徴量の次元が大きくなっても識別精度がよい(マージン最大化のおかげ)
- 一般的にデータの特徴量の次元をむやみに増やすと識別精度が悪くなる(ヒューズの現象、球面集中現象)。
なので、本来次元数の数倍の学習データを用意しなければいけないとされている。
しかし、SVM は特徴量の次元数が大きくても対応できるため、画像認識の分野で頻繁に使われる。
(文字認識の問題では、元の画像をグレースケールにして 20x20Pixel に正規化して、そのまま400次元の特徴量として SVM にぶち込んでやるという手法もとられている。)
・最適化するべきパラメータが少ない
- ニューラルネットワークでは、良い精度を得るためにパラメータを試行錯誤して決定する必要があるが、SVM では割と簡単に最適なパラメータが求められる。
SVM の欠点
・学習データが増えると計算量が膨大となる
- 特徴量の次元は大きくても対応できるが、学習データ数が増えるとタイヘン。
・基本は2クラスの識別の手法
- 複数のSVMを組み合わせることで多クラスの識別が可能だが、多クラスを考慮に入れた識別関数の最適化をすることができない。
参考 : 前田英作, "痛快! サポートベクトルマシン ~古くて新しいパターン認識手法~", 情報処理学会誌, Vol.42, No.7, pp.676-683, (2001).
http://www.neuro.sfc.keio.ac.jp/~masato/study/SVM/index.htm
とか、あといろいろ見たよ。
実際に計算してみよう!
パッケージとしては、"LIBSVM"と"SVMlight"が有名なようだ。
http://www.bi.a.u-tokyo.ac.jp/~tak/svm.html
R(オープンソースの統計処理ソフトウェア) のインタフェースが用意されているということで、LIBSVM を選択。
http://www.csie.ntu.edu.tw/%7Ecjlin/libsvm/
LIBSVM は、R の"e1071"というパッケージに入っています。
パラメータをどのように設定したらいいかは以下の pdf を参照。
http://www.csie.ntu.edu.tw/~cjlin/papers/guide/guide.pdf
e1071 の仕様は以下の pdf を参照。
http://cran.r-project.org/doc/packages/e1071.pdf
e1071 を使ったサンプル
http://www.csie.ntu.edu.tw/%7Ecjlin/libsvm/R_example
(↑とか、e1071.pdf のサンプルとかを実際に入力して練習してみるといいよ)
LIBSVM の FAQ
http://www.csie.ntu.edu.tw/%7Ecjlin/libsvm/faq.html
最適なパラメータの探し方
・主に精度の良し悪しを決めるのは kernel の選び方と γ(gamma) と C(cost) の設定である。
・上の guide.pdf を参考にすると設定法は以下となる
- kernel はデフォルトの RBF 一択でOK。
- γとC は、grid serch により最適な値をヒューリスティックに探す。
grid serch は、例えば調べる値を γ=(0.5, 0.25) C=(1, 2, 4)として入力したら、
(γ,C) = (0.5, 1),(0.5, 2),(0.5, 4),(0.25, 1),(0.25, 2),(0.25, 4)
の 6 種類すべて、cross-validation(または、bootstrap) で性能評価し、一番制度の良いものを提示してくれる。
(e1071 では、grid serch を tune という関数で行う。)
- 最初は大雑把な値で、次に詳細な値で、探すといいよ(coarse to fine(祖から密へ) の考え方で)。
- ただし、特徴量の次元がバカでかい(数千次元)などの特別な場合は、他の手法を取る必要があるよ。
その他のパラメータについて
・type について
- "C-classification" と "nu-classification" の違い
FAQに該当箇所がある
http://www.csie.ntu.edu.tw/%7Ecjlin/libsvm/faq.html#f411
基本的には同じということだし、デフォルトが"C-classification"だし、教科書的な方法は"C-classification"みたいだし(詳しくは以下の pdf 参照)、デフォルトままでよさそう。
http://www.csie.ntu.edu.tw/~cjlin/papers/libsvm.pdf
・scale について
- デフォルトのTRUE だと、すべての特徴量の次元ごとでスケーリング(正規化)を行う。
- 特徴量の次元ごとに重みを変えたい場合は、scale を FALSE にして、自分で重みを考慮したスケーリングすると調整するとできるのかな?
・class.weights について
- クラスの重みを変えることができる。
- 例えば、犬の画像と猫の画像をクラスタリングすることを考える。
自分は犬の画像が大好きなので、犬の画像にクラスタリングされる画像が欲しいのだが、
一枚の犬の画像も見逃したくはない、という場合に犬のクラスタの重みを大きくする。
すると、犬の画像が猫の画像だと誤認識される確率は減り、犬の画像の再現率が上がる。
でも、猫の画像が紛れ込む可能性が上がるけどね。
という感じにクラスの重みを調整できる。
type パラメータについてもっと詳しく
・"C-classification" (or "nu-classification") (分類)について
- 普通のクラスタリング問題の時に使う。
- 例えば、犬の画像と猫の画像のクラスタリング問題を考えると
テストデータの予測(predictの)結果は、犬クラスか猫クラスかという2値(2クラスタなので)で出力される。
・"eps-regression" (or "nu-regression") (回帰)について
- 上の"C-classification"では、テストデータの予測結果は、犬クラスか猫クラスかという2値で与えられるが、
このパラメータを使用すると、予測結果は数値として出力される。
つまり、そのテストデータがどれくらい犬クラス(猫クラス)として尤もらしいかを知りたい時に使用する。
- ラベルは数値で与える。
- 例えば、学習データの犬の画像に -1、猫の画像に 1 のラベルを与えたとする。
すると予測(predictの)結果は -0.10516366 や -0.80516366 という値として出力される。
両方とも犬クラスとして判定されたことになるが、前者(-0.10516366)より後者(-0.80516366)の方が、犬の画像として尤もらしいことが分かる。
なお、0 より小さい値を犬クラス、0 より大きい値を猫クラスと判定すれば、"C-classification" と同じことになる。
たぶん。
・"one-classification" (1クラスSVM)について
- 1つのクラスとその他にクラスタリングしたいときに使用する。
- 例えば、種々雑多な画像群から犬の画像だけ取って来たい場合
犬の画像のみで学習し、犬の画像とそれ以外の画像にクラスタリングする。
- e1071 では、ラベルの引数を与えずに 関数svm でモデルを作れば、
自動的に type="one-classification" となり、1クラスSVM となる。
SVM 使った感想
・精度タケー!