Graph Convolutional Networkを使った推薦システム

西場正浩氏(以下、西場):「Graph Convolutional Networkを使ったニュース等の推薦システム」という話をします。

エムスリーというところで働いていて、AI・機械学習チームのチームリーダーをやっています。そこでは自然言語処理とか推薦システムまわりをやっています。あとは採用マーケティングもやっています。

エムスリーを聞いたことある人!

(会場挙手)

すごーい! ですが、これ、1年前は本当に誰もいなくて、1年間めっちゃマーケティングをやった成果ですね。

最近はプロダクトやプロジェクトマネジメントをやっていて、今後はすごく大きなプロジェクトのプロダクトマネージャーとしてやっていくことになるので、本当にMLは関係ない世界になっています。

「We are hiring!!」なので、うちは楽しいから来てください! 欠点は「ポストイットの会社でしょ?」と言われることですね。

今日はレコメンデーションの話をします。

どんな問題かと言うと、100ドキュメントの中からユーザごとに10個選ぶ、みたいな状況です。対象のテキストへのアクセス数が少ない、ニュースとかを想像してもらえればいいと思います。

出す前にあまりアクセスがありません。僕らはYahooみたいなポータルページを持っていて、そこに来て何人かは見ているんだけど、めちゃくちゃ多いわけではないという状況です。それなので、メールマガジンを配信しています。

課題とその背景

モチベーションとしては、属性データとかをもっと使いたいとか、ファットテールな感じにしたい。インアクティブなユーザにも良い感じに出し分けをしたいのと、100個の中からいい感じに満遍なく出したいという要望があります。ランキングモデルみたいなものが強くなってしまうとツライのでやっています。

なぜインアクティブなユーザにも良い感じに出したいかと言うと、日本のお医者さんの数は33万人しかいないからです。僕たちはお医者さん向けのサービスをやっているのでターゲットが33万人しかいなくて、そのうちの28万人以上がユーザなんです。だからアクティブユーザを増やそうを思ったら、新規ユーザ開拓じゃなくて、インアクティブなユーザを取りに行かなければ行けないので、「インアクティブな人をいかに掘り起こすかがビジネスにとって非常に大事です。

久しぶりにサイトを見たときに「なんか俺の好きなものばかり並んでるめっちゃいいメディアじゃん」みたいな状況を目指しています。

アプローチとしては、「Graph Convolutional Network」と「Latent Cross」を使っています。このベースはGCMCと呼ばれるもので、属性データを入れるときにGoogleが1年半前ぐらいに書いたやつを取り入れています。僕がだいぶ前に作った既存モデルはGoogle Newsの論文がベースになっていて、それとは違うものを使っている感じです。

ニュースの記事のレコメンドのようなものなんですが、弊社のメルマガでのクリック率がすごいんです。「それをさらに上げてくれ」みたいな問題なので、けっこう大変です。

ユーザによって興味がけっこう変わります。若手の人はキャリアとか、人によっては資産運用に興味があったりとか、「オンコロジー」という癌の領域に興味があったりとか。

お医者さんにはそれぞれ専門領域があります。みなさんもそうだと思いますが、MLといってもいろいろな分野がありますよね。自然言語系なのかレコメンド系なのかいろいろあって、興味が偏るんです。

どう考えても外科の人が耳鼻科の記事は見ないと思います。そういうわけで、興味に応じて出し分けが必要です。

では、なぜうちの医療ニュースが大事かと言うと、実はお医者さん向けのニュースサイトはほとんどないからです。例えばお医者さんが不祥事を起こすと世間が盛り上がるというか、最初はすごく注目されるじゃないですか。でも、裁判が始まってからは徐々に世間は興味を持たなくなっていきます。

でも、お医者さんは気になるわけです。どんな内容で訴えられてその後どうだったのか。そういった情報は普通のメディアにはあまり出ないので、そういった情報を追いかけていくことで、お医者さんが喜んでいるという感じです。なので、いい感じに出し分けられると、ユーザにとって価値があります。

GCNモデルを解説

GCNモデルを簡単に紹介します。

この数式はなにをやっているかと言うと、お医者さんとアイテムの2部グラフを使ってやっています。どういうことかというと、ここに書いてある通りです。

お医者さんがいて、コンテンツがあって、クリックしていたら線が入ります。リンクが貼られるというような状態のグラフを考えます。グラフのConvolutionの方法はいろいろありますが、message passingを使っています。属性データは、Latent cross的なアイディアで統合しています。

どうやっているかと言うと、オートエンコーダーみたいなものを作るんですが、まずは、学習できる変数として、ユーザとアイテムの両方にembeddingをします。次元を数百使ってembeddingをします。何がmessage passingかと言うと、このembeddingではありません。最終的なユーザの特徴をどうやって作るかというと、このユーザがクリックしているアイテムのembeddingを使って、最終的にはユーザの特徴量というのを作ります。

アイテムはアイテムで、自分がアイテムをクリックしたユーザの学習したembeddingを使って、最終的な特徴を作ります。つまり、ユーザ1がアイテム1をクリックする確率は、こういうaverageなど何かしらのかたちで集計した、自分がクリックしたアイテムのembeddingでユーザの特徴を表しています。アイテムは、それをクリックしているユーザのembeddingで表すということをやっています。

なぜこの方法を採用したかと言うと、新しいアイテムを推薦しなければいけないという、けっこうなつらみがあったからです。ニュースなので毎日新しいものが控えていて、しかもクリックの情報は徐々に変わっていきます。なので、しょっちゅう予測を作り直していると、すごく速く計算できなければいけなくなります。

毎回グラフを叩き込むということはできないので、新しいアイテムが出てきたらどうなるかというと、例えば真ん中にあるアイテム2が新しいアイテムだとしたら、この特徴のembedding自体を学習せずにこの特徴を作ろうと思うと、ユーザの2人から作れます。

作れると、評価が最新のものが取りやすくなります。アイテムのembeddingが無かったら、ある程度評価されていたらユーザのところだけで作れます。逆に、本当だったらここがないと「あれ? この人のやつ評価できないじゃん」となるんですが、この人は本当はいろんなものをいっぱい評価しているはずです。そこからこのユーザの特徴量が作れるので、本来であれば1個無くても新しいのが入れば、別にこれを無視して0だと思って考えても問題ありません。

なので、これも比較的新しいアイテムにも使えます。これは、めっちゃ簡単に書いているだけで、論文ではもう少し丁寧な説明になっています。

数字で見る実験結果

レコメンデーションにおいてテストをどうやってやっているかと言うと、もちろん全体から満遍なくテストデータを取ることはやっていません。

なぜかというと比較的新しいアイテムをちゃんとレコメンドできるよね、ということをするために、2018年1月1日から2018年12月31日までのデータを全部使って、1月のデータは一部のユーザのときだけ使います。なので一部は評価されていると。これをテストデータとして訓練させて様子を見ます。テストユーザは50パーセントから90パーセントという感じで、どれぐらい少なくても評価できるかを見ています。

ここが1番すごいところで、バックテストに使ったユーザ数は4万人、記事数が1,000個です。これは本当に実データで使ったやつです(笑)。

ランキングモデルというのはただ単に順位で予測する。これはGCMCでいろんなかたちでやったものなのですが、だいたい全体的にランキングモデルに負けています。それはそうで、バックテストでオフライン評価なので、このログ自体にすごくバイアスが掛かっているんですね。

今はランキングに近いかたちでメルマガを送ったりしているので、基本的にランキングモデルが勝つ。それはいっぱい出ているからですね。

あとはこの「p@2」とは何かというと、2件出してそのうちクリックされたかどうか、というものです。このp@2がすごい重要で、メルマガなどを想定するとメールの件名には2つぐらいしかタイトルが入らないんですよ。そこで開封するかしないかが選ばれるので、ここがすごく良くなければいけません。

これはちょっとまずいので、直します。

すると、だいたい赤いところが学習しているので勝ちます。何をやったかというとランキングモデルのアンサンブルっぽいことをやりました。なんで良くなるかというとけっこう明確な理由があって、そもそも100記事なんだけど、100個全部読む記事に値する記事かというとそうでもないんですね。

あまり人気ではない記事も100個の中に入ってくるので、それをテキスト的に見て「ユーザが興味ありそうだよね」って出しても中身が空っぽだったら、やっぱりあまりうれしくないですよね。そういったものは全部弾くようにしたので、ランキングモデルと比べるとすごい良くなりました。

実際にモデルの挙動で、ファットテールにやりたいというのは最初に書いた通りです。

今のGoogle Newsのランキングモデルに長期モデルと短期モデルを組み合わせたものをやっているところが青ですけど、新しい赤いほうでは満遍なく推薦できています。これ編集部に見せると結構いい感じだと言ってくれます。

属性データを入れているので、インアクティブな人にも良い感じに出るようになりました。全部「(編集部調べ)」と書いてありますが、うちは編集部を持っていて記事を書ける人がいるので、彼らに見せることで適切なレコメンデーションかどうかがわかります。なので、モデルを作ったあとに編集部が全部チェックして「良さそう!」みたいなことをやっています。

改善したいこと

これはA/Bテスト中なんですが、実際に出してみたらけっこう良い感じで勝っています。ただ、改善の余地があるところも何個か見えてくるので、それについてもお話ししたいと思います。

何が起きたかと言うと、ユーザの埋め込みみたいな分布を作っているのですが、あれはだいたいユーザのクラスタみたいになるんですね。それで「そことそこにクラスタがあるね」みたいな感じになるんですが、他のクラスタがよくクリックしている記事というのはだいたいそこの平均を取るので、ここのクラスタの赤いところみたいになるんですよ。それで右下がこうなります。

これはこれでいいんですが、例えばこっちの記事は2人がクリックしただけです。こっちの記事はもうちょっと外側の人も含めていっぱいの人がクリックしている。「じゃあこっちのほうが人気だよね」と、したいんですけど、それは関係なく、自分との距離になってしまいます。

次の問題が、こっちとこっちの両方から人気、みたいになると真ん中になってしまいます。それは真ん中にいるんだけど、真ん中になってほしいわけではない、みたいな。このクラスタとこのクラスタからの両方から人気というのは、この間にあると困るので、その辺をどうやって解こうかと考えています。

最後に「WE ARE HIRING!!」で、いろいろやっています。では、これで終わりたいと思います。

ノイジーな挙動をどうするか

司会者:じゃあ、質問に行きましょうか。

西場:はい。

司会者:「検索の文脈などでは、ユーザのクリックのシグナルをそのまま知ろうとして用いると、とてもノイジーなことが多いと言われますが、記事のレコメンドでもそういった事象は見受けられるのでしょうか?」

西場:そうですね。一応明確なのは、なるべくクリックする人は何もあてにならないので入れていません。クリック率が異常で「毎日クリックしています」みたいな人にレコメンドをしても意味がないので、そういったことは除いてたり、あとはものによりますが、1回レコメンドモデルを作って、異常値ぽいものは軽く目で確認しながら全部消して、ある程度何個かランダムサンプリングして、目で「消してもいいよね」という閾値を設けて消したりしています。

ただ、ユーザ数がめちゃくちゃ多いわけではないので、めちゃくちゃ消すと本当につらいことになるので、バランスかなぁと思います。今これをやっているのは一部のモデルなんですけど、他のところではまだそこまでの精度を出せていないので、ノイズがあるせいで精度が悪い状況にはまだなっていないので、今後の課題かなぁと思います。

司会者:これは答えやすそう。「エムスリーさんは、会社での取り組みを論文化していますか? またはする予定はありますか?」。

西場:うちは、今ばんくしさんが書こうとしています。ちなみにGCMCのレコメンドモデルをGitHubに公開しています。アルゴリズムを公開していい会社なので、論文を書こうとしています。

司会者:「比較的よく読まれる記事とそうでない記事の差が、かなり顕著な場合の調整はどうしていますか?」

西場:どうしたらいいか教えていただけると、この問題が解決しそうです。一番大きいのが、クリック率を予測するみたいなモデルをかましています。単純なランキングではなくて、公開日とかカテゴリとか、タイトルに書いてある単語とかで、ある程度予測できるはずだと思ってそういうモデルを組み込んでいますね。

昔作ったGoogle Newsのほうは、そういうことはうまくできていますね。補正はいろいろ掛けてはいるんですけど、こっちをベースにやっているだけでこれの内容はそのまま書いていないんですけど。取れている感じかなと思います。

司会者:最後の質問にしようと思います。「ランキングモデルとグラフベースのレコメンドのアンサンブルのことってどういう比率でやっているのでしょうか? ユーザによって比率を変えたりしているのでしょうか?」。

西場:今は変えていないです。A/Bテストのやつは変えていないです。だけど、これから変えようかなと思っています。変え方はけっこう単純にできるかなぁと思っていて、少なくともただの統計量から、この人はランキングによるとどちらの好みが強いのかはわかると思うので、それで出そうかなとは思っています。

終わりかな? ありがとうございました。また懇親会で聞いてください。

(会場拍手)