Successfully reported this slideshow.
Your SlideShare is downloading. ×

2014 11-20 Machine Learning with Apache Spark 勉強会資料

Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad

Check these out next

1 of 42 Ad

More Related Content

Slideshows for you (20)

Similar to 2014 11-20 Machine Learning with Apache Spark 勉強会資料 (20)

Advertisement

More from Recruit Technologies (20)

Recently uploaded (20)

Advertisement

2014 11-20 Machine Learning with Apache Spark 勉強会資料

  1. 1. Spark ベストプラクティスと Linear Regression with MLlib のチュートリアル 株式会社リクルートテクノロジーズ アドバンスドテクノロジーラボ Yu Ishikawa 1
  2. 2. 自己紹介 • 所属 – 株式会社リクルートテクノロジーズ – アドバンスドテクノロジーラボ • 現在の業務 – Apache Spark の機械学習ライブラリMLlib へのコントリ ビュート • バックグラウンド – 某SNS サービスの大規模データ分析基盤構築,サービス のデータマイニング,社内コンサルティングなど 2
  3. 3. Apache Spark コミュニティと 協力して取り組んでいること • Distributed Divisive Hierarchical Clustering • Distance Functions (Breeze) • kNN • Bootstrapping (Bag of Little Bootstraps) • Canopy K-mean • Bregman Divergence on K-means 3
  4. 4. 発表のねらい • Spark を扱う上での基本的な考え方を学ぶ • Logistic Regression をScala で処理する方法を学ぶ – アルゴリズムの詳細は解説はしません 4
  5. 5. Agenda • Spark の基礎知識をおさらい • Spark ベストプラクティス • Logistic Regression with MLlib • Spark 1.2 のMLlib の動向 5
  6. 6. RDD, Partition, Cache SPARK の基礎知識をおさらい 6
  7. 7. RDD:Resilient Distributed Datasets • DAG 型実行計画により,in-memory 分散処理の フォールトトレラントを実現 – Resilient: 回復力のある,すぐに立ち直れる – DAG: Directed Acyclic Graph,無閉路有向グラフ 7 Cited by Matei Zaharia et al. “Resilient distributed datasets: a fault-tolerant abstraction for in-memory cluster computing”
  8. 8. Lazy Evaluation 8 // load data from Amazon S3 val data = sc.textFile(“s3n://bucket/data/access-log.txt”) // transformations val errors = data.filter(line => line.contains(“error”)) val splitedData = errors.map(line => line.split(“t”)) val elements = splitedData.map(x => x(3)) // action elements.count この段階では処理は 実行されていない この段階になって初 めて処理が実行 RDD のAPI はTransformations とActions に分類 map() , filter() などのTransformations は遅延評価 count() などのActions が評価されたタイミングで実行計画を立てて処理される
  9. 9. Partitions in RDD • RDD の「分割数」≒利用できるCPU コア数 • 一般的に利用できるCPU コア数x 1 ~ 3 を設定するのがよい • Partition を増やしすぎても遅くなるのでバランスが大事 val rdd1 = sc.textFile(file, 2) val rdd2 = rdd1.map(x => x + 10) rdd1 9 rdd2 val rdd1 = sc.textFile(file, 4) val rdd2 = rdd1.map(x => x + 10) rdd1 rdd2 Max CPU Cores: 2 Max CPU Cores: 4
  10. 10. Cacheとは? • クラスタ横断でメモリ上に処理データをキャッシュす ることができる • 繰り返し「再利用される」データに活用すると効率的 に処理できる • 11000000 レコードのデータのカウント(160 cores) – キャッシュなし:7.48 [sec] – キャッシュあり:0.40 [sec] 10 Spark はCache の活用次第でパフォーマンスが 大幅に変化するので注意!
  11. 11. Cacheされるタイミング(1) 11 内部処理の違いについて考えてみてください val rdd1 = sc.textFile(file, 2) val rdd2 = rdd1.map(x => x + 10) rdd2.count rdd1.cache val rdd1 = sc.textFile(file, 2) rdd1.cache val rdd2 = rdd1.map(x => x + 10) rdd2.count
  12. 12. Cacheされるタイミング(2) 12 Cache はAction の処理をしながら行われる val rdd1 = sc.textFile(file, 2) val rdd2 = rdd1.map(x => x + 10) rdd2.count rdd1.cache val rdd1 = sc.textFile(file, 2) rdd1.cache val rdd2 = rdd1.map(x => x + 10) rdd2.count この時点ではrdd1 は厳密に はキャッシュされていない rdd2 のcount をしながら, rdd1 をキャッシュする
  13. 13. SPARK ベストプラクティス 13
  14. 14. Cacheの活用ポイント(1) 14 cached filter val rdd1 = sc.textFile(file, 4) rdd1.cache val rdd2 = rdd1.filetr(x => x % 5 == 0) val rdd3 = rdd2.map(x => x + 10) rdd3.count rdd3.count map rdd1 rdd2 rdd3 2回目のrdd3.count でも rdd1 -> rdd2 -> rdd3 の処理が行われてしまう
  15. 15. Cacheの活用ポイント(2) 15 cached rdd4 rdd1 rdd2 rdd3 • 適宜キャッシュしないとrdd1 からのDAG 処理が 適応されてしまう • 特に機械学習では複雑な繰り返し処理をするよ うなアルゴリズムもあるので,キャッシュのタイミ ングがパフォーマンスに大きく影響する rdd1 rdd2 rdd3 rdd4 例:データを再帰的に分割しながら処 理をしていくようなアルゴリズム
  16. 16. Cache の状態の確認 • WebUI からSpark のRDD のキャッシュ状態などを確 認できる – http://${SPARK_MASTER}:4040/storage/ 16
  17. 17. 利用データの圧縮形式 • Gzip などで圧縮されたファイルをSpark で読み込む と,いくらPartition 数を増やしても1プロセスでしか 処理することができない • Gzip の分割不可能の性質が原因 – Hadoopをやったことある方にはお馴染み 17 • 元データを予め解凍するか • Spark で1回なめて,そのデータをキャッシュするなり書 き出すなりする必要がある
  18. 18. Data Locality • Hadoop と同様に処理を行うマシンと,データがあるマシンが 同じ方が処理効率がよい • Cache と同様にWebUI から確認できる – PROCESS_LOCAL で処理されているようであればよい 18
  19. 19. Master (Driver) に負荷を掛けない • RDD のcollect メソッドは,RDD をScala のコレクションに変換 • 巨大なデータを集約しようとするとDriver が動いているマシ ンのメモリに乗り切らない • データを確認したいときは,take() やtakeSample() • 同様の理由で,countByKey(), countByValue(), collectAsMap() でも気をつける 19 Don't copy all elements of a large RDD to the driver!!
  20. 20. IntelliJ のimport 最適化問題 • flatMap() などのTransforms メソッドは, org.apache.spark.SparkContext 以下に配置されてい る • IntelliJ のimport 最適化では, `org.apache.spark.SparkContest._` を自動追記してく れない • 手でimport 文を書く必要がある 20 import org.apache.spark.SparkContext._ rdd.flatMap(x => (1 to 10).map(i => x))
  21. 21. LOGISTIC REGRESSION CLASSIFICATION WITH MLLIB 21
  22. 22. Logistic Regression with Spark • Logistic Regression (Classification) – 二項分類の予測モデルの一種 – Regression のアルゴリズムも用意されている • Apache Spark 1.1 ではSGD (確率的勾配降下法) に対応したアルゴ リズムのみTop-Level API で利用できる – L-BFGS 法はTop-Level API として直接は扱えない • LogisticRegressionWithSGD のパラメータ(*: 必須パラメータ) – * Input: (ラベル,特徴量のベクトル)のRDD – * numIterations: Gradient Desent を実行する回数 – stepSize(default: 1.0): SGD の – miniBatchFraction(default: 1.0): SGD の1回のiteration で利用するデータ の比率 – initialWeights(default: ): 初期値の重みベクトル 22
  23. 23. モデル構築のイメージ図 23 Logistic Regression Model 予測したい特徴量 (1.0, 4.1, 3.0, 1.1) Label: 1, Features: (1.0, 4.2, 3.2, 1.2) Label: 0, Features: (0.1, 2.4, 8.2, 4.6) Label: 0, Features: (0.1, 2.3, 8.1, 4.2) Label: 1, Features: (1.2, 4.1, 2.8, 0.9) Train 訓練データ 0 or 1 Predict
  24. 24. 二項分類器の評価方法 • Spark は二項分類器を評価するためのクラスがある – BinaryClassificationMetrics • BinaryClassificationMetrics で算出できる値 – Area Under the ROC curve • 最大値:1のときがモデルとして最も良い • 最悪値は0.5 のときで,ランダムな判別を行ったときと同じ – Area Under the Precision-Recall curve 24
  25. 25. 実験概要 25 S3 CSV 7.5GB Spark Cluster on EC2 3.2GB parse duplicate X30 105.2GB Test 73.2GB Train 32GB 2/3 1/3 Evaluation Logistic Regression Model K-分割交差検証(K = 3)
  26. 26. Spark Cluster スペック • Cluster – Total CPU cores: 160 – Total Memory: 1195.0 GB • Master – Instance Types: r3.large – Compute Units: 6.5 (2 core x 3.25 unit) – Memory: 15.25GB • Slaves (# Instances: x5) – Instance Type: r3.8xlarge – Compute Units: 104 (32 core x 3.25 unit) – Memory: 244GB – Spot Biting: $0.35 / hour 26
  27. 27. 利用したデータ • 利用元 – Baldi, P., P. Sadowski, and D. Whiteson. “Searching for Exotic Particles in High-energy Physics with Deep Learning.” Nature Communications 5 (July 2, 2014) – http://archive.ics.uci.edu/ml/datasets/HIGGS • 二項分類のデータ • データサイズ:7.5GB • レコード数:11000000 • Number of Attributes:28 • Sample Data:(指数表現されている…) 27
  28. 28. 処理手順の概要 1. S3 上のファイルをSpark で読み込んで扱える形式に変換 2. デモ用にレコード数を30倍に増やす 3. (K-分割交差検証で)Logistic Regression のモデルを構築 4. 訓練したモデルにテストデータを当てはめて正解率とArea Under the ROC curve を算出 28
  29. 29. 処理手順:S3 上のファイルをSpark で読み込んで扱える形式に変換 29 // Loads a CSV file from Amazon S3 val origin = sc.textFile(“s3n://your-bucket/HIGGS.csv”, 160) // Converts Strings to Doubles val data = origin.map(_.split(",")) カンマで分割 .map { array => array.map(java.lang.Double.parseDouble(_))} .map { array => val label = array(0) val features = Vectors.dense((1 to (array.length - 1)).map(array(_)).toArray) new LabeledPoint(label, features) } 文字列をDoubleでパース Logistic Regression 用のクラスに変換
  30. 30. 処理手順:デモ用にレコード数を30倍に増やす • flatMap() を利用することでデータ量をコントロール できる – (Scala) List(0,1,2).flatMap(n => List(n,'A'+n)) –  List(0, 65, 1, 66, 2, 67) 全く同じデータにならないように1% ランダム誤差を加える 30 data.flatMap { point => (1 to 30).map { i => val newFeatures = point.features.toArray.map(x => x + (0.01 * math.random * x)) new LabeledPoint(point.label, Vectors.dense(newFeatures)) } }
  31. 31. 処理手順:K-分割交差検証(K = 3)でLogistic Regression のモデルを構築 (予測ラベル,正解ラベル)のタプルのRDD を作成 31 // Attaches index number to each record val indexed = data.zipWithIndex().map { case (lp, idx) => (lp, idx % 3)} // Extracts the training data val fit = indexed.filter { case (lp, idx) => idx % 3== 0}.map { case (lp, idx) => lp} // Extracts the test data val test= indexed.filter {case (lp, idx) => idx % 3!= 0}.map {case (lp, idx) => lp} // Trains a model val model = LogisticRegressionWithSGD.train(fit, subIterations = 100) // Predicts the test data val predicted = test.map { point => val predictedLabel = model.predict(point.features) (predictedLabel, point.label) }
  32. 32. 処理手順:訓練したモデルにテストデータを当てはめて正解率とAUC を算出 32 // Calculates a accuracy ratio val correct = predicted.filter { case (p, l) => p == l}.count / predict.count.toDouble println(s"Correct Ratio: ${correct}") // Calculates a Area Under the Curve val metric = new BinaryClassificationMetrics(predicted) println(s"AUC: ${metric.areaUnderROC()}") 2値分類器を評価するためのクラス
  33. 33. 実験に用いた条件と結果 • 実験に用いたデータ – 全体:330,000,000 レコード(105.2GB) – 1回の訓練データ:110000000 レコード(32 GB) – 1回のテストデータ:220000000 レコード(73.2GB) • 実験に利用したパラメータ – numIterations: 100 • 処理時間 – 平均訓練時間:75.9[sec] – 平均テスト時間:10^-4[sec] • 評価 それほど良い結果が得 – 平均正解率:0.61 – 平均Area Under the ROC curve: 0.60 33 られなかったが… 処理速い!
  34. 34. SPARK 1.2 のMLLIB の動向 34
  35. 35. Spark MLlib の課題 • Kmeans などの距離関数はEuclidean Distance のみ サポート – OpenNLP のScala 移植のBreeze で距離関数を実装 • Top-Level API が一貫していない • アルゴリズムによって実装品質がバラバラ 35 リファクタリングと新規機能追加で 卵が先か鶏が先かのような状況が起きているので コミュニティを主導して交通整理する必要がある
  36. 36. Spark 1.2 MLlib で注目のissue • [SPARK-3530] Pipeline and Parameters – scikit-learn の`fit`, `predict` のような一貫性API に向けた取り組み – 各アルゴリズムの対応は1.3 以降のマイルストーンになると思われる – [SPARK-1856] Standardize MLlib interfaces が1.3 のマイルストーン • [SPARK-1545] Add Random Forest algorithm to Mllib – Decision Tree に,ようやくRandom Forest が追加 – 通常のDecision Tree はRandom Forest のnumTree = 1 で実装 • [SPARK-3486] Add PySpark support for Word2Vec – 1.1 系のSpark のWord2Vec はスケールしにくいし,機能として不十 分 – 1.2 系以降で処理の改善と機能拡充が期待 36
  37. 37. [SPARK-3530] Pipeline and Parameters • 簡単にデータの処理フローを定義できる – ノーマライズ – 主成分分析による次元圧縮 – LogisticRegression 37
  38. 38. 今日最低限持って帰っていただきたいもの • Spark で処理を効率化するにあたって最低限知って おいていただきたいことは,RDD のPartition 数と Cache • Cache はタイミングが重要 – Lazy Evaluation によりCache はRDD のActions API が実 行されているときに行われる • MLlib なら数行程度で機械学習が使える – 大規模データも高速に処理できる 38
  39. 39. Useful Resources • databricks/learning-spark – https://github.com/databricks/learning-spark – O’reilly のLearning Spark のサンプルコード • databricks/spark-knowledgebase – https://github.com/databricks/spark-knowledgebase – Spark のパフォーマンスチューニングなどの簡単な紹介がある 39
  40. 40. リクルートテクノロジーズ アドバンスドテクノロジーラボでは 人材を募集しています! 興味のある方は懇親会でお声掛け下さい 40
  41. 41. ご清聴ありがとうございました 41
  42. 42. Q&A 42

×