[レポート] The Art of Smart Channel #linedevday_report
せーのでございます。
2019年11月20日(水)・21日(木)にグランドニッコー東京 台場でLINEのデベロッパーカンファレンス「LINE DEVELOPER DAY 2019」が開催されました。
本記事は、セッション「The Art of Smart Channel」をレポートします。
スピーカー
- 渡邉 直樹氏 [LINE AD Dev 1チーム Manager]
セッション概要
Smart Channelは、LINEのトークリストの一番上の部分に表示されています。ここに何が表示されるのかは、実は人それぞれに違います。その人がどんな情報を求めているのか、何が今一番価値ある情報かを推測して届けるのがコンセプトです。システムの中心機能はリアルタイムレコメンデーションなのですが、実はLINEの中でも新たな挑戦をいくつもしています。単一のサービスのレコメンデーションだけではなく、LINEに存在する沢山のサービスからコンテンツをあつめてきて、リアルタイムでランキングし、その中から1件を選択して表示しています。これはLINEでも初めての試みです。このサービスの実現のために、私達は2層のレコメンデーションレイヤーを用意しています。1層目は各サービスに特化したレコメンデーションの生成ロジック、2層目は沢山のコンテンツを扱う全体最適化のレイヤーです。Smart Channelの中核となるCRS(Contents Recommender Service)では全体最適の為にOnline Bandit Algorithmを中心に様々な工夫をしています。本セッションでは、トークリストからの膨大なトラフィックを安定的に処理しながら、Machine learningをどのようにインテグレーションしているのかを中心にお話したいと思います。Machine learningに関連する話が中心になりますが、個々のロジックの詳細ではなく、システムのコンセプトと、どのように構築しているかの話を中心にさせていたきますので、Machine learningの専門的な知識がなくてお楽しみいただける内容となっています。
レポート
- LINEのトーク画面の上に表示されているSmart Channelはユーザ一人ひとりにパーソナライズされている
- 内容はスタンプ、ニュース、天気、漫画など広く及ぶ
- 外国ではその国のスタッフがその国のユーザに合うようにコンテンツを変更している
- コンセプト
- LINEにある様々なコンテンツから情報を集めてきて、その場その時でユーザに合うように表示している
- 複数のコンテンツを集めてリアルタイムに表示しているレコメンデーションは初めて
- アーキテクチャ
主に5つのコンポーネント
- Importer: LINEのコンテンツを集めて送る
- CRSEngine: Contents Recommend Service。アプリからのリクエストに対して適切なコンテンツを返す
- Event Tracker: クリックなどのフィードバックを返す
- Joiner: MLで使いやすい形に変換する
- Learning worker: 機械学習する
- 2つのレイヤーによるパーソナライズ
- Layer #1: 各コンテンツからレコメンドされた情報
- Layer #2: 提供されたコンテンツを全体最適化する
- Layer #1
- Importerの役目
- Mapping Provider: どのユーザにどのコンテンツを表示するかというマッピング
- Data Provider: 現在のリアルタイムなコンテンツ情報
- ImporterはMapping ProviderからNotificationを受けてユーザーとレコメンドされるコンテンツの組み合わせ情報を取得する。
- Importerはその組み合わせのレコメンド情報の詳細をDataProviderに取りに行き、Redisに保存する。
- Mapping Providerは1日1回程度のバッチ処理だが、Data providerはリアルタイムで情報が更新されるために分けている
- Layer #2
- 対象となるユーザにその時どのコンテンツを提供するのがベストか、というのは難しい問題
- 解決の為に「Bandit Algorithms」を採用した
- スロットマシンでコインの数を最大化するために作られたアルゴリズム
- Bandit Algorithmsの特徴
- 複数のアーム(スロットを回すときのバー)の中から1回にどれか一つのアームが引ける
- どのアームを引けば報酬(reward)が一番高いのかはわからない
- 今課題に置き換えるとアームが選択するコンテンツ、報酬はユーザの満足となる
- A/Bテストとの違い
- どのアームがベストなのかを探る行為(探索)が終わったら、その後は全てそのベストなアームのみを引き続ける(活用)
- Bandit Algorithmは1回の探索ごとにフィードバックをもらい、その結果によって動的に次に引くアームを切り替える
- 探索しながら活用する形。学習が進めば正しい活用に収束していく
- どれくらいの割合で活用に移っていくかはBandit Algorithmsの実装に依存する
- Smart ChannelでのBandit Algorithmsの実装
- LinUCB
- Bayesian Liner Regression
- Bayesian Factorization Machines
- Bayesian Neural Factorization Machines (開発が終わった所)
評価の方法
- クリックしたとき: ポジティブな反応
- 何もしなかった時: フラット(天気など見るだけで満足するコンテンツのもあるから)
- Xボタンで消された時: ネガティブな反応
- 10分待って何もボタンがクリックされなければフラットと判断
実装方法
- 表示時に10分のタイマーをつけてKafkaに登録
- クリックやXボタンを押された時は別のKafka => Redisに登録
- タイマー終了時にRedisを見に行き、何もなければフラット、あればそのリアクションを採用する
全体最適の方法
- ユーザ属性ごとにコンテンツ情報に対する反応を学習してスコアを比較する
- 例えば天気であれば天気が崩れるとスコアが上がる傾向
- 傘を持っていく、交通機関の確認など関心が高くなる
- 一番スコアが高くなるのは「晴れのち雪」など途中で天気が変わる場合
学習時に工夫していること
- アプリからくる大量の情報を安定的に処理すること
- 膨大なトラフィックに対応するために処理を分散すること
- 一部の処理は分散すると効率が悪くするのであえて分散させない
- ユーザからのクリックなどのデータは膨大なので一旦ロードバランシングさせる
- データがよく貯まるアームは分散して処理をする
- データが貯まらないアームは一つで処理をする
- K平均法でパーティション分けをして、同じパーティション、同じアームのコンテンツは同じインスタンスで処理をする
- パーティション分けまでがリアルタイム処理となり、学習からは非同期処理にて行う
- 学習結果をリアルタイムな処理と同期させるためにパラメータサーバというのを一つ挟む
- リアルタイム処理と非同期処理では言語も違う
- リアルタイム処理はJava、非同期処理は学習に得意なPythonで書いてあり、お互いはAPIでつながっている
オペレーションと運用
- テスト環境にはログが少ない
- プロダクション環境でやるしかない
- レコメンデーションは何が正解かがわかりにくい
- Gradual Rollout
- 全ユーザではなく特定のユーザにのみテストする
- 管理のためにLibraというツールを使っている
- 良い反応: クリックの数が多く、☓を押された(ミュート)数が少なくなればいい
- クリック/ ミュートをスコアとしてKPIの指標としている
Banditの弱点
- 学習が始まるまで10分かかる(reward): 初期の探索時間
- 年代で分けている(収束しないから): ユーザごとに変更したい
- クリックされたCTRとミュートのCTR(XCTR)をユーザ属性として使う
- 各コンテンツの今までのCTR、XCTRを参考情報として使う
今後の計画
- 生活情報
- 地震、災害などの生活情報の追加
- Bandit API
- BanditシステムをAPIとして提供することで別システムにも使いやすくする
- レコメンド情報をSmart Channel以外にも提供する
- LINE Walletにクーポン情報をレコメンドする
- 提供元の企業にAPIを提供する
- 場所情報の追加
- 旅行先でも今いる場所の天気を表示させる
- Beacon
- 特定の場所でのみ見られるコンテンツの提供
まとめ
LINEのトーク画面の上にあるやつってSmart Channelと言うんですね。Bandit Algorithmというのは強化学習でよく使われる手法でA/Bテストと違って正解を探りながら徐々に活用していくので効率的な手段だと思います。
みなさんも自分にどんなコンテンツが最適と判断されているのか、注目してみてはいかがでしょうか。