6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Scalaで機械学習(1)

Posted at

はじめに

基本的に機械学習はPython、データクレンジングとかはRでやってるんですけど、Scalaとかで開発してる企業だったらJVM上で機械学習できたら便利なんかなってなって調べたらbreezeってライブラリあるみたいです、ちょっといじってみたのでその備忘録ってことで。
github -> https://github.com/scalanlp/breeze

セットアップ

scalaとsbtは入ってる前提としますね。

scala := 2.10.3
sbt := 0.1.0

一応僕はこんな感じです。
とりあえずテスト用のディレクトリを作ります。そしたら直下にbuild.sbtファイルを作成してください。コードは以下です。

$ mkdir BreezeTest
$ cd BreezeTest
$ touch build.sbt

できたらbuild.sbtに以下を記述してください。(バージョンとか同じだったらコピペで大丈夫なはずです)

name := "scalanlp-usage"

version := "0.1.0"

scalaVersion := "2.10.3"

resolvers ++= Seq(
"maven repo" at "http://zact.googlecode.com/svn/maven/repository",
"Typesafe Repository" at "http://repo.typesafe.com/typesafe/releases/",
"sonatype releases" at "http://oss.sonatype.org/content/repositories/releases"
)

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

scalacOptions ++= Seq("-encoding", "UTF-8")

ここまでできたら動作チェックをします。以下を実行してください。

$ sbt update

実行できて[success]と表示されてたら成功です!

とりあえず動かしてみる

consoleを開いて以下のように実行してみてください。

scala> import breeze.linalg._
import breeze.linalg._mpile / compileIncremental 0s

scala> val m = DenseMatrix((1, 3), (5, 8))
m: breeze.linalg.DenseMatrix[Int] = 
1  3  
5  8  

scala> val v = DenseVector(1, 3)
v: breeze.linalg.DenseVector[Int] = DenseVector(1, 3)

scala> m * v
res0: breeze.linalg.DenseVector[Int] = DenseVector(10, 29)

まあなんとなくわかると思いますけど、行列演算を行なっています。
最初にパッケージをimportして、2×2行列と要素数2の縦ベクトルを生成して行列積を計算してる感じですね。
何してるのか直感的にわかりやすいのはPythonのNumpyと同じくいいですね。

使い方

では具体的にどのように使えばいいのかみてみましょう。

行列の生成

行列は以下のように生成できます。

scala> val m1 = DenseMatrix((1, 2), (3, 4))
m1: breeze.linalg.DenseMatrix[Int] = 
1  2  
3  4  

scala> val m2 = DenseMatrix((1, 2, 3), (4, 5, 6))
m2: breeze.linalg.DenseMatrix[Int] = 
1  2  3  
4  5  6  

breeze.linalg.DenseMatrixの引数にタプルを渡すとそれを列にした行列が生成されます。当然要素数あってなかったらエラー吐きます。

scala> val m3 = DenseMatrix((1, 2, 3), (4, 5, 6, 7))
<console>:10: error: could not find implicit value for parameter rl: breeze.linalg.support.LiteralRow[Product with Serializable,V]
       val m3 = DenseMatrix((1, 2, 3), (4, 5, 6, 7))

また、単位行列やゼロ行列、転置行列、乱数行列も生成できます。

scala> val identityMatrix = DenseMatrix.eye[Double](2)
identityMatrix: breeze.linalg.DenseMatrix[Double] = 
1.0  0.0  
0.0  1.0  

scala> val zeroMatrix = DenseMatrix.zeros[Double](2, 2)
zeroMatrix: breeze.linalg.DenseMatrix[Double] = 
0.0  0.0  
0.0  0.0  

scala> val mT = m1.t
mT: breeze.linalg.DenseMatrix[Int] = 
1  3  
2  4  

scala> val randomMatrix = DenseMatrix.rand(2, 2)
randomMatrix: breeze.linalg.DenseMatrix[Double] = 
0.9231480299363446  0.24529928109482446  
0.3786893726630529  0.7983929038314084   

ベクトルの生成にはbreeze.linalg.DenseVectorが使えます。

scala> val v1 = DenseVector(1, 2, 3, 4)
v1: breeze.linalg.DenseVector[Int] = DenseVector(1, 2, 3, 4)

基本的な行列演算

breezeではNumpyのように割と柔軟に行列演算できます。
基本的なやつだけ紹介します。Test.scalaというファイルを作成してコード書いてきます。 

import breeze.linalg._
import breeze.numerics._

object Test {
  def main(args: Array[String]): Unit = {
    // 行列を生成
    val m1 = DenseMatrix((1.0, 2.0), (-3.0, 4.0))
    val m2 = DenseMatrix((5.0, -6.0), (7.0, 8.0))

    // 演算
    println("和: " + (m1 + m2))
    println("差: " + (m1 - m2))
    println("スカラー倍: " + (m1 :*= 2.0))

    // 内積
    println("内積: " + (m1 * m2))

    // 逆行列
    println("逆行列: " + (inv(m1)))

    // 行列式
    println("行列式: " + det(m1))
    println("固有値: " + eig(m1)._1)
    println("固有ベクトル: " + eig(m1)._3)
  }
}  

では実行してみましょう。以下を叩いてください。

和: 6.0  -4.0  
4.0  12.0  
差: -4.0   8.0   
-10.0  -4.0  
スカラー倍: 2.0   4.0  pile / compileIncremental 0s
-6.0  8.0  
10月 29, 2019 4:26:03 午後 com.github.fommil.jni.JniLoader liberalLoad
情報: successfully loaded /var/folders/w_/2q_ddgq51279x8rwrydld_200000gn/T/jniloader1690075005761835753netlib-native_system-osx-x86_64.jnilib
内積: 38.0  20.0   
26.0  100.0  
10月 29, 2019 4:26:03 午後 com.github.fommil.jni.JniLoader load
情報: already loaded netlib-native_system-osx-x86_64.jnilib
逆行列: 0.2                  -0.09999999999999999  
0.15000000000000002  0.05                  
行列式: 40.0
固有値: DenseVector(5.0, 5.0)
固有ベクトル: 0.38729833462074165  -0.5  
0.7745966692414834   0.0   

ちょっと余計な情報入ってますが悪しからず。ちゃんと計算できているのがわかります。

終わりに

とりあえず行列演算はNumpy的な感じでできるのがわかりました。上でも言いましたけど、割とコードわかりやすいのいいですね。
今度は線形回帰とか実装できたらと思います。(疲れたんで今回はこれで終わり)

6
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?