Jubatusハッカソンに参加して、イベントのレコメンデーションを作ってみた。
4日金曜日から5日にかけて、Jubatus ハッカソンに会社の後輩と2人で参加してきました!
今回のハッカソンは、初心者向けとあったので Jubatus は未経験でしたが勢いで参加してきました。ハッカソンへの参加はもちろんのこと、Jubatus 自体も初めてでしたが、結果から言えば、クオリティはさておき動くものを作ることができ、なんとかプレゼンまでこぎつけることが出来ました。とても有意義かつ楽しいイベントでした。主催者の皆様、ありがとうございました!
というわけで、Jubatus 始めたいけどどうよ、と思っていらっしゃる方には Jubatus のファーストインプレッションをお届けできるように、ハッカソンって怖くない?と思っていらっしゃる方には、ハッカソンの楽しさをお届けできるようなエントリにしたいと思います。
作ったものの紹介。
画面はこんな感じ。チーム Paper です。
Connpass というイベント支援サイトのイベント情報をレコメンドするサイトです。あとで読むサービスの Pocket のデータを元に、レコメンドするイベントを決めるので、本当に興味があるイベントのみをレコメンドする仕組みを目指しました。
処理の流れとしては Pocket から利用者のクリップした記事の情報をダウンロードし、利用者ごとに分類モデルを作成します。モデルに対して connpass から取得したイベントのタイトルを1つずつ投げつけ、興味あり/なしを推定します。
利用した環境は以下のとおり。細かいバージョンは記録してません・・すいません。
- Ruby on Rails
- Postgres
- Bootstrap
- Python
- Jubatus
- Mecab (結局使っていないが)
モデルの作成と推定はバッチでやっているのですが、Gists に上げたのでよろしければご参考までに。かなりゴリゴリで汚いですがw
Connpass Event Classifiere using Pocket - Jubatus Hackathon - Team Paper.
推定の処理について
まず、モデルの作成は Pocket からダウンロードしてきた記事のタイトルを「興味あり」として、はてブから拾ってきたビジネスやエンタメのタイトルを「興味なし」として、2つの分類を利用者ごとに作成しました。パラメータはタイトルだけで、つまりタイトルの類似度だけでレコメンドされる形になります。また、タイトルは、Mecab による形態素解析も試してみましたが、なぜか 3-Gram が、スコア含め、うまく推定されるようでした。
今考える、改善できるポイントとしては以下のとおりです。
データソースが異なる (Connpass と Pocket) だと、取れる値が全く異なるので、パラメータを増やすことが難しいことがわかりました。結果、タイトルだけになっており、例えば、利用者の居住地区や開催される曜日などは全く考慮に入っていません。学習データと推定対象のデータは同じソースのものが精度が高くやりやすいと思います。
「興味なし」のデータの集め方に工夫が必要だなと思いました。今回は、上記でも記載しましたがデータソースが異なったので、分類を利用しました。*1その場合、「興味あり」は Pocket のデータで良かったのですが、無しは適当に集めてきたデータになってしまいました。集め方には工夫が必要です。
適当に集めてきたので、興味ありとなしの両方に同じキーワードが含まれているデータが結構あって、うまくレコメンドされないケースがありました。
まー、ハッカソンの時間内ではいずれも厳しいですが。
ハッカソンについて
Jubatus を使うこと、時間制限がある、ということ以外は目立った制限はありませんでした。とにかくどっぷり開発することができる、コーディングが好きな人にはたまらないイベント形式です。
また、徹夜も可能で*2、夜食まで用意いただいておりました!発表も辞退が可能なので、あまり初心者も気負わずにトライすることが出来ました。あと、普段の勉強会などと違い、皆で黙々と開発する、チーム単位ですが皆が発表するというのは結構面白かったです。
最終発表ですが、参加者のレベルがばらばらで、我々のような初心者チームから、かなりの上級者までいらっしゃいました。ハッカソンは、最後の成果物で評価されるわけですが、正直勝ち目なんかありませんでしたw 逆に、ハイレベルな成果物と発表が聞ける、またとない機会だったわけです。多分、ハッカソンじゃないと発表しなさそうな内容も飛び出してきてびっくりでした。*3できれば、上位入賞者の詳細を別途勉強会でプレゼンしないですかね?
Jubatus について
Jubatus は、ハッカソンの当日にインストールをやって、チュートリアルをコード含めざっと見てみて、感触をつかんだレベルで突入しました。ブログのエントリにも出来ない程度ですが、一応、Amazon EMR やローカルで Mahout の Recommender を動かしたことはありました。その時と比較すると、ドキュメントが日本語であれだけしっかりと揃っていたので、とにかく立ち上がりが早くて楽でした。また、clinet ライブラリ含めて揃っていたので、本当に集中すべき、前処理、後処理、チューニングに時間を使うことができました。
正直なところ、Random Forest 実装して欲しいなーとか、プロダクションレディーはいつやねんとか、パフォーマンスってどうかとか、海外含めた利用者の広がりってどうとか、気になるところはたくさんあったのですが、これだけ簡単に動かすことができちゃうと、まあ、機械学習の初心者は Jubatus 触っとけでいいと思いました!
あと、メモ的にちょっと気になったところを残しておきます。
一度に複数のモデルをつくろうとするケースにはあまり向いていないような気がしました。モデルを管理する機能が save / load ぐらいしか見当たらなかったので、作ったスクリプトでは、毎回ユーザーごとにモデルを消して、再度1から学習させ、推測するのループを回していましたが、データやユーザーの件数によっては非現実的な作りです。save / load をかわりに繰り返す、が正解だとおもうのですが、できれば save / load 不要で同時に扱えるようになるといいなと思います。そんな使い方は普通しない?
精度のチューニングが難しかったなと思います。メソッドと、n-gram/mecab、sample_weight/global_weight、regularization_weight を弄る、ということを繰り返していたわけですが、理屈がわからないので、とにかくトライエラーしかありませんでした。AROW や NHERD などの仕組みを勉強するしか無いのでしょうか?ちょっとハードルが高くて正直つらいな〜。。
色々と書かせてもらいましたが、こんなに書けるようになったのはハッカソンと Jubatus のクオリティの高さの証左かなと思っています。機会があれば、どんどん使っていきますので今後共よろしくお願いします!次回、イベントも楽しみにまっています。