元ネタ
Spark MLlib の K-means を Java から利用してみる - ALBERT Engineering Blog のScala移植版です。
とても丁寧な解説付きなので、まずはそちらをご覧ください。
Scalaコード
変数名やデータ構造および出力フォーマットは、元ネタに合わせています。
言語以外に変更した点は、下記の通りです。
- "iris.txt"が見当たらなかったので、"iris.data"を使いました。
- ヘッダ行ではなく空行を取り除いています。
- http://archive.ics.uci.edu/ml/machine-learning-databases/iris/
- Sparkのバージョンを上げているため、特徴ベクトルの型がMLib独自のものになっています。
- Java 8 & 機械学習の視点でみる Spark 1.0 リリース - ALBERT Engineering Blog
KMeansIris.scala
import org.apache.spark.SparkContext
import org.apache.spark.mllib.clustering.KMeans
import org.apache.spark.mllib.linalg.Vectors
object KMeansIris extends App {
val context = new SparkContext("local", "demo")
val data = context.
textFile("src/main/resources/iris.data").
filter(_.nonEmpty).
map { s =>
val elems = s.split(",")
(elems.last, Vectors.dense(elems.init.map(_.toDouble)))
}
val k = 3 // クラスタの個数を指定します
val maxItreations = 100 // K-means のイテレーション最大回数を指定します
val clusters = KMeans.train(data.map(_._2), k, maxItreations)
// 各クラスタの中心を確認する
println("## クラスタの中心")
clusters.clusterCenters.foreach {
center => println(f"${center.toArray.mkString("[", ", ", "]")}%s")
}
// 各データがどのクラスタに分類されたのかを確認する
println("## 各データのクラスタリング結果")
data.foreach { tuple =>
println(f"${tuple._2.toArray.mkString("[", ", ", "]")}%s " +
f"(${tuple._1}%s) : cluster = ${clusters.predict(tuple._2)}%d")
}
}
確認環境
build.properties
sbt.version=0.13.6
build.sbt
name := "KMeansIris"
version := "1.0"
scalaVersion := "2.10.4"
libraryDependencies ++= Seq(
"org.apache.spark" %% "spark-core" % "1.1.0",
"org.apache.spark" %% "spark-mllib" % "1.1.0"
)