はじめに
Rubyの機械学習ライブラリであるRumaleに、回帰分析のための計量学習手法である Metric Leaning for Kernel Regression (MLKR) を追加し、ver. 0.22.1 としてリリースした。
rumale | RubyGems.org | your community gem host
使い方
Rumaleはgemコマンドでインストールできる。主成分分析の固有値分解のためにNumo::Linalgを、実行結果の描画にNumo::Gnuplotを使うので、一緒にインストールする。
$ gem install rumale numo-linalg numo-gnuplot
Numo::Gnuplotのためにgnuplotを、Numo::LinalgのためにOpenBLASをインストールする。
$ brew install gnuplot openblas
MLKRは、教師あり特徴変換・次元削減と捉えることができる。後述するが、目的変数に合わせたデータ分布になるような変換・射影を行う。Rumaleではfitメソッドで学習し、transformメソッドで変換・射影を行う。
まずは、テストデータを主成分分析で変換した例を示す。
require 'numo/linalg/autoloader' require 'rumale' def make_regression(n_samples: 1000, n_features: 100, n_informative: 10, n_targets: 1) n_informative = [n_features, n_informative].min rng = Random.new(42) x = Rumale::Utils.rand_normal([n_samples, n_features], rng) ground_truth = Numo::DFloat.zeros(n_features, n_targets) ground_truth[0...n_informative, true] = 100 * Rumale::Utils.rand_uniform([n_informative, n_targets], rng) y = x.dot(ground_truth) y = y.flatten rand_ids = Array(0...n_samples).shuffle(random: rng) x = x[rand_ids, true].dup y = y[rand_ids].dup [x, y] end def mds_visualize(x, y, filename: 'tmp.png') # 多次元尺度構成法で二次元にマッピングする mds = Rumale::Manifold::MDS.new(random_seed: 2) z = mds.fit_transform(x) # Gnuplotで可視化結果を出力する y = (y - y.min) / (y.max - y.min) y = Numo::Int32.cast((y * 5.9).floor) plots = y.to_a.uniq.sort.map { |l| [z[y.eq(l), 0], z[y.eq(l), 1], t: l.to_s] } Numo.gnuplot do set(terminal: 'png') set(output: filename) plot('[-6:6] [-6:6]', *plots) plot(*plots) end end # テストデータを主成分分析で変換する x, y = make_regression(n_samples: 500, n_informative: 4, n_features: 10) pca = Rumale::Decomposition::PCA.new(n_components: 10) z = pca.fit_transform(x, y) # 結果を可視化する mds_visualize(z, y, filename: 'pca.png')
描画の便宜上、目的変数を5段階に区切った。異なる目的変数を持つデータが混在しているのがわかる。
同様のデータをMLKRで変換してみる。
# テストデータをMLKRで変換する x, y = make_regression(n_samples: 500, n_informative: 4, n_features: 10) mlkr = Rumale::MetricLearning::MLKR.new(n_components: nil, init: 'pca') z = mlkr.fit_transform(x, y) # 結果を可視化する mds_visualize(z, y, filename: 'pca.png')
主成分分析の場合と比較して、目的変数にそってデータが配置されているのがわかる。このMLKRで変換したデータで回帰を行えば、決定係数などが向上する。
MLKRのアルゴリズム
MLKRの目的関数は、とてもシンプルなもので、以下のようになる。カーネル関数(論文中ではガウスカーネルが用いられる、Rumaleの実装でもそのようにした)を重みとした目的変数の重み平均を推定値とし、目的変数と推定値の自乗誤差を目的関数とする。
ガウスカーネルの計算には、二点間の距離が必要になるが、これがMLKRにより変換・射影したベクトル間の距離となる。こうすることで、カーネル関数による回帰分析において、誤差が小さくなるような変換を得られる。
おわりに
計量学習では分類を想定したものが多い。MLKRは回帰分析を対象としていて、おもしろいなと思って実装した。Rumaleの計量学習の実装は、一旦これで打ち止めとしたい。計量学習自体が、教師なし・教師あり・半教師あり学習(もちろん深層学習も)と様々あり、きりがないというか、全てをカバーするなら別gemにしたほうが良いと考えた。MLKRの最適化の実装には、lbfgsb.rbを用いた(我ながら作ってよかった)。今後もRumaleでは、最適化にL-BFGS (-B) が使えるようなアルゴリズムを追加しようと考えている。