8,400万人の中の誰に広告を配信するか

加賀谷北斗氏(以下、加賀谷): LINE株式会社 開発4センター/B2B Platform開発室の加賀谷と申します。「LINE広告における8400万人を対象としたリーチ数の推定」というタイトルで発表していきたいと思います。

LINE広告とはその名の通り、LINEが提供するサービス上で広告を配信できる唯一のプラットフォームになります。みなさんの中にも、きっとLINEのアプリ内で広告を見たことがある方が多いんじゃないかなと思います。

LINEの国内MAUは、2020年6月時点で8,400万人以上と、非常に多くの方に使っていただいています。この8,400万人というたくさんのユーザーに広告を配信できるのが、我々LINE広告の一番の強みだと思います。

そんなLINE広告ですが、大きく3つの構成要素があります。広告配信面、クリエイティブ、広告配信機能。ざっくり言ってしまえば、この3つの区分はどこで・何を・誰に表示するかというのを表していますが、我々のチームが主に扱うのは3番目の広告配信機能「誰に広告を配信するか」の決定に関わる部分です。さらに今日お話しするのは、それらの機能のうち、LINEデモグラフィックデータ配信、オーディエンス配信に関わる部分の話になります。

推定属性を元にターゲティングする

一般的にWeb上の運用型広告というのは、費用を抑えて最大限に広告効果を得るために、できるだけ興味をもちそうなユーザーに広告を配信したいという大原則があるので、どんなユーザーに広告を配信するかが非常に重要になります。LINEではそのユーザーのターゲティングのために、こちらのようなオプションを提供しています。

例えばそのユーザーがどんなモバイルキャリアを利用しているか、どのくらいテレビを見るのか、どんなことに興味関心をもっているか、こういったデータですね。なお、これらのデータは基本的にはLINEでのユーザーの行動などを元に機械学習を利用して求められた推定属性になります。

属性の推定というのもエンジニア的にはとても興味深いトピックなんですが、今日はあまり時間がないので、別の機会に譲りたいと思います。

同じような目的で、デモグラフィックデータの他にユーザーのデータを元に広告配信ユーザーを絞ることもできます。例えば広告主が既にIDFA/AAIDといった広告識別子や電話番号、メールアドレスといった情報をもっている場合には、それを利用することもできます。

あとは、LINE広告で発行されたtagと呼ばれるJavaScriptスニペットがありますので、それを実際にWebサイトに張り付けてもらって、イベントが発火したユーザーを溜めておきまして、それをリターゲティングに利用するということもできます。それぞれのユーザーのグループのことを、内部的にはオーディエンスグループと呼ぶことがありますので、本発表でも便宜的にオーディエンスグループという用語を用いていきたいと思います。

ターゲティングオプションの具体例

それでは実際のターゲティングオプションの例を考えてみましょう。あなたは以下のようなユーザーに広告を配信したいとします。新宿駅を中心に半径5km以内に居住しているユーザー。あるいは通勤しているユーザーで、かつ結婚をしていて、40歳以上でAndroidを使っている。かつオーディエンスグループAあるいはBに所属していて、Cには所属していない。さらに金融あるいは健康および運動に興味はあるが、スポーツには興味がない。

非常に複雑な条件ですが、この例の設定のまま実際に登録が可能です。もう少ししっかりと見てみると、いろいろなターゲティングの条件があり、全体としてANDやOR、NOTといった論理演算が複数含まれていることがわかります。

ところで、こんなに複雑な条件を設定しても、実際に配信してみるまでは効果的な広告がわからないというのでは、効率的な広告配信は難しいですよね。ターゲティングは、狭すぎても広告がほとんど配信されませんし、あまりに広すぎても費用ばかりかかって効率の面で現実的ではありません。

広告主にとってはいかに効率的に広告を配信するかというところが非常に重要であるため、事前にどれだけのユーザーにリーチできるかを知ることができれば、適切な範囲のターゲティングを設定する助けになると言えます。

今回、解きたい問題のイメージを簡略化したのがこちらです。これは、よく見るベン図というものですね。この図でいうと、白の枠がLINEのユーザー全体を表す枠で、茶色の円と黄緑色の円の共通部分、かつピンクの円には含まれない、赤線を引いた部分ですね。これが我々のターゲティングオプションを満たすユーザーだとすると、そこに含まれるユーザーの総数を知りたいというのが、今回の問題になります。

さて、もう少し具体的に問題を見ていきましょう。ここでは、この問題のどんなところが難しさになるかを列挙しています。まず条件を満たすために、AND、OR、NOTなどの集合演算をサポートする必要があります。また、ネストした集合演算も、当然可能である必要があります。

サイズの部分でもそんなにシンプルではなくて、まず先ほどお伝えした通り、オプションの数というのが多くて、そのオプションを使うためのデータ生成元のインプットソースも、複数存在します。あと何度も言っているように、ユーザーの数も非常に膨大です。

さらに我々でいう条件、ターゲティングオプションにあたる集合に含まれるユーザーは日々アップデートされるということも、問題の難易度を高めています。それぞれについて、後ほどのスライドで詳しく見ていきます。

リーチできるユーザーの数を推定できる

改めて作りたいシステムを定義すると、このようなかたちになります。「こんなユーザーに配信したい」というターゲティング設定を入力として、リーチできるユーザーの数を推定できる、そんなシステムです。出力が、リーチできるユーザー数の推定になるということですね。そして推定結果に基づいて、広告主はターゲティングの設定を再調整できます。

ここからは具体的にシステムの実装について見ていきたいと思います。いきなりトップダウン式にはなりますが、こちらがシステム全体のアーキテクチャを簡略化して図示したものです。いくつかの部分に分けて紹介していきます。

まず、もっとも重要なメインストレージには、検索エンジンとしても有名なElasticsearchを利用しています。先ほどのスライドをもう一度出しますが、ここからお話しする内容は、このSet operation、集合演算の部分に関連するトピックになります。

さて先ほど述べた問題をもう一度考えてみましょう。私たちのしたいことは、別の言葉で言い換えれば、特定の複数の条件を満たすユーザーを検索する、あるいはカウントすることです。よってデータ量の問題を考えなければ、任意の検索エンジンで要件を満たすことができます。

そのため、社内でも利用例が多く、私個人としても使用した経験が幾分多かったElasticsearchを採用することにしました。簡単に言えば、Elasticsearchの1ドキュメント1レコードを1ユーザーと見立てて、いろいろなユーザー情報を入れておき、単純にほしい条件をクエリするという方法です。

こちらは実際のデータを一部改変したものですが、イメージとしてはこのようなデータがElasticsearchに入っています。いろいろデータがありますが、例えば下のほうのオーディエンスグループを見てみると、このユーザーが属するオーディエンスグループのIDが列挙されているのがわかるかと思います。

推定に必要なデータを準備する

続いては、推定に必要なデータを実際に準備する部分です。Elasticsearchにデータをインサートする部分、と言い換えることもできるかなと思います。この部分でも、いくつかの工夫があります。ここからの内容は先ほどの難しいポイントのうち、サイズとUpdatability、更新性に関わる部分です。

まず我々の既存のシステムの制約上、各種ターゲティングオプションのデータに対して複数の生成元データソースというのがあります。実際にはもうちょっと複雑なんですが、ざっくり書くとこんな感じになります。オーディエンスグループは、実際の広告配信に使っているRedisをバッチサーバが定期的にスキャンして、Elasticsearchに保存しています。

推定属性と位置情報については、Hadoopクラスタに別途情報が保持されているために、これもバッチサーバが定期的にスキャンして、Elasticsearchに保存しています。

一番下のNRTデータというのが少しわかりにくいですが、ユーザーがリストでIDFA/AAIDといった広告識別子のリスト、これを手動でアップロードするようなオーディエンスグループの場合、すぐに反映させたほうがUX的によいため、ユーザーのアクションをトリガーにそのままデータをElasticsearchに保存しています。

問題点の1つ、とても大量のユーザーを上手く扱うためにというところは、本当にシンプルにサンプリングを導入しています。これはサンプリング後のデータで、基本的にあくまで推定なので、ユーザーがある程度一様に分布するサンプリングを行えば、ある程度の精度を保ったまま速度面やインフラコスト面でのパフォーマンスの改善が期待できるので、サンプリングを導入しています。

現在日本以外のユーザーも含めて2,900万人ほどのデータをもっています。

推定データの更新性の問題

最後に残った問題がUpdatability、更新性のところですね。頻繁に中身が変わるデータとして、オーディエンスグループを取り上げたいと思います。オーディエンスグループは、日々刻刻とアップデートされます。例えばtagのイベントをベースにしたグループでは、新しいユーザーがtagを踏む度に人数が増えますし、LINE公式アカウントの友だちを元にしたグループでは、当然日々の友だちの増減に応じて、カウントが変化していきます。

最初我々は、これらのオーディエンスが増加・減少する事象を1件のイベントとして捉え、ストリーム処理でこれをElasticsearchに入れることを検討しました。ですが、このイベントは1日のうちピークの時間帯では20万QPS程度あり、ユーザーをサンプリングしたとはいえ、この方法ではElasticsearchがどうにも耐え切れませんでした。

そもそもElasticsearchにおいては、アップデートはデリートしてインサートする処理とだいたい等しく、本質的に得意な処理とは言えません。またオーディエンスグループは、先ほど例に示したように、arrayのかたちでもたせているので、普通のフィールドに比べてちょっと更新の負荷が高くなってしまいます。

そのため、我々はこの部分についてクラシカルなバッチ処理で書き換えることにしました。2時間に1回あるユーザーが所属するオーディエンスグループをすべてスキャンして、それを丸ごとElasticsearchに保存します。これによって、ユーザーの数とオーディエンスグループの数の掛け合わせで考える必要があったアップデートを、ユーザー分で発行できるようになったので、だいぶ数が削減されました。

もちろんElasticsearchのクラスタを無尽蔵にスケールさせていけば、リアルタイムにアップデートすることも可能だとは思います。しかし目的はあくまで推定ですので、リアルタイムに元データを更新しようとすることは、時間的にもインフラコスト的にもちょっと割に合わないかなと判断しました。

最後に実際に推定を行うところの実装ですが、API Serverは今のところ管理画面からリクエストを受けて、それをElasticsearchのクエリに変換して投げているだけで非常にシンプルな作りになっています。Elasticsearchを利用して苦労しながらデータを溜められたというのもあって、参照側については非常にシンプルなインターフェースを提供できているかなと思います。

広告の管理画面のデモ

最後に、簡単にデモをご覧いただきたいと思います。こちらは、実際の広告の管理画面の映像です。今の初期設定としては、日本のユーザーというところまではわかるかと思います。右側が推定された結果を表すゲージと、推定の実際の数字になりますね。この中で、男性かつ40代以上のユーザーで、iOSを使っているユーザー。かつゲームに興味があって、あるいはスポーツに興味があって、もしくはテレビと映画に興味がある。

でもあまりテレビを見ないユーザーは除外したいと。そういうときに、こういう設定をします。設定をすると右側の数字ゲージが、さくさくと変わっていったのがわかったかなと思います。こんな感じでデモになります。

最後にまとめです。私たちはLINE広告のためにオーディエンスサイズを推定するシステムを構築しました。そのメインストレージとしてElasticsearchを採用しました。巨大かつ頻繁に更新されるデータへの対策として、非常にシンプルではありますが、サンプリングと伝統的なバッチ処理を用いて実装を行いました。

以上で発表は終わりになります。本発表は、2016年にLINEに新卒入社した後、2019年からこの部署で働いています加賀谷がお送りしました。

ご清聴ありがとうございました。

質疑応答

司会者:どうもありがとうございました。ここからは質疑応答のセッションに移ります。一つ目の質問は、「LINE広告のシステムはどのような言語、フレームワークを使って構築していますか?」ということですね。「Java/Springの組み合わせが多いようですが、同様でしょうか?」ということですが、いかがですか?

加賀谷:はい。今日説明したシステムに出てくるコンポーネントは、基本的にはJava/Springの組み合わせですが、LINE広告全体で言うと、とくに速度を厳格に要求されるようなコンポーネントだとGo言語を使っているケースがあります。とくにDSPと言われている広告配信サーバは、Goを使って実装されているはずです。

司会者:なるほど。ありがとうございます。もう1つの質問が「サンプリングでも問題ないかと思いますが、実際の広告配信のためには、条件に合致するユーザーを抽出する必要があると思います。それはこのシステムとは別でやっているのでしょうか?」ということですが。

加賀谷:はい。ちょっと画面をいいでしょうか? 今の質問の内容は、このElasticsearchに入れるときにサンプリングをしているようだけど、実際の広告配信は当然サンプリングされていなくなったユーザーのデータは消えちゃうのでどうするんだ、という話だと思うのですが、この図で言うところの右側の雲のところが、雑に隠しているんですけど、実際には実はこのRedisのところが……。

Redisのところが広告配信で使っているDBで、基本的にはスピード重視で、いろいろなデータがRedisに格納されていると思ってもらえればいいのかなと思います。

むしろ、Elasticsearchには広告配信で使っているDBから定期的にもってきたり、バッチでもってきたりして、スナップショットを撮っているイメージですね。なので、実際の広告配信で用いるDBではサンプリングしているということはないですね。

司会者:ありがとうございます。