読者です 読者をやめる 読者になる 読者になる

よしだのブログ

サブタイトルはありません。

Spark MLLib への最速の入り口! (と、インプレとJubatusとの比較)

機械学習、ビッグデータ Apache Spark IT、プログラミング

このエントリーは、Machine Learning Advent Calendar 2014 - Qiita の15日目の記事です。

まずはじめに、初心者向けの記事です。機械学習に興味があって、とりあえずレコメンドをやってみたいけど、数学とか線形代数とかわからないし、Spark も Hadoop も概要以上のことはわからないが、好奇心旺盛なあたなに向けて書いています!

Spark MLLib への入門の近道は、ズバリ Spark Summit 2014 のハンズオン資料です!Spark Summit 2014 で行われたハンズオンの資料はステップバイステップで実装でき、とっても分かりやすいです。唯一の難点は Scala か Python しかないことだけです!資料は、以下のURLから参照することができ、ハンズオンに必要な、当日配られた USB メモリに入っていたデータもスクリプトも全てダウンロードできるようになっています。ハンズオンは、MovieLens*1のデータを元にして、レコメンドできるようになります。

Movie Recommendation with MLlib

ただ、ハンズオンをこなすだけでもつまらないので、勢いでライブドアグルメのデータセットのデータでレコメンドができるように改造してみました。データは以下から。正規化されたテーブルごとに、CSV ファイルに出力されているものです。

livedoor Techブログ : livedoor グルメの DataSet を公開

かなり汚いですが、作成したコードも gist に公開しましたのでご参考までに。

https://gist.github.com/yoshi0309/33bd912d91c0bb5cdf30

というわけで、初心者がやってみて気がついた Spark MLLib の色々を本エントリではつらつらと書いていきたいと思います。また、以前ハッカソンで触らせてもらった Jubatus でも同じく実装してみたのですが、その比較も簡単に書いてみました。

チューニングと結果の評価について

基本的には、rank、num iteration、lambda の3つのパラメータをいじる形になります。ざっくり言うと、rank と num iteration は値を大きくすると精度が向上するがモデルの生成に時間がかかるようになります。lambda は、下に凸のグラフになり、値が小さいほうが精度が高くなるのですが、どこが一番よいかはトライ&エラーで探る必要があります。

あと、ハンズオンのコードに仕込まれている、精度を評価する RMSE の数値ですが、これは少ないほどよいのですが、いくつ以下なら良い、という値がありません。RMSE の値だけ見て、これなら良さそうだと思っていると、全然思ったものと違う結果になっている、ということになります。。

各パラメータの詳細な意味は、アルベルトさんのブログを参照してください。チューニングの話は2です。

カエルでもわかる!Spark / MLlib でやってみる協調フィルタリング(前編) - ALBERT Engineer Blog カエルでもわかる!Spark / MLlib でやってみる協調フィルタリング(後編) - ALBERT Engineer Blog

以下も参考に。Spark MLLib の勉強会のメモです。

勉強会メモ - Machine Learning with Apache Spark - よしだのブログ

ここまでは基本。以下は個人的な失敗談(笑)

チューニングは初めてだったのですが、最初に気がついたのは、とりあえず出力された結果が良いのか悪いのかさっぱりわかりませんでした(笑)。その時の感覚はレストランの名前がいっぱい並んだけど、それっぽいような、それっぽくないような・・・というひじょーーに曖昧な感覚でした。

チューニングの前に、やはりデータをエクセルなどに整理して、何をインプットにして、何が出力されたらOKなのかをまとめておく必要があります。理想的には。ライブドアグルメのデータセットもなかなかデータ量が多いので、一目で正解がわかるようにはならないのですが、少なくともエクセルに整理しておくだけで 全くのハズレはわかるようになります ので、チューニングの取っ掛かりには必ず必要です。

以下は、実際に私が作った Excel のスクリーンショットです。一番左の列がユーザーIDで、右に訪れたラーメン店で評価が一定以上のものを表示しています。テキストファイルのデータを DB にロードして、ジョインした結果を CSV に出力し、Excel に食わせました。「一蘭」「ラーメン二郎」「天下一品」に色付けをしておいて、その3店舗しか訪れていないユーザーXに次に何をレコメンドすべきかを推測できるようにしました。

つまり、Xさんに対して何かのレストラン名がレコメンドされた時に、この表と照らしあわせ、Xさんが行ったことのある、「一蘭」「ラーメン二郎」「天下一品」の、すなわち色がついていない、もしくは付いているけど少ない行のレストランがレコメンドされているとNGと判断できます。

f:id:yoshi0309:20141215233337p:plain

今回はサンプルデータを利用したので、DB → Excel という手が使えましたが、量によっては Redshift や BigQuery のような DWH などを使う必要や、サンプル抽出する必要がありそうです。

データのロード、SQL の作成、Excel へのインポート、トライ&エラー、MLLib に食べさせるデータを変える、などなど一番時間がかかりましたが、実データでは更に比較にならない時間がかかる気がします。実務でどのぐらいの時間をかけるものなのか、どのぐらいの頻度でチューニングするのか、計画は、など色々聞いてみたいですね。。。

Spark と MLLib について

  • Spark の API 自体が、関数型のメソッドや記述法( lambda / map / reduce / filter など ) を前提としているので、勉強を必要としました。ただ、Hadoop の MapReduce と比較すると、関数型の記述を覚えてしまえば非常に自由度が高くコーディングが簡単です。この辺りは、Spark の売りの一つだと思います。

  • 関数型の勉強をしつつコーディングしていて一箇所躓いたのが、変数のスコープです。map や reduce には関数を渡し、データを1つずつその関数で処理するのですが、基本的に関数はその関数内の変数しか使えませんので注意が必要です。

  • model は pickle に対応していないので、現状自前でserialize/deserializeを実装しないと保存できません。1.2.0 に対応されるよていだそうです。結構辛いですw

  • さらに加えて、model のトレーニングは後から訓練データをモデルに追加して、モデルをアップデートできるようにはなっていません。なので、web service を作ろうとした時には、若干トリッキーな作りになります。

Jubatus Recommendation との比較

アルゴリズムの細かい比較は素人なので出来ません(笑) 両方触ってみて気がついた違いを列挙してみます。

外部とのI/Fについて

  • Spark は基本的にバッチなので、サーバーが立ち上がるということはありません。基本的にバッチの処理の中で、トレーニングから予測まで全部行う必要があります。なので、一度のバッチ処理でトレーニングから予測までを行い結果を出力するまでを実装する必要がありますので、少しコード量は多くなりそうです。

  • Jubatus はサーバーが立ち上がります。外部のスクリプトからサーバーに接続してトレーニングデータを送ったり、予測をさせたりする構成になっています。なので、比較的、既存のシステムに組み込みやすい作りになっています。予測についても一度に全部出力する必要がなく、必要なときに問い合わせれば予測結果を得ることができます。

モデルのトレーニングについて

  • Spark は後からモデルにデータを追加して、インクリメンタルに更新することはできません。毎回トレーニングデータを全て食べさせてモデルを作成する必要があるので、リアルタイムレコメンド・・は難しそうです。

  • Jubatus はインクリメンタルにモデルのデータを追加することができます。したがって、利用者のアクションをリアルタイムにモデルに反映させて、予測する結果をアップデートさせることができます。

まとめ

  • Spark MLLib は、非常に読みやすく書きやすい API を備えています。関数型を知る必要はありますが、それさえ乗り越えればさくっとバッチ程度は簡単に作れると思います。

  • コーディングは簡単ですが、チューニングが素人ながらになかなか難しいです。一番むずかしいのは、予測結果が適当かどうかの評価です。DB や Excel 、スクリプトなどのツールを駆使するのはもちろんですが、予めインプットとあるべきアウトプットを整理できていると理想的だと思います。

  • Spark MLLib はバッチ処理です。トレーニングから予測までを一気通貫に行う必要があるので、システム組み込み時の外部I/Fには工夫が必要です。また、リアルタイムレコメンドはそのつくり上難しいと思います。

Learning Spark: Lightning-fast Big Data Analysis

Learning Spark: Lightning-fast Big Data Analysis

  • 作者: Holden Karau,Andy Kowinski,Matei Zaharia,Patrick Wendell
  • 出版社/メーカー: Oreilly & Associates Inc
  • 発売日: 2015/02/22
  • メディア: ペーパーバック
  • この商品を含むブログを見る

*1:有名な Netflix Prize で使用されたデータを公開できるように消毒されたデータセット。サンプルでよく使われる。