Rubyの機械学習ライブラリまとめ
はじめに
最近では、機械学習関連Gemが多く開発され、Rubyでも機械学習できるようになってきました。代表的なものを、ざっくりとまとめてみました。
まとめ情報
いきなりですが、この記事は私の偏見で選んだものですので、他のまとめ情報も紹介します。もっとも大きなのがAndrei Beliankou (arbox) さんのまとめリポジトリです。色んなものが紹介されています。
Railsエンジニアにとっては、SearchkickやStrong Migrationsで有名な、Andrew Kane (ankane) さんも、機械学習関連のGemを多く作成しています。C/C++のAPIが提供されている、他言語の機械学習ライブラリを、FFI/Fiddle/Riceでラップして、Rubyで使えるようにしています。ankaneさん自身が書かれた、それらGemのまとめ記事があります。
ベクトル・行列・線形代数
PythonでいうところのNumPyですが、Numo::NArrayとNumo::Linalgがオススメです。先に紹介した、ankaneさんのGemでもNumo::NArrayに対応しています。NumPyでできることは、だいたいNumo::NArrayでできます。NumPyの使用経験がある方は、Numo vs numpyを見ると使えるようになると思います。
逆行列を求めたり固有値分解したりとなると、Numo::Linalgが必要になります。numpy.linalgやscipy.linalgに相当します。Numo::Linalgは、BLAS/LAPACKをバックエンドライブリとして使用します。Intel MKLやOpenBLASなど様々ありますが、Gemをインストールする際に選択できます。
ただ、requireするだけでいい感じにバックエンドライブリを読み込んでほしい、という気持ちもあります。そのためにautoloaderがあります。普通にgemコマンドでインストールして、
$ gem install numo-linalg
autoloaderをrequireします。これでいい感じにバックエンドライブリを読み込みます。
require 'numo/linalg/autoloader'
autoloaderの仕組みは /usr/local/lib
などのバックエンドライブリが置いてありそうなところから、Intel MKLなどのライブラリを探すという仕組みです(ルートから全ディレクトリを探すととても重いので置いてありそうなところだけ)。しかし、OSやライブラリ配置は人それぞれなので、百発百中ではなく、ライブラリを発見できないことがあります。この問題に対して、Numo::OpenBLASを作りました。
Gemをインストールするときに、OpenBLASをダウンロードしてきてビルドし、それをNumo::Linalgのバックグラウンドライブラリとして使用します。Juliaをビルドしてて思いついたものです。
$ gem install numo-openblas
OpenBLASをビルドするので、インストールはちょっと重いです。
require 'numo/openblas'
# 私はanyenvでrbenvをいれてRubyをインストールしているのですが、
# numo-openblasのディレクトリ下にlibopenblasがあり、
# それがバックグラウンドライブラリとして選択されます。
p Numo::Linalg::Loader.libs
# ["/Users/hoge/.anyenv/envs/rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/numo-openblas-0.3.1/vendor/lib/libopenblas.dylib"]
# ビルドされたOpenBLASのバージョンもわかります。
p Numo::OpenBLAS::OPENBLAS_VERSION
# " OpenBLAS 0.3.13 "
ちなみに、ベクトル・行列Gemとして、以前はNMatrixという選択肢もあったのですが、開発は止まっている様です。NMatrixと同じSciRubyのもとで、いまはnumrubyというのが動いています。
(2021/02/16追記)
Cudaに対応したNumo::NArrayとも言えるCumoがあります。NumPyに対するCuPyのような存在です。Numo::NArrayと互換性があり、切り替えも簡単です。
データフレーム
PythonでいうところのPandas、Rでいうところのdplyrですが、DaruとRoverがあります。DaruはSciRubyが開発しており、Rubyのデータフレームのデファクトスタンダードかもしれません。
ただ、現在はあまり活発には開発されていません。また、サポートしているデータ形式にNMatrixはあるのですが、Numo::NArrayがありません。最近は多くの機械学習系のGemが、Numo::NArrayを利用しているので、取り回しがよくありません(DaruからArrayやMatrixに変換してNumo::NArrayにするなど)。これに対してRoverは、内部的にもNumo::NArrayを使用しており、最近の機械学習系のGemとも親和性が高いです。
Apache Arrowは、Rubyのデータ処理ツールの開発を目指すRed Data Toolsのメンバーがコミッターとして参加しており、開発が活発です。
機械学習ライブラリ
PythonでいうところのScikit-learnですが、これはRumaleになります。Rumaleは、Scikit-learnと同様のインターフェースを意識しています。つまり、fitで訓練して、predictで予測するというものです。また、多くの機械学習アルゴリズムをサポートしています。
古典的な機械学習ライブラリといえば、LIBSVMとLIBLINEARですが、これをRumaleのインターフェースで使えるようにした、Rumale::SVMもあります。
勾配ブースティングのXGBoostやLightGBMのbindingは、ankaneさんが開発しています。
これらライブラリで、機械学習の一通りのことはできると思います。
深層学習
深層学習のほうが、古典的な機械学習ライブラリより、色々と開発されているかもしれません。
torch.rbは、PyTorchのC++版APIといえるlibtorchをbindingしたものなのですが、libtorch自体がver. 1.5からstableなAPIとして提供されているので、安心して使えるかな〜といったところです。私は試してないですが、GPUも対応しています。また、ModelZoo的なものも使えるので、ちょっと遊ぶには良いかなと思います。
グラフ作成
私がこのジャンルにうといのもあって、詳しくないのですが、chartyが有名だと思います。Numo::NArrayやDaruなど、様々なデータ形式に対応しています。
SciRubyであれば、Daru::Viewというのがあります。
うといのも理由があって、長いことGnuplotでグラフを作ってまして、Numo::Gnuplotがあれば私としては十分だったりします。
近似最近傍探索
近似最近傍探索の古典的なものであるFLANNは、公式のリポジトリにRuby bindingがあります。ただデータの受け渡しにNMatrixを使います。
最近のものですと、Yahoo! Japanが開発しているNGTや、Facebookが開発しているFaissのbindingがあります。
検索精度とインデックスの大きさのバランスの良さから、よくWebサービスで採用されているAnnoyのbindingもあります。
torch.rbによるVGG-16 Networkを使った特徴抽出と組み合わせて、類似画像検索を作るというのをやってみました。
画像処理
ImageMagickでは、RMagickとMiniMagickが定番です。
最近はlibvipsのbindingであるruby-vipsも人気みたいですね。
OpenCVのbindingは複数あります。
私の開発しているMagroは、基本的には、pngとjpegがNumo::NArray形式で読み書きできる、というものです。機能としてもリサイズと畳み込みなどミニマルなものを意識してます。
自然言語処理
割と色々なものが作られているのですが、NLTKやSpaCyのような統合的なものが無いように思います。そういったライブラリを作るのが今後の課題でしょうか。私も挑戦したい気持ちはあります。
日本語形態素解析では、MeCabをラップしたNattoがあります。
外部ライブラリなどを必要としない、Gemをインストールするだけで使える、PythonでいうところのJanomeのような辞書同梱型の形態素解析には、Suikaがあります。
ただ、Suikaはまだ機能が少ないのと、ユーザー定義辞書も対応していません。辞書の読み込みが遅いので、まずはそこを何とかしたいのですが。
ノートブック
(2021/02/16追記)
IRubyを使うとJupyter NotebookでRubyが使えます。リポジトリのREADMEに丁寧にインストール方法が書かれています。
Try JupyterにもRubyのものがあります。RumaleのVersionは0.16.1なので、ちょっと前のものです。
コミュニティ
SciRubyは、Rubyで機械学習やデータサイエンスに取り組んでいるコミュニティでは最も有名なんじゃないでしょうか。IRubyやDaruが有名です。
Red Data Toolsは、Ruby用のデータ処理ツールの開発を目指して活動されています。おそらくRubyでデータ処理ツールのコミュニティとしては、最も活発だと思います。
Rubyプログラマーの交流の場でもあるruby-jpにもmachine-learning、datascience、nlpといったチャンネルがある様です。
おわりに
以上、勢いで書いた雑なまとめでした〜。 個人的な体験なのですが、ActiveRecordでデータを取ってきて、適当に加工して、Rumaleでサクッと分類器を作り、APIをたてるみたいなのが、すごいスムーズで便利でした。今後は、Railsとの親和性を高めるようなものがあると良いんだろうな〜と漠然と考えてます。
Discussion