Scala製の機械学習フレームワーク「PredictionIO」

Pocket

こんにちは、エンジニアの渋江です。
前々からGitHubで気になってStarしてた割に中々触る機会がなかったので機械学習の勉強用として触ってみました。

PredictionIOとは

Spark上で動作するScala製のオープンソース機械学習フレームワークです。
以下のようなアプリケーションを作ることができます。
・アイテムのレコメンド(例えば、映画、製品、食品)
・ユーザーの行動を予測
・アイテムの類似性を識別
・アイテムのランキング

公式リポジトリ:https://github.com/PredictionIO/PredictionIO/

今回はレコメンデーションができる様になるまで公式ドキュメント(英語)を見ながら進めていきます。
前提としてMac上での操作になります。

PredictionIOのインストール


対話式でインストールしていきます。

$ bash -c "$(curl -s https://install.prediction.io/install.sh)"

どこにインストールするか聞かれるので任意の場所に保存しましょう。
vendorも同様のパスに置きます。

データストアとして以下の組み合わせを選ぶことになりますが、今回はMySQLを選択します。

1) PostgreSQL
2) MySQL
3) Elasticsearch + HBase

更新受け取りやメールアドレス設定はお好みで。

続けてSparkのインストール前の設定が始まります。
ディストリビューションを選択しろと言われるのでOtherを選択します。

1) Debian/Ubuntu
2) Other

インストールに数分時間がかかりますが、正座して待ちましょう。
MySQLは手動でインストールしておきます。

楽するためにProductionIOのパスを通しておきます。
.bashrcに追記します。

PATH=$PATH:/home/yourname/work/PredictionIO/bin

保存したら忘れずに最新を読み込んでおきます。

source ~/.bashrc

イベントサーバーをバックグラウンドで走らせます。

$ pio eventserver &

ステータスを確認します。

$ pio status

以下のように表示されればOKです。

...</p>

<p>(sleeping 5 seconds for all messages to show up...)
Your system is all ready to go.

エンジンテンプレートの作成


機械学習分野のいろんなエンジンのテンプレートが用意されています。

テンプレート:http://templates.prediction.io/

自分のユースケースにマッチしたエンジンを選択します。
今回はレコメンデーションのエンジンテンプレートを使います。
デフォルトでは協調フィルタリングアルゴリズムを採用しているそうです。

ss

MyRecommendationディレクトリに保存するようにします。

$ pio template get PredictionIO/template-scala-parallel-recommendation MyRecommendation
$ cd MyRecommendation

MyApp1の名前で実行します。

pio app new MyApp1

データの投入


デフォルトではレコメンデーションエンジンは評価と購入をサポートしているそうです。

訓練させるためにはより多くのサンプルデータを入れないといけません。
MyRecommendationディレクトリ内にあるdata/import_eventserver.pyがサンプルデータをインポートしてくれるプログラムなので、これを使って投入してみます。
PythonSDKを使ってストアするのでまずはSDKをインストールしましょう。
pythonは3系ではエラーが出たので2系にしました。

$ pip install predictionio

サンプルデータをdataディレクトリ以下に保存します。
今回のサンプルは映画データのようです。
先ほどのアクセスキーを使ってデータをインポートしてあげます。

$ cd MyRecommendation
$ curl https://raw.githubusercontent.com/apache/spark/master/data/mllib/sample_movielens_data.txt --create-dirs -o data/sample_movielens_data.txt
$ python data/import_eventserver.py --access_key アクセスキー

インポートに成功すると以下のように出力されると思います。

Importing data...
1501 events are imported.

エンジンをデプロイ


MyRecommendationディレクトリ以下にengine.jsonがあると思います。
engine.json内のappNameをMyApp1に修正します。

以下のコマンドでビルドします。
初回実行時は少し時間がかかります。
ログを出力させたくない場合は--verboseは外してください。

$ pio build --verbose

成功すると以下のように出力されます。

[INFO] [Console$] Your engine is ready for training.

以下のコマンドで学習させることができます。

$ pio train

成功すると以下のように出力されるはずです。
僕はメモリ圧迫しててスタックオーバーフロー起こしてしまいました…w
余計なアプリを落として再度実行すると以下ように出力されました。

[INFO] [CoreWorkflow$] Training completed successfully.

さてデプロイしましょう。

$ pio deploy

デプロイに成功すると以下のように出力されます。

[INFO] [HttpListener] Bound to /0.0.0.0:8000
[INFO] [MasterActor] Engine is deployed and running. Engine API is live at http://0.0.0.0:8000.
http://localhost:8000/にアクセスしてみましょう。

こんな感じのページが表示されると思います!
スクリーンショット 2015-07-08 20.33.33

レコメンデーションしてみる


user_idが1のユーザーに4つの映画をレコメンドしてみます。
jsonで{ "user": "1", "num": 4 }のように指定してリクエストするとjsonでレスポンスが返ってくるはずです。
リクエストもSDKを使えば送れますが、今回はcurlでリクエストしてみます。

$ curl -H "Content-Type: application/json" -d '{ "user": "1", "num": 4 }' http://localhost:8000/queries.json

成功すると以下のようにjsonでレスポンスが返ってきました。

{
    "itemScores": [
        {
            "item": "17", 
            "score": 10.006698289241443
        }, 
        {
            "item": "7", 
            "score": 9.955696127629967
        }, 
        {
            "item": "90", 
            "score": 9.096176394228518
        }, 
        {
            "item": "22", 
            "score": 7.554842530973965
        }
    ]
}

ベーシックな使い方はこんな感じだそうです。

もう少し調査してカスタマイズできるようになりたいなあ。