57
Why don't you create new Spark.jl? 2015711JuliaTokyo#4 @sfchaos 1

Why dont you_create_new_spark_jl

  • Upload
    sfchaos

  • View
    1.235

  • Download
    4

Embed Size (px)

Citation preview

Page 1: Why dont you_create_new_spark_jl

Why don't you createnew Spark.jl?

2015年7月11日JuliaTokyo#4

@sfchaos

1

Page 2: Why dont you_create_new_spark_jl

自己紹介■ twitterID: @sfchaos

■ キーワード: データマイニング,機械学習,オントロジー, R,Python,Perl,C++,Julia

■ 今日はこの言葉を言うためにやって来ました. “Why don't you create Spark.jl?”

2

Page 3: Why dont you_create_new_spark_jl

アジェンダ1. Sparkとは

2. SparkRを使ってみる

3. PySparkを使ってみる

4. JuliaとSparkの連携をめぐる動向

5. まとめとご提案

3

Page 4: Why dont you_create_new_spark_jl

1. Sparkとは

4

Page 5: Why dont you_create_new_spark_jl

Apache Sparkの概要■ OSSのインメモリ処理の分散並列基盤.

■ RDDという分散コレクションに対して,map, filter, reduceなどのデータ処理を繰り返して目的のデータを得る処理モデル.※ RDD: Resilient Distributed Dataset

■ 2009年,UC Berkeley(当時)のMatei Zaharia氏が関数プログラミング言語Scalaを用いて開発.

5

Page 6: Why dont you_create_new_spark_jl

Apache Sparkの概要■ Sparkのコアとなる分散処理エンジン

(Apache Spark Core)■Spark SQL: SparkのアプリでSQL

■Spark Streaming: ストリーム処理

■MLlib: 機械学習

■GraphX: グラフの処理

6

Page 7: Why dont you_create_new_spark_jl

データ分析でSparkを使用する意義■ インタラクティブな分析が可能.

■ 並列分散方法などを意識せずに,大規模データ(~TB級)の処理が可能.

■ 機械学習のアルゴリズムで頻出する反復処理を高速化.

7

Page 8: Why dont you_create_new_spark_jl

データ分析でSparkを使用する意義■k平均法などの反復計算で高速化が期待できる.

8

猿田浩輔,「Spark MLlibではじめるスケーラブルな機械学習」,

JJUG ナイトセミナー, 2014年.

http://www.slideshare.net/hadoopxnttdata/spark-m-llib-nttdata

Page 9: Why dont you_create_new_spark_jl

産業界で進むSparkへの投資■ IBMが3,500人を投入するなど,今後の一層の成長が有望視される.

9

TechCrunch記事(2015年6月16日)

http://jp.techcrunch.com/2015/06/16/20150615ibm-pours-researchers-and-resources-into-apache-spark-project/

Page 10: Why dont you_create_new_spark_jl

SparkRのサポートの開始■ 従来は,Scala, Java, Pythonで記述,実行可能.

■ 先日リリースされたSpark 1.4.0からはSparkRのサポートを公式に開始.

10

Page 11: Why dont you_create_new_spark_jl

Sparkのインストール■ Mac/Linuxユーザは,以下のページから落として解凍するだけ.http://spark.apache.org/downloads.html

■ Windowsユーザは,qtwiさんのQiitaの記事を参照.http://qiita.com/qtwi/items/7abcfc53ba9568f20004

11

Page 12: Why dont you_create_new_spark_jl

MLlibとは■ Sparkで機械学習を実行するライブラリ

■ 残念ながら,Spark 1.4.0のSparkRではMLlibへのインタフェースは提供されていない.

12

Page 13: Why dont you_create_new_spark_jl

MLlibで利用できるアルゴリズム■線形モデル■クラス分類(線形カーネルSVM, ロジスティック回帰)

■回帰(最小二乗法,LASSO,リッジ回帰)

■決定木■集団学習(ランダムフォレスト,勾配ブースティング)

■ナイーブベイズ分類器■ isotonic回帰(等調回帰?)

13

Page 14: Why dont you_create_new_spark_jl

MLlibの参考資料■ MLlibについては,以下の資料が大変参考になる.

■ MapReduceを用いる問題点の指摘からSparkやMLlibの処理の概要まで,非常に分かりやすい.

14

猿田浩輔,「Spark MLlibではじめるスケーラブルな機械学習」,

JJUG ナイトセミナー, 2014年.

http://www.slideshare.net/hadoopxnttdata/spark-m-llib-nttdata

Page 15: Why dont you_create_new_spark_jl

予測モデルの構築・検証(ホールドアウト検定)

■訓練データと検証データに分割

15

データ

訓練データ

検証データ

モデル構築

予測モデル

モデル検証

検証結果

モデルを評価するフェーズ

モデルを構築するフェーズ

Page 16: Why dont you_create_new_spark_jl

Scalaのファイルを覗いてみる${SPARK_HOME}/examples/src/main/scala/org/apache/spark/examples/mllib/DecisionTreeRunner.scala

16

object DecisionTreeRunner {

object ImpurityType extends Enumeration { type ImpurityType = Value val Gini, Entropy, Variance = Value }

import ImpurityType._

Page 17: Why dont you_create_new_spark_jl

Scalaのファイルを覗いてみる${SPARK_HOME}/examples/src/main/scala/org/apache/spark/examples/mllib/DecisionTreeRunner.scala

17

case class Params( input: String = null, testInput: String = "", dataFormat: String = "libsvm", algo: Algo = Classification, maxDepth: Int = 5, impurity: ImpurityType = Gini, maxBins: Int = 32, minInstancesPerNode: Int = 1, minInfoGain: Double = 0.0, numTrees: Int = 1, featureSubsetStrategy: String = "auto", fracTest: Double = 0.2, useNodeIdCache: Boolean = false, checkpointDir: Option[String] = None, checkpointInterval: Int = 10) extends AbstractParams[Params]

def main(args: Array[String]) {

Page 18: Why dont you_create_new_spark_jl

ランダムフォレストを用いたホールドアウト検定

■ 現状は,あえてSparkRを使う理由はない気がする

18

scala> import org.apache.spark.SparkContext scala> import org.apache.spark.mllib.tree.RandomForest scala> import org.apache.spark.mllib.util.MLUtils scala> import org.apache.spark.mllib.evaluation.BinaryClassificationMetrics scala> import org.apache.spark.mllib.evaluation.MulticlassMetrics scala> // データのロード scala> val sc = new SparkContext("local", "RandomForest") scala> val data = MLUtils.loadLibSVMFile(sc,             "data/mllib/sample_libsvm_data.txt") scala> // 訓練データとテストデータへの分割 scala> val splits = data.randomSplit(Array(0.7, 0.3)) scala> val (trainingData, testData) = (splits(0), splits(1))

Page 19: Why dont you_create_new_spark_jl

ランダムフォレストを用いたホールドアウト検定

■ 現状は,あえてSparkRを使う理由はないかも

19

scala> // ランダムフォレストを用いた予測モデルの構築 scala> val numClasses = 2 // クラス数 scala> val categoricalFeaturesInfo = Map[Int, Int]() // カテゴリ変数の情報 scala> val numTrees = 500 // 構築する決定木の個数 scala> val featureSubsetStrategy = "auto" // 特徴量選択のアルゴリズム scala> val impurity = "gini" // 不純度に用いる指標 scala> val maxDepth = 5 // 木の最大の深さ scala> val maxBins = 32 scala> val model = RandomForest.trainClassifier(trainingData,       numClasses, categoricalFeaturesInfo, numTrees,       featureSubsetStrategy, impurity, maxDepth, maxBins)

Page 20: Why dont you_create_new_spark_jl

ランダムフォレストを用いたホールドアウト検定

■ 現状は,あえてSparkRを使う必要はないかも.

20

scala> // テストデータに対する予測モデルの評価 val labelAndPreds = testData.map { point => val prediction = model.predict(point.features) (point.label, prediction) } scala> // 混合行列 scala> val metrics = new MulticlassMetrics(labelAndPreds) scala> metrics.confusionMatrix res20: org.apache.spark.mllib.linalg.Matrix = 13.0 1.0 0.0 17.0

scala> metrics.precision res21: Double = 0.9285714

正例と予測

実績が正例

適合率

(precision)

Page 21: Why dont you_create_new_spark_jl

2. SparkRを使ってみる

21

Page 22: Why dont you_create_new_spark_jl

SparkRとは■ RからSparkを使うためのバインディング

■ Spark 1.4.0から公式にサポートされることになった.

22

Page 23: Why dont you_create_new_spark_jl

SparkRの情報■ qtwiさんのQiitaの記事が非常にまとまっている.

■ 本資料でも大いに参考にさせていただいた. http://qiita.com/qtwi/items/7abcfc53ba9568f20004■ というか,この記事を読んだ方がはるかに良い.

23

Page 24: Why dont you_create_new_spark_jl

SparkRの情報■@hoxo_mさんの記事

http://qiita.com/hoxo_m/items/22d31ad589970246562d

24

Page 25: Why dont you_create_new_spark_jl

SparkRのアーキテクチャ

25

Shivaram Venkataraman, Zongheng Yang, SparkR: Enabling Interactive Data Science at Scale, https://spark-summit.org/2014/wp-content/uploads/2014/07/SparkR-SparkSummit.pdf

Page 26: Why dont you_create_new_spark_jl

SparkRの起動■Sparkのディレクトリ配下のbin/sparkRを実行■必要に応じてパスを通しておくと良い

26

$ bin/sparkR

R version 3.1.2 (2014-10-31) -- "Pumpkin Helmet" Copyright (C) 2014 The R Foundation for Statistical Computing Platform: x86_64-apple-darwin13.4.0 (64-bit)

(中略)

Welcome to SparkR! Spark context is available as sc, SQL context is available as sqlContext

Page 27: Why dont you_create_new_spark_jl

データの入出力・変換■ createDataFrame: SparkのDataFrameに変換 ※ DataFrameは,SparkSQL用のデータ形式

27

Page 28: Why dont you_create_new_spark_jl

データの入出力・変換■ jsonファイル

■ read.df関数で読み込みHiveSQL上のテーブルに変換■ SQLによりデータ抽出可能

28

> people <- read.df(sqlContext, “./examples/src/main/resources/ > people.json", "json") > head(people) ## age name ##1 NA Michael ##2 30 Andy ##3 19 Justin

> printSchema(people) # root # |-- age: integer (nullable = true) # |-- name: string (nullable = true)

Page 29: Why dont you_create_new_spark_jl

データの入出力・変換■ Hiveとの連携

■ HDFSに蓄積されたデータの抽出

29

> hiveContext <- sparkRHive.init(sc) > sql(hiveContext, "CREATE TABLE IF NOT EXISTS src (key INT, value STRING)") > sql(hiveContext, "LOAD DATA LOCAL INPATH ‘examples/src/main/ resources/kv1.txt' INTO TABLE src")

> # クエリはHiveQLで表現可能 > results <- hiveContext.sql("FROM src SELECT key, value")

> # 返り値はRのデータフレームで返される > head(results) ## key value ## 1 238 val_238 ## 2 86 val_86 ## 3 311 val_311

Page 30: Why dont you_create_new_spark_jl

DataFrameオブジェクトの作成■ createDataFrame関数によりRのデータフレームから作成

30

> iris.df <- createDataFrame(sqlContext, iris) > iris.df DataFrame[Sepal_Length:double, Sepal_Width:double, Petal_Length:double, Petal_Width:double, Species:string] > class(iris.df) [1] "DataFrame" attr(,"package") [1] “SparkR" > head(iris.df, 3) Sepal_Length Sepal_Width Petal_Length Petal_Width Species 1 5.1 3.5 1.4 0.2 setosa 2 4.9 3.0 1.4 0.2 setosa 3 4.7 3.2 1.3 0.2 setosa

Page 31: Why dont you_create_new_spark_jl

DataFrameオブジェクトの操作■ 行の抽出(filter関数)

31

> library(magrittr) > head(filter(iris.df, iris.df$Sepal_Length >= 5.0), 3) Sepal_Length Sepal_Width Petal_Length Petal_Width Species 1 5.1 3.5 1.4 0.2 setosa 2 5.0 3.6 1.4 0.2 setosa 3 5.4 3.9 1.7 0.4 setosa > # パイプ処理も可能 > iris.df %>% filter(iris.df$Sepal_Length >= 5.0) %>% head(3) > # NSE(Non Standard Evaluation)は使えない > iris.df %>% filter(Sepal_Length >= 5.0) %>% head(3) 以下にエラー filter(., Sepal_Length >= 5) : 引数 'condition' の評価中にエラーが起きました (関数 'filter' に対するメソッドの選択時): エラー: オブジェクト 'Sepal_Length' がありません

magrittrパッケージを使用

(dplyrを読み込むと名前の衝突が起きて,

面倒なことに・・・)

Page 32: Why dont you_create_new_spark_jl

データフレームの操作■ 列の抽出

32

> head(select(iris.df, iris.df$Species), 3) Species 1 setosa 2 setosa 3 setosa > # パイプ処理も可能 > iris.df %>% select(iris.df$Species) %>% head(3) > # NSE(Non Standard Evaluation)は使えない > iris.df %>% select(Species) %>% head(3) 以下にエラー select(., Species) : 引数 'col' の評価中にエラーが起きました (関数 'select' に対するメソッドの選択時): エラー: オブジェクト 'Species' がありません

Page 33: Why dont you_create_new_spark_jl

グループ化・集約■ グループ化処理はgroupBy関数で実行.

■ 集約処理はsummarize関数で実行.

33

> # 列Speciesの種別ごとに件数を集計する > iris.df %>% groupBy(iris.df$Species) %>% summarize(count=n(iris.df$Species)) %>% collect Species count 1 versicolor 50 2 setosa 50 3 virginica 50

Page 34: Why dont you_create_new_spark_jl

SparkRからのランダムフォレストの実行■ launchBackend関数でScalaやJavaでビルドした関数を実行するのが良さそう.※ qtwiさんのqiita記事を参照.

34

> SparkR:::launchBackend( sparkSubmitOpts=“--class     org.apache.spark.examples.mllib.DecisionTreeRunner lib/spark-examples-1.4.0-hadoop2.6.0.jar”, jars=“", args="-input data/mllib/sample_libsvm_data.txt -numTrees 500       -fracTest 0.3”, sparkHome=Sys.getenv("SPARK_HOME"))

ランダムフォレストの実行例

Page 35: Why dont you_create_new_spark_jl

その他の話題■ ローカルモードだけでなく,マスター・スレーブを用いた実行例■ RStudioからの利用

■ SparkRからのRDDの利用 等々 qtwiさんのqiita記事を参照.

35

Page 36: Why dont you_create_new_spark_jl

3. PySparkを使ってみる

36

Page 37: Why dont you_create_new_spark_jl

PySparkのアーキテクチャ

37

大規模並列処理:PythonとSparkの甘酸っぱい関係~PyData.Tokyo Meetup #3イベントレポート

http://codezine.jp/article/detail/8484

Page 38: Why dont you_create_new_spark_jl

PySparkの起動■ PySparkの起動

38

$ cd $SPARK_HOME/bin

$ ./pyspark Python 2.7.9 (default, Feb 10 2015, 03:28:08) [GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.56)] on darwin Type "help", "copyright", "credits" or "license" for more information. Using Spark's default log4j profile: org/apache/spark/log4j-defaults.properties 15/07/11 13:35:56 INFO SparkContext: Running Spark version 1.4.0 (中略) Welcome to ____ __ / __/__ ___ _____/ /__ _\ \/ _ \/ _ `/ __/ '_/ /__ / .__/\_,_/_/ /_/\_\ version 1.4.0 /_/

Using Python version 2.7.9 (default, Feb 10 2015 03:28:08) SparkContext available as sc, HiveContext available as sqlContext. >>>

Page 39: Why dont you_create_new_spark_jl

MLlibの使用■ランダムフォレストの実行

39

>>> from pyspark.mllib.tree import RandomForest, RandomForestModel >>> from pyspark.mllib.util import MLUtils

>>> # データファイルをロードしパースしてLabeledPointのRDDに変換 >>> data = MLUtils.loadLibSVMFile(sc, ... ’../data/mllib/sample_libsvm_data.txt’) >>> # データを訓練用とテスト用に分割 (テスト用は30%) >>> (trainingData, testData) = data.randomSplit([0.7, 0.3], seed=123) >>> # ランダムフォレストを用いた予測モデル構築 >>> model = RandomForest.trainClassifier( ... trainingData, numClasses=2, ... categoricalFeaturesInfo={}, numTrees=3, ... featureSubsetStrategy=‘auto’, impurity='gini', ... maxDepth=4, maxBins=32) >>> # テストデータに対してモデルを評価し,誤差を算出 >>> predictions = model.predict(testData.map(lambda x: x.features)) >>> labelsAndPredictions = testData.map( ... lambda lp: lp.label).zip(predictions) >>> testErr = labelsAndPredictions.filter( ... lambda (v, p): v != p).count() / float(testData.count()) >>> print('Test Error = ' + str(testErr)) >>> print('Learned classification forest model:') >>> print(model.toDebugString())

自然な記述が可能

Page 40: Why dont you_create_new_spark_jl

4. JuliaとSparkの 連携をめぐる動向

40

Page 41: Why dont you_create_new_spark_jl

JuliaとSparkの連携■ Spark.jl : JuliaでRDDの実装.

■ RPC(Remote Procedure Call)でJVMと連携.

41

https://github.com/d9w/Spark.jl

Page 42: Why dont you_create_new_spark_jl

JuliaとSparkの連携■ Spark.jlはRDDの実装が正しくない?

42

Page 43: Why dont you_create_new_spark_jl

JuliaとSparkの連携■ とりあえずインストール

43

$ julia julia> Pkg.clone("https://github.com/d9w/Spark.jl.git") INFO: Cloning Spark from https://github.com/d9w/Spark.jl.git INFO: Computing changes...

Page 44: Why dont you_create_new_spark_jl

JuliaとSparkの連携■ とりあえずサンプルコードの実行

44

$ julia julia> using Spark julia> # マスターサーバ julia> master = Spark.Master("127.0.0.1", 3333) julia> # ワーカーサーバの起動 julia> # Spark.load(master, “default_workers.json") julia> # マスターサーバーの初期化 julia> Spark.initserver(master)

julia> # RDDの生成と操作 julia> # 整数が並んだデータを読みこむ julia> rdd = Spark.input(master, "RDDA.txt", "int_reader") julia> filtered_rdd = Spark.filter(master, rdd, "number_filter") julia> results = Spark.collect(master, filtered_red) 0-element Array{Any,1}

1 2 … 10

!!!原因究明中

Page 45: Why dont you_create_new_spark_jl

JuliaとSparkの連携■ 他にも Spock.jl や Sparta.jl などがある.

45

Spock.jl

Sparta.jl

https://groups.google.com/forum/m/#!msg/julia-dev/-Ft7jaHLAec/ZfLo9uTAP1cJ

Page 46: Why dont you_create_new_spark_jl

JuliaとSparkの連携■ セグフォ(Segmentation Fault)が難関?

46

https://groups.google.com/forum/m/#!msg/julia-dev/-Ft7jaHLAec/ZfLo9uTAP1cJ

Page 47: Why dont you_create_new_spark_jl

Spock.jl■ Jey Kottalam(カリフォルニア大学バークレー校)が開発.■ JavaCall.jl を用いてJuliaからJavaのコードを呼ぶ.

47

https://github.com/jey/Spock.jl

Page 48: Why dont you_create_new_spark_jl

Spock.jl■ インストールとサンプルプログラムの実行

48

$ julia julia> Pkg.clone(“https://github.com/jey/Spock.jl.git") julia> quit()

$ cd $HOME/.julia/v0.3/Spock/

$ ln -s /usr/local/share/spark/lib/spark-assembly-1.4.0-hadoop2.6.0.jar lib/spark.jar

$ make mkdir -p build javac -Xlint -d build -cp lib/spark.jar: src//JuliaFunction.java src//JuliaObject.java jar cf lib/spock.jar -C build . julia test/runtests.jl 2> stderr.log Loaded /Library/Java/JavaVirtualMachines/jdk1.8.0_45.jdk/Contents/Home/jre/lib/server/libjvm.dylib

Page 49: Why dont you_create_new_spark_jl

Spock.jl■ サンプルプログラムの実行

49

julia> using Spock julia> using Base.Test julia> sc = SparkContext() julia> rdd1 = parallelize(sc, 1:10, 2) julia> collect(rdd1) 10-element Array{Int64,1}: 1 2 3 4 5 6 7 8 9 10

Page 50: Why dont you_create_new_spark_jl

Sparta.jl■ Andrei Zhabinski氏が開発しているライブラリ.

■ Pysparkを移植しようとしている.

50

https://github.com/dfdx/Sparta.jl

Page 51: Why dont you_create_new_spark_jl

Sparta.jl■ これも多分,RPCでJVMと連携.

51

using JavaCall

JList = @jimport java.util.List JArrays = @jimport java.util.Arrays JJuliaRDD = @jimport org.apache.spark.api.julia.JuliaRDD JJavaRDD = @jimport org.apache.spark.api.java.JavaRDD JJavaRDD_ = @jimport "org.apache.spark.api.java.JavaRDD\$" JRDD = @jimport org.apache.spark.rdd.RDD JJavaSparkContext = @jimport org.apache.spark.api.java.JavaSparkContext

Page 52: Why dont you_create_new_spark_jl

Sparta.jl

52

https://groups.google.com/forum/m/#!msg/julia-dev/-Ft7jaHLAec/ZfLo9uTAP1cJ

現時点ではほとんど空だけど すぐに戻ってきて進めるよ

(6月19日)

45%完了!!(7月11日時点)

https://github.com/dfdx/Sparta.jl

Page 53: Why dont you_create_new_spark_jl

Sparta.jl■ githubからインストール.

53

julia> Pkg.clone("https://github.com/dfdx/Sparta.jl.git") INFO: Cloning Sparta from https://github.com/dfdx/Sparta.jl.git INFO: Computing changes... INFO: No packages to install, update or remove INFO: Package database updated

Page 54: Why dont you_create_new_spark_jl

Sparta.jl■ パッケージの読み込み

54

julia> using Sparta Loaded /Library/Java/JavaVirtualMachines/jdk1.8.0_45.jdk/Contents/Home/jre/lib/server/libjvm.dylib

signal (11): Segmentation fault: 11 unknown function (ip: 362844852)

julia> using Sparta せまりくるセグフォの恐怖

Page 55: Why dont you_create_new_spark_jl

Sparta.jl■ テストを確認してみる.

55

using Sparta using Base.Test

# write your own tests here @test 1 == 1 ~

test/runtests.jl

Page 56: Why dont you_create_new_spark_jl

5. まとめとご提案

56

Page 57: Why dont you_create_new_spark_jl

まとめ■ Spock.jl や Sparta.jl などのパッケージ開発中.

■ セグフォ問題: Julia-Spark連携に立ちふさがる壁

■ そこで,

57

“Why don't you create new Spark.jl?”