はじめに
Random Recursive Support Vector Machine(R2SVM)は、ランダム射影による特徴変換を繰り返すことで、線形SVMで非線形な分類器を実現する手法である。また、Rumale::SVMは、Rubyの機械学習ライブラリであるRumaleと同様のインターフェースで、様々なSVMアルゴリズムを利用できるGemである。このRumale::SVMに、R2SVMを実装した。
Vinyals, O., Jia, Y., Deng, L., and Darrell, T., "Learning with Recursive Perceptual Representations," In Proc. NIPS’12, pp. 2825–2833, 2012.
インストールと使い方
Rumale::SVMのインストールは、gemコマンドで行う。
gem install rumale-svm
例として、LIBSVM Dataにあるletterデータセットの分類を行う。
wget https://www.csie.ntu.edu.tw/~cjlin/libsvmtools/datasets/multiclass/letter.scale.tr wget https://www.csie.ntu.edu.tw/~cjlin/libsvmtools/datasets/multiclass/letter.scale.t
分類性能の評価のためrumale-evaluation_measureをインストールする。
gem install rumale-evaluation_measure
letterのデータを分類して、その分類の正確度を出力するスクリプトは以下の様になる。
require 'rumale/dataset' require 'rumale/evaluation_measure' require 'rumale/svm' # letterデータを読み込む. x_train, y_train = Rumale::Dataset.load_libsvm_file('letter.scale.tr') x_test, y_test = Rumale::Dataset.load_libsvm_file('letter.scale.t') # R2-SVMによる分類器を生成する. # パラメータである隠れ層の数は2, 重みパラメータは0.9, 正則化パラメータは1.0とした. classifier = Rumale::SVM::RandomRecursiveSVC.new(n_hidden_layers: 2, beta: 0.9, reg_param: 1.0, random_seed: 42) # 学習データで学習する. classifier.fit(x_train, y_train) # テストデータのラベルを推定する. y_pred = classifier.predict(x_test) # 推定結果の正確度を出力する. acc = Rumale::EvaluationMeasure::Accuracy.new puts format('Accuracy: %.1f%%', (100.0 * acc.score(y_test, y_pred)))
これを実行すると正確度は72.6%となった。
$ ruby example.rb Accuracy: 72.6%
比較のために線形SVMを試してみる。分類器の生成の箇所を以下で置き換えればよい。
classifier = Rumale::SVM::LinearSVC.new(reg_param: 1, random_seed: 42)
結果として、線形SVMの正確度は69.7%となった。R2SVMのほうが、良い分類性能を得ている。
$ ruby example.rb Accuracy: 69.7%
ちなみに、RBFカーネルなカーネルSVMだと正確度は94.6%と、R2SVMより良い数字が得られる...まあ合う合わないがあるようだ。
アルゴリズムの説明
R2SVMについて簡単に説明する。ある次元の入力データをとする。データは個のクラスに分けられている。また、この入力データに対する線形SVMの出力をとする。これらと、正規分布に従うランダム射影行列をを用いて、以下のように特徴変換を行う。
ここで、はシグモイド関数であり、は元のデータをどれくらい移動するかを制御する重みパラメータとなる。 こうして得られたを入力として線形SVMを学習して出力を得て、ランダム射影行列で...と同様の変換をフィードフォワード的に繰り返す。ある層の変換は次の様になる。
出力を連結するのではなく、ランダム射影して足し合わせるのが面白い。
よくある2-moonsデータで、R2SVMの決定境界を示すと次のようになる。
半円の端が誤分類されているが、まあデータ分布に沿った非線形な決定境界となっている。
おわりに
Random Recursive SVM(R2SVM)は、線形SVMをdeepにする方法の一つである。隠れ層の変換は、線形SVMに限らず、各クラスに対する予測スコア的なものを出力できる学習アルゴリズムであれば適用できる。発想は面白いが、手元にあるデータでは、カーネルSVMを超えるようなことはなかったので、実用性はちょっとアレかもしれない。