はじめに
Rubyの機械学習ライブラリであるRumaleに、前処理としてカーネル行列を計算するクラス、カーネルリッジ回帰による分類器を追加した。また、Nystroemカーネル近似では、サポートするカーネル関数がRBFカーネルだけであったが、多項式カーネルやシグモイドカーネルを追加した。これを、ver. 0.22.5としてリリースした。
rumale | RubyGems.org | your community gem host
使い方
Rumaleはgemコマンドでインストールできる。カーネルリッジ回帰による分類器で、特異ベクトルを求める必要があるので、numo-openblasも一緒にインストールする。
$ gem install rumale numo-openblas
カーネルリッジ回帰による分類器は、あるラベルが付与されてない/されてるを {-1, 1} の目的変数に変換し(ラベルが3種類あって、あるサンプルに3番目のラベルが付与されているとすると、[-1, -1, 1]という目的変数によるベクトルになる)、これに対して回帰を行い、推論では推定値が最も大きな値に関係するラベルを返す。Rumaleでは、カーネル法による推定器に対しては、カーネル行列を与えるようになっている。scikit-learnなどでは、サンプルを与えることが多い。これと同じ使い方ができるように、前処理としてカーネル行列を計算するクラスを追加した。Pipelineでつないで使用する。
これらを用いて、分類を行う例を示す。データセットには、LIBSVM Dataからletterをダウンロードした。
$ wget https://www.csie.ntu.edu.tw/~cjlin/libsvmtools/datasets/multiclass/letter.scale.t $ wget https://www.csie.ntu.edu.tw/~cjlin/libsvmtools/datasets/multiclass/letter.scale.tr
require 'numo/openblas' require 'rumale' # データを読み込む. x_train, y_train = Rumale::Dataset.load_libsvm_file('letter.scale.tr') x_test, y_test = Rumale::Dataset.load_libsvm_file('letter.scale.t') # 与えられたサンプルからカーネル行列を計算する KernelCalculator と # カーネルリッジ回帰による分類器の KernelRidgeClassifier を Pipeline でつなぐ. classifier = Rumale::Pipeline::Pipeline.new( steps: { ker: Rumale::Preprocessing::KernelCalculator.new(kernel: 'poly', gamma: 1, degree: 3, coef: 1), krc: Rumale::KernelMachine::KernelRidgeClassifier.new(reg_param: 1) } ) # 分類器を学習する. classifier.fit(x_train, y_train) # 正確度を出力する. puts(format("Accuracy: %.3f", classifier.score(x_test, y_test)))
これを実行すると以下のようになる。ロジスティック回帰では、正確度は0.763だったので、カーネル法を用いることで精度が向上することがわかる。
Accuracy: 0.917
おわりに
自分のなかで、1週間ほどカーネル法のリバイバルが起きて、あれこれと追加した。カーネル法は、ニューラルネットワークの隆盛で、影が薄くなってしまったが、小さいデータセットであるとか条件によっては有効であると考える。関連して、ガウス過程の手法を追加したいと考えているが、Rumale::GPとか別Gemかな〜と思っている。