MACHINE LEARNING Meetup KANSAI #3で機械学習を使った趣味サービスにおける工夫を紹介しました

最近、仕事のちゃんとした登壇が多かったので、趣味でやっているWebサービスにおける機械学習関連の工夫について発表してきました。基本的に昔ブログで紹介したエントリのまとめバージョンです。

趣味の余暇時間で開発しているサービスなので、いかに手間をかけずに済むかというのが大事です。テーマは怠惰!!

効率的なアノテーション方法

機械学習、データ数が多くないとなかなか精度が出ないですが、教師データをたくさん作るのも手間がかかります。そこで能動学習を使って効率的にアノテーションしていくツールを作ったので、それの紹介をしました。

精度の継続的なモニタリング

機械学習のコードでは、テストは通ってたけど実は本番では精度が下っていた...ということが起きがちです。きちんと計測して人間が目視で確認ということが毎回できれば理想的かもしれませんが、趣味でやっているサービスでは手間は最小限にしたいものです。

そこで、テストデータに対する分類性能をMackerelに継続的に送っています(Golangのライブラリを使っています)。グラフで可視化をするとどこで性能が劣化したか分かりますし、性能に対して監視ルールを入れることもできます。グラフにアノテーションをすることもできるので、deploy時のcommit idなどを書いておくと、どのcommitやPull Requestから挙動がおかしくなったかを突き止めやすいので便利です。

多様性を持たせた簡単な推薦方法

二値分類器でよい精度が出たとして、実際にユーザーに結果を提示することを考えると、スコア上位の結果は似たようなもので偏って困ってしまう場合があります。多様性のある推薦方法をお手軽にやるために、劣モジュラ最適化を使った方法を使っています。

組合せ最適化の問題を解くことになるわけですが、Golangで100行もない形で書けますし、貪欲法なので結果を出すのも速いです。貪欲法ではありますが、賢い人が性能の下限はこれより悪くならないよ!というのを証明してくれているので、ある程度安心して使うことができますね。

パイプラインジャングルと戦う

機械学習を使ったサービスは「データのクロールジョブ」「学習ジョブ」「予測ジョブ」など様々なバッチジョブが登場します。昔は「クロールが10分で終わるから15分後に学習ジョブをスタートさせる」「学習は20分で終わるから予測ジョブは30分後にスタートさせる」といった具合にcronやJenkinsで頑張ってジョブを整理していました。しかし、これだと予想より時間がかかった場合に思った挙動をしないとか、前段の処理が失敗した場合の考慮がうまくできず破滅しがちでした。

こういった機械学習に関連するパイプラインをいい感じに扱うツールがいくつかあります。

しかし、趣味でパイプライン管理ツールのお世話までやっているのはちょっとダルいです。そこで、AWSのマネージトサービスであるStep Functionsを使ってパイプラインの管理をすることにしました。

ステートマシーンを書けばよくて、図が出てくるのでどこで失敗したかが一目で分かりますし、失敗したときのretryなども簡単に指定できます。お手軽です。

Pythonではじめる機械学習 ―scikit-learnで学ぶ特徴量エンジニアリングと機械学習の基礎

Pythonではじめる機械学習 ―scikit-learnで学ぶ特徴量エンジニアリングと機械学習の基礎