Scala

Scala用の機械学習関係ライブラリ関係を調べてみる

 
Scala Advent Calendar 2013の一環として記事を書いてます.内容としてはScala Advent Calendar 2011の記事(Scalaは機械学習に使えるかな?)の続きみたいなものかな・・・.

まずScalaからJava系のライブラリ各種を呼び出す場合ですが,Scala Days 2013のトーク : Scalable and Flexible Machine Learning With Scala (http://parleys.com/p/51c2e0f3e4b0ed877035684f)や,関係のスライド Scalable and Flexible Machine Learning With Scala @ LinkedInあたりをまず見てみます.
 
要するにMapReduceの処理にどうやって持っていくかという話になるのですが(暴論),紹介されているScalding(Github: https://github.com/twitter/scalding)などのように,ScalaでDSLの実装をして,裏ではJavaライブラリやScalaで書かれた部分に頑張ってもらう,と.ScalaでDSLという話はScalaスケーラブルプログラミングにも出てくる程度には普通の話だと思うので,まぁ普通に嬉しいですね,ということになります.
 
自前で実装するという話をもう少し見ていくと,メソッドを演算子のような形で使うことで(この表現は怪しい?)普通に自作クラス間での計算式を賭けるようになるので,機械学習で使うような計算(線形代数: ベクトル,行列, 確率統計: 分布からのサンプルその他)を実装していくという方向になります.2年前に調べたときはScalalaという線形代数(Linear Algebra, LA)のライブラリ開発がされていましたが,今はbreezeというプロジェクトになりました.

Github: https://github.com/scalanlp/breeze

ScalaNLPというNLP(自然言語処理; 人間が読み書きや話しに使う言語で書かれた文書や,文書の集まり(コーパス)をコンピュータで処理すること. ibisforestさんより)のための開発の一環でしょうか.

Breeze is a library for numerical processing, machine learning, and natural language processing. Its primary focus is on being generic, clean, and powerful without sacrificing (much) efficiency.

 
Scalalaの時代はそこまでドキュメントが整理されていなかったですが,最近ではMatlabやPythonでのNumpy/Scipyと比較してどうこう・・・Breeze Linear Algebra · scalanlp/breeze Wiki · GitHubというページが整備されていて,普通の行列計算やベクトル計算をそのまま書き写すことが一応出来るでしょうか.

なぜ一応と言っているかというと,Pythonでいうndarrayの機能が全てないようなんですね.全て無いこと自体は欠点ではないですが,平たく言うと多次元配列をそんなに上手く扱えないようので,そのあたりが本当にMatlabやNumpy/Scipyからの書き写しが出来るのか疑問に思っています.というかできなかったんだよ.

val c = DenseMatrix.zeros[Double](n,m) 
c(::, 2) 

このようにそれっぽく要素アクセス出来るので,たぶんちゃんと調べたらもう少し使い方分かるような気がするのですが.上の対応表ページで紹介されているSpecial “reduction” functions.とか面白いのですけどね.肝心の性能ですが

Breeze uses netlib-java for its core linear algebra routines. This includes all the cubic time operations, matrix-matrix and matrix-vector multiplication. Special efforts are taken to ensure that arrays are not copied.

ということらしいです.僕は詳しいことは分からないので,そのうち実験したいです.DenseMatrixと他のMatrixの違いとか.

breeze自体は上に書いた通り,自然言語処理関係の一部分で開発されているようなので,線形代数計算以外にもパッケージがあります.機械学習関係(breeze-learn)や可視化関係(breeze-viz)があります.一番ドキュメントが整理されているのは線形代数関係(UserGuide: https://github.com/scalanlp/breeze/wiki/UserGuide)だと思いますが.ホームページ上ではEpicというパーサ(文を区切ります)を作ってるっぽいですが,正体は謎です.

ただ,ScalaDocで吐き出されているAPIページを見てみると,breeze.classify(分類器), breeze.corpora(コーポラ), breeze.data(データ関係,おそらくファイルとか読み込んだりする用), breeze.inference, breeze.stat, breeze.optimize(推論,確率統計関係,最適化関係)とかいろいろあるんですよね.まぁ開発中なんでしょ,きっと.

ちょっと試したい場合,build.sbtにライブラリ依存を書いて使って見て下さい.

scalaVersion := "2.10.2"

libraryDependencies ++= Seq(
  "org.scalanlp" % "breeze_2.10" % "0.5.2",
  "org.scalanlp" % "breeze-viz_2.10" % "0.5.2"
)

resolvers ++= Seq(
  "Sonatype Snapshots" at "https://oss.sonatype.org/content/repositories/snapshots/",
  "Sonatype Releases" at "https://oss.sonatype.org/content/repositories/releases/"
)



さて,もう少し別の方向にDSLが発展した(と言っていいのか,ちょっと自信がないですが)ものにOptiMLという開発中のものがあります(Stanford PPL).これは全体的にもっと大きなフレームワークの一部だと思いますが,機械学習用のDSLを目指しているように見えます.

OptiML is a domain-specific language for machine learning written in Scala. This project primarily explores how scalable data and task parallelism can be implicitly extracted out of high level abstractions such as vectors, matrices, factor graphs, decision trees, and neural networks.


現在はアルファ版(OptiML — Welcome)で遊ぶことができます.結構容量あります.Scalaで書かれているものを.degファイルで書かれたものにコンパイルして実行します.大きなフレームワークってどういう話かというと,OpenCLやCUDA使ったり,C++と絡ませたり,そういうことです.全然Scalaで完結してないじゃん・・・.

それはともかく,サンプルとしてGDA(って何?), ロジスティック回帰,ナイーブベイズ,RBM,kNNのscalaファイルが入ってます.余計な部分を省いてちょっと見てみます.

val x = readMatrix(args(0))
val y = readVector(args(1)).t

val theta = DenseVector.zeros(x.numCols)
// gradient descent with logistic function
val alpha = 1.0
val w = untilconverged(theta, maxIter = 30) { cur =>
  val gradient = sum((0::x.numRows) { i =>
    x(i)*(y(i) - sigmoid(cur *:* x(i)))
  })
  val z = cur + gradient*alpha
  z
}

ってまぁ上のbreezeみたいな計算,中で書いてます.普通だった.んでoptimlの中身に上のbreezeのコアで使われているっぽいですがnetlib-java使ってるようです.あらあら.もう少しの中身はExampleページをどうぞ(Example: OptiML — Examples).実際中身でどんなことしてるか,よくわかりませんでした.


と,ここまで順番にbreezeとOptiMLを見て見ましたけど(書いてないですが,breeze.linalg使って一応ナイーブベイズまで書いたんだよ…),正直なところ例えばMatlabからScalaに,PythonからScalaにと,移行してくるほどかというと,全然そうでもないですね.また来年に期待しましょう.もう少し真面目に,ドキュメント/API読んでみようかなぁ.

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です