LoginSignup
7
6

More than 5 years have passed since last update.

Spark mllibのPrefixSpan実装

Last updated at Posted at 2015-11-30

はじめに

この記事はApache Spark Advent Calendar 2015の7日目の記事です。

Spark 1.5から系列パターンマイニングアルゴリズムの1つ PrefixSpanがmllibに実装されました。

我々は文書や検索クエリー内のキーワードの並びから有益な情報を抽出する目的でPrefixSpanアルゴリズムに以前より興味を持っていました。

OSSで公開されているPrefixSpan実装はオンメモリー上でデータを処理するため、大規模データを処理することが難しかったのですが、Sparkを使った分散PrefixSpan実装が登場したことで、大規模データに対して系列パターン抽出が可能になりました。

今回は、このSpark mllibの分散PrefixSpan実装が、どのくらいのサイズのデータを、どのくらいの処理時間で処理できるのかを確認するために、日本語ngramコーパス [2] 1000万件から頻出形態素パターンを抽出する処理を実行させた。

動作確認、ベンチマーク

確認方法

Spark上で分散処理可能なPrefixSpan実装がどのくらい大規模なデータを処理できるかを確認するために、日本語ngram web corpusから頻出形態素列を抽出する処理を実行させた。

使用したngram corpusは[2]で公開されているもので

  • 7gram
  • 1000万件

のデータをcassandraにinsertし、それをsparkからアクセスしてPrefixSpanで頻出形態素パターンを抽出することにした。

gm | partition | content                               | freq
----+-----------+---------------------------------------+------
  7 |         0 |           ( は ち おうじ みなみ の え |   18
  7 |         0 |            ) から 桓武 天皇 の 時代 ( |   26
  7 |         0 | ) について 】 当 キャンペーン 終了 後 |   15
  7 |         0 |                  ( まゆ ) の 間 を 、 |   11
  7 |         0 |          3 分 ブン の 2 以上 イジョウ |   11
  7 |         0 |    ( PDF ファイル ) ( ダウンロード し |   46
  7 |         0 |          ( 偶然 かも しれ ない けど ) |   38
  7 |         0 |              1 ) 予定 価格 調書 案 の |   20
  7 |         0 |                  1 号 店 3 階 の 販売 |   11
  7 |         0 |        22 日 、 東京 地裁 八王子 支部 |   32

クラスター設定

使用したSparkクラスタ構成は以下である。

今回使用したクラスタは評価テスト用であり、処理時間性能の絶対性能を測定できるものではない。
あくまで、どの程度のデータを処理できるかを評価するためである。

  • Spark master 1台, Spark worker 7台構成
  • cassandra server 3台

マシンスペックは全台ほぼ同じで

  • CPU: 4コア
  • mem: 32GB

のマシンを使用した。

Sparkの設定は

  • standalone mode
  • worker memory: 4GB
  • driver memory: 10GB

とした。

処理時間

PrefixSpanのパラメータ

  • minSupportを 0.1〜 0.0001まで3段階に変化
  • maxPatternLength = 3に固定

とした。

またデータはcassandraからRDDとして読み込んだ後cacheさせ、cassandraへのアクセスオーバーヘッドは最小限になるようにした。

処理時間は総処理時間をlinuxのtime commandで測定した。

minsup min count time
0.1 1,000,000 1m34.274s
0.01 100,000 4m26.014s
0.001 10,000 4m18.359s
0.0001 1,000 30m35.717s

結果

minsupが小さくなればなるほど頻出itemの異なり数が大きくなり、それに伴い指数関数的に処理時間を大きくなることが予想され、実測値でもそうなった。1000万件の大規模データからcount >= 1000の頻出パターンをOOMなしに30分で抽出することができ、分散PrefixSpan実装の有効性を確認できた。

Spark mllib PrefixSpan実装概説

mllib PrefixSpan実装
https://github.com/apache/spark/blob/master/mllib/src/main/scala/org/apache/spark/mllib/fpm/PrefixSpan.scala

の処理フローを以下で概説します。

頻出itemの抽出とid化

PrefixSpan.rum methodで

  • 頻出itemの抽出
  • minCount以上の頻出itemのid化
  • 系列パターンの内部表現化


https://github.com/apache/spark/blob/master/mllib/src/main/scala/org/apache/spark/mllib/fpm/PrefixSpan.scala#L139
https://github.com/apache/spark/blob/master/mllib/src/main/scala/org/apache/spark/mllib/fpm/PrefixSpan.scala#L154

あたりで行われています。

頻出itemの抽出はword countと同じで、結果はdriverにcollectされています。

PrefixSpan本体処理 = getFreqPatterns

https://github.com/apache/spark/blob/master/mllib/src/main/scala/org/apache/spark/mllib/fpm/PrefixSpan.scala#L179
https://github.com/apache/spark/blob/master/mllib/src/main/scala/org/apache/spark/mllib/fpm/PrefixSpan.scala#L236

になります。

このmethod内で、分散PrefixSpanアルゴリズムが実装されています。

itemによる射影

が↑で実行されています。

https://github.com/apache/spark/blob/master/mllib/src/main/scala/org/apache/spark/mllib/fpm/PrefixSpan.scala#L271

prefixとpostfixを2重のflatMapでjoinさせて頻出prefixとその頻度を求めています。
この結果はこれもdriverにcollectされています。

ここが、分散PrefixSpanアルゴリズムのコアのように思います。

この処理の中で射影dbのサイズがサイズが小さいものは、
https://github.com/apache/spark/blob/master/mllib/src/main/scala/org/apache/spark/mllib/fpm/PrefixSpan.scala#L289
smallPrefixesとして保持されて、次のlocalPrefixSpan objectにより再帰的に処理されるようです。

各worker上でのlocalPrefixSpan.runの実行

に実行されています。

最終的な頻出パターンの抽出結果

でdriver上で保持されている頻出パターンと、最後に、各worker上のlocalPrefixSpan objectが抽出した
頻出パターンをRDDとしてunionして、返しています。

おわりに

以前より興味を持っていた分散PrefixSpanのSpark mllib実装を1000件の大規模データで動作確認を実施した。
動作確認前は、実際に処理できる不安な面を持っていたが、minsupがある一定以上の場合は十分高速に処理できることを確認できた。

大規模コーパスや検索クエリーから、頻出キーワードパターン、形態素列パターンの抽出にPrefixSpanを適用する場合

  1. 大規模データに対するPrefixSpan適用の困難
  2. 無意味な頻出パターンの抽出
  3. 情報が重複する、内包される頻出パターンの抽出

の3つの欠点があった。

  1. はSpark mllib PrefixSpan実装で解決できそうである。2,3に関しては、処理させる大規模データへの前処理、後処理で解決することが多かったが、PrefixSpanの拡張アルゴリズムにより、2., 3. を解決したいと考えている。 例えば
  • itemへの重要度ウェイトを付与して、そのウェイトにより抽出するパターンを制御する。
  • PrefixSpanをClosed系列パターンマイニングにまで拡張する。

などである。これらをSpark mllib PrefixSpanアルゴリズムに適用できればと考えている。

参考情報

[1] PrefixSpan: http://chasen.org/~taku/software/prefixspan/
[2] 日本語ウェブコーパス 2010: http://s-yata.jp/corpus/nwc2010/

7
6
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
7
6