AbemaTVにおける推薦システム

福田鉄也氏(以下、福田):ありがとうございます。このセッションでは、AbemaTVの裏側で動いてる「推薦システム」について、簡単ではありますが紹介したいと思います。

まず初めに、簡単に自己紹介させてください。名前は福田鉄也と言います。

サイバーエージェントには2年ちょっと前の2016年6月に中途で入って、以降は「秋葉原ラボ」という組織で「推薦システム」の開発とか運用をしています。

ついでに、サイバーエージェントと「秋葉原ラボ」ついても簡単に紹介します。

まずサイバーエージェントなんですが、事業内容としては大きく4つやっていて、メディア事業とインターネット広告とゲームと、スタートアップに分かれています。

「秋葉原ラボ」は、このうちのメディア事業部門の研究開発組織という立ち位置になっています。メディアサービスの具体的なものとしては、AbemaTVがあって、それ以外にもAmebaというブログを中心としたサービスであったりとか、音楽配信サービスのAWAとか、マッチングサービスの「タップル誕生」とかがあります。

「秋葉原ラボ」がこういったサービスのなかで何をしているかという部分なんですけれども、各サービスから生成されている大規模なデータの収集とか蓄積とか処理のための基盤を持っていて、そのうえでデータの分析とか機械学習とかを使ったデータの活用とかをやっています。

AbemaTVともいろいろな面で連携していて、例えば上に書いてあるような、ユーザの行動ログのトラッキングとか、集計のための基盤システムを提供したりとか、そういったデータを使ったレポーティングとか分析だったりとか、あとはこういったデータを使うためのプロダクトとして、本日お話ししますけど、「推薦システム」や検索まわりの基盤システムとかの開発・運用もしています。

本題に入ります。本日の内容ですけれど、最初にAbemaTVというサービス自体についてと、そのサービスの中のどういった部分で「推薦システム」が使われているかについてお話しします。次に、AbemaTVで使っている「推薦システム」のアルゴリズムとかシステム構成みたいなところについて紹介します。

あと、今後の展望についてお話しして、最後にまとめというかたちで進めていきます。

AbemaTVにおける推薦システム

ではまず、最初の話から入ります。AbemaTVの説明ですが、今日はすでに100回くらい聞いているかもしれないんですけれど、サイバーエージェントとテレビ朝日が共同で展開しているサービスで、インターネットテレビ局という位置付けです。

中身はこの言葉どおりのものを想像していただければよくて、ニュースとかドラマとかアニメみたいないろんなチャンネルがあって、そのチャンネルの中でいつも放送されている番組が決まってて、アプリケーションを開くとその番組が観れる感じになっています。

あと他にもう1つ、Abemaビデオという機能があります。

こちらはサブスクリプション型のVideo on Demandのサービスになっていて、一部の番組は無料で観れたりとか、あとは月額いくらかを払うと動画が観れるかたちになっています。あと、こちらは放送枠という概念はなくて、好きなタイミングで好きな番組が観れるようになっています。

AbemaTVにおける推薦ですけれども、現時点で2種類の機能が提供されています。

1つ目が「関連するシリーズ」と呼ばれてるやつで、もう1つが「視聴履歴からのおすすめ」と呼ばれてるやつです。いずれも推薦されているコンテンツは、先ほどのAbemaビデオの番組になっています。

1つ目の「関連するシリーズ」ですが、これは番組のページとかに表示されているRecommendationになります。

なので問題設定としては、基本的に番組自体のIDでクエリされて、類似した番組を表示するものになっています。「基本的に」と言ったのは、詳細は後で話すんですが、こっちにもパーソナライズみたいな要素は入っている感じです。

もう1つが「視聴履歴からのおすすめ」でしたが、こっちはビデオのトップページに表示されているRecommendationです。

こっちは完全なパーソナライズで、ユーザのIDによってクエリされるタイプの問題設定になっています。こっちはいろいろ理由があって、一部のユーザのみ配信中というステータスです。

推薦システムの実装

では、システムの具体的な実装とかについてお話ししたいと思います。まず初めに、どういう「推薦システム」を作りたいかという部分なんですけど、当然、推薦結果の精度とか品質は重要なものだと思います。

ただ、一方で、「推薦システム」はオンラインで提供されているシステムなので、そのレイテンシーとかには強い制約があります。なので、オンラインでの処理はなるべくシンプルにしたくて、例えば複雑で大量の数値計算とかはなるべく避けたい、みたいなモチベーションがあります。

こういった要件に対応するための方針なんですけど、現時点では2段階の処理をするアプローチを実装しています。

1段階目の処理が非常に簡単な粗いアルゴリズムになってて、推薦の候補になる番組をすべての番組の中から何十件か程度まで絞ります。その後、精度の向上のためにもうちょい複雑なモデルを使って、その候補を並び替えて最終的なトップの数件の推薦結果を得る感じになっています。

またアレなんですが、こっちのリランキングが入ってるのは現時点では「関連するシリーズ」だけで、今ちょうどA/Bテストをしている真っ最中という状況です。

アルゴリズムの詳細

では次に、それぞれのアルゴリズムについて、もう少し細かく見ていきたいと思います。まず最初の、候補選択のステージの目的なんですが、先ほども言ったとおり、オンラインでのレイテンシーはすごい制限があるので、その短い時間の中で、すべての番組の中から高速に推薦の候補を生成する必要があります。

ただ一方で、とくに「視聴履歴からのおすすめ」の話なんですが、さすがに全ユーザに対して推薦の結果を事前に計算してデータストアに書くのは、あまり効率的ではないので避けたいです。あと、ユーザの視聴とかの行動に対する一定の更新性は保ちたいという目的があります。

ここでの目的の対応なんですが、今の実装だと、オフラインでの類似番組の事前計算の結果を、オンラインでユーザの直近の行動に合わせてマージして返却するかたちをとっています。

この実装についてもう少し見ていきます。類似番組の事前計算なんですが、まず初めに、クライアントからユーザの行動ログが、Patriotと呼ばれているラボのデータ解析のための基盤に送信されています。

ここはHadoopベースのシステムになっていて。ちょっと余談ですけども、ここに入れている情報は今回のような推薦だけではなくて、データの分析とかレポーティングでも使っている基盤システムになっています。

次にそのデータを使って、Patriot上でバッチジョブを実行して、類似番組の計算結果をデータストアに書き出します。

ここはSparkで実装していて、いわゆる次元削減系のアルゴリズムを使っています。なので、ユーザの行動ログからそれぞれ番組の低次元のベクトルの表現を得て、そいつをコサイン類似度でクエリする感じになっています。

「関連するシリーズ」の場合には、この結果がそのまま候補として利用されます。なので、こっちはこの段階では、まだパーソナライズはされてない感じになります。

「視聴履歴からのおすすめ」の場合には、もう少し事前に準備をします。先ほどPatriotに流していたユーザのログを、同時に「Zero」というラボの内製のストリーム処理の基盤にも転送します。

ここでユーザの例えば視聴ログとかを、ほぼリアルタイムでラボ側のデータストアに書き出しています。

あとはClientからRecommendationのリクエストが来たタイミングで、ユーザの直近の行動ログを何件か取ってきます。

最終的に、行動ログに含まれている番組に似た番組を最初のDBからまとめて取ってきて、あとはまとめて候補として利用する実装になっています。

精度を向上させるために候補をリランキングする

次に、2段階目のアルゴリズムについてお話しします。

ここでの目的なんですが、さっき取ってきた何十件かの候補の中から、よりよい数件のトップの推薦結果を作ることです。

ここでのアプローチなんですが、ここではユーザが推薦対象になっているそれぞれの番組を、ある一定のしきい値を超えて視聴することで予測するバイナリのクラシファイアを作ってやります。

その後、クラシファイアの予測確率をスコアとして、先ほどの候補を並び替えることをします。

なので、これは非常にシンプルなアプローチになっていて、リクエストしてきたときに、そのユーザが一番観そうな番組が良い推薦結果であろうという仮定のもと、出力するものになっています。

実装の全体像なんですが、さっきのRecommendation APIのバックエンドとして、ランキング用のコンポーネントを作っています。こっちのコンポーネントもWeb APIみたいなかたちで提供されてて、RecommendationのAPIがオンラインでさっきの推薦候補をこっちのAPIに投げてやって、スコアリングとかソートをする感じになっています。

このコンポーネントの実装をもう少し細かく見ていきたいと思います。まず最初に、2値分類のためのモデルの学習をしなくてはいけないです。

ここでのデータソースは、さっきと同じPatriot上にあるユーザの行動ログとか、番組のマスタみたいな情報を使っています。このモデルの学習自体は、オフラインのバッチみたいな感じで実行をしています。

その学習されたモデルは、オンラインのトラフィックを受け付けるために、モデルの配信サーバに転送されます。

あとは簡単で、RecommendationのAPIからランキング用のAPIにリクエストがくるので、そのユーザとか番組の情報のような、素性になるデータをバックエンドのデータストアから取ってきてやって、配信サーバの方にプレディクションのリクエストを投げる感じです。

最後に、予測スコア順に候補の並び替えをやって、その上位だけがClient側にはレスポンスとして返るかたちになっています。

今後の展望

既存のシステムの話はここまでで、次に今後の展望についてお話ししたいと思います。

今後の展望の1つとして、既存のシステムのブラッシュアップみたいな部分で、もっとよりよい候補の選択とか、リランキングのためのアルゴリズムに取り組みたいと考えています。

とくに候補選択のほうの話なんですが、今回お話ししたアルゴリズムはかなりヒューリスティックなものになっていたと思います。ここをもっとsupervisedな機械学習のモデルに置き換えることを考えたいと思っています。

なぜかと言うと、今のアルゴリズムってヒューリスティックなものなので、評価とかチューニングはほぼすべてがオンラインのA/Bテストに依存している状態になっています。

ただ、これは個人的な意見も含むんですが、A/Bテストの実施はかなりコストが高いとは思っていて、当然その判断にかかる期間もそうですし、場合によってはユーザに提供されている機能が若干デグレードしたりしているわけですよね。なので、パラメータのグリッドサーチをオンラインのテストでやるのは、さすがに避けたい感じです。

なので、モデルの良し悪しの最終的な判断は、当然オンラインのトラフィックに対するテストで行なうべきだと思うんですが、モデル自体のオフラインのメトリクスも、もうちょっと活用していけるといいんじゃないかと考えています。

あと、もう1つの展望があるんですが、現時点ではビデオの番組が推薦の対象になっていました。今回、それ以外のコンテンツの推薦も検討したいと考えています。

例えば、放送枠はAbemaTVにとって非常に重要なコンテンツだと思うんですが、こっちはビデオとは違って放送されている時間に制約があるので、問題設定としてはもう少し複雑になるんじゃないかと思います。

あとは、大きい目的として、ビデオのトップページとかに表示されているモジュールがいろいろあると思うんですけど、そこ自体のパーソナライズとか最適化みたいなことも検討したいと考えています。

まとめですが、今回はAbemaTVの「推薦システム」についてご紹介しました。

今のアプローチとしては、2段階の処理によるものを利用していました。1つ目が粗いアルゴリズムによる候補の選択で、もう1つが視聴の予測による候補のリランキングでした。

今後の課題としては、より精緻なモデリングだったりとか、ビデオ以外のコンテンツの推薦も検討したいと考えています。

発表は以上です。ご清聴ありがとうございました。

(会場拍手)

質問者:ありがとうございます。2段階に分けて粗くやったあとリランキングをやっていますけど、でも同じようなモジュールで同じようなデータからやってるので、一発でソートされた結果を返すわけにはいかなかったんですか?

福田:複雑なモデルと言っているほうで全番組をスコアリングするのは、ちょっと計算が重すぎる感じです。とくにその番組側の素性を使うと、全番組の素性をデータストアから取ってこなきゃいけないので、そこでちょっときついという感じです。

質問者:あくまでも、ユーザが観ている履歴の中の番組だけで計算する、それでリランキングをするのが、ちょっとだけ重たい処理になっている感じですか?

福田:そうです。

質問者:わかりました。ありがとうございます。