FANCOMI Ad-Tech Blog

株式会社ファンコミュニケーションズ nend・新規事業のエンジニア・技術ブログ

FANCOMIでのCTR予測インターン

データ分析コースのインターンシップに参加させていただいた NAIST の福田です。
普段は、機械学習を使って、アンケートにより得られる労働者の心身状態(ワークエンゲージメント、うつ度合いなど)を当てる研究をしています。

元々、広告業界に興味があり、なかでも機械学習を使ったものがあると聞き、FANCOMIの広告枠のCTR予測について、5 日間取り組みました。

最近は、コロナウイルス(COVID-19)が流行っていますが、体調に気をつけて頑張っていきたいと思います。
※ 福田さんがインターン参加の時期(2020年2月頃は)は、コロナの影響でファンコミュニケーションズでは、出勤・退勤時間をずらす対応やテレワーク業務を実施していました。(ファンコミュニケーションズ追記)

1day : 広告配信の仕組みの勉強&CTR予測のための事前知識の勉強

私が取り組んだテーマである 広告枠のCTR 予測は、広告を表示したい広告主がよりうまく宣伝できるように、RTB で広告枠の取引する際に用いる指標となるものです。
 
具体的には、Webページを開いたときに、訪問者の画面に表示する広告枠がリクエストされ、どの広告主がその権利を得るかのRTB取引市場に流れた時に、広告主は、クリック率などの指標を基に、入札処理を行い、勝ち取った場合に、その広告主の広告が表示されます。

機械学習での CTR 確率予測

CTR(Click Through Rate)は、広告枠に表示された広告をクリックするかしないかの確率であり、機械学習で予測する場合、クリックするか / しないか の分類ではなく、何%でクリックするかの確率値を予測することになります。

実際の例で言うと、広告素材やサイトのジャンル、サイトの訪問者の属性によって異なりますが、おおよそ 2 % 程度らしいです。学習データとなる広告リクエストのトラフィックデータもそのような割合になっており、クリックされた時の広告リクエストの割合は全体の1-3 % 程度です。
つまり、極端な不均衡データとなっています。

また、別の問題として、予測は確率値で行いますが、その評価に用いるデータは、クリックしたか / していないかの 2 値であるため、どのような評価指標で、予測した確率値とクリックの有無の2 値を紐付けて評価するかが課題になります。
この辺りの議論は、ここに詳しく書いていますので、参考にしてください
www.jstage.jst.go.jp
CiNii 論文 -  CTR 予測モデルの評価に AUC や log-loss は適切か?

2day : nend サービスのトラフィックデータのクリーニングとCTR 予測を行う機械学習モデルの構築

5 日間のインターンシップで、自分が行うCTR予測の目標設定をしました。
NN系のモデルやKaggleなんかではFactorization Machines (FM)による方法が精度が良さそうということがわかっていましたが、5日間しかないため、そこは目指さず、特徴量の改良にフォーカスしてみました。

カテゴリー変数となる広告ID などが特徴量に入っており、OneHotエンコーディングでスパースになっているため、次元の呪いなどもあるんじゃないかと思い、色々試してみることにしました。
具体的には、スパースになりにくい特徴量で、モデルを組むとどうなるのかを試すことにしました。

流れとしては、nend のリクエストなどが格納された DB から、Treasure Data経由のSQLによりトラフィックデータを取得し、欠損値補完などを行い、ロジスティック回帰などのモデルに学習させました。

f:id:fan_s_fukuda:20200221163915p:plain
CTR予測のながれ

まずはじめに、広告宣材ID, サイトID, キャンペーンID などをOneHotエンコーディングし、特徴量とした場合の結果です。

機械学習のモデル構築・評価に使用したデータは、昨年度の nend のトラフィックデータのうちの、学習データ:10日間、評価データ:7日間です。モデルには、パラメータ調整を行なっていないロジスティック回帰モデルを使用しています。

広告宣材ID, サイトID, キャンペーンID などを特徴量とした場合の結果

model N  pos. rate  Expecred click  AUC  log loss  mean entropy  NE  ECE
train 3,279,148  0.113428  0.113113  0.703659  0.322233  0.353622  0.911236  0.003114
test 4,042,439 0.002305  0.002571  0.698176  0.015577  0.016297  0.955832  0.000282

上の表の NE が、正規化エントロピー (NE) であり、今回着目した指標となります。
これは、CTR 予測などの不均衡データに対して対応されている指標であり、対数損失(Logloss)に対してデータの不均衡性に対応する形で正規化されたものです。
おおよそ 1 を超えると、平均確率で予測するよりも悪い精度ということになります。

今回は、上記の結果を基準に特徴量を増やした場合などの比較をしていきたいと思います。
明日以降に特徴量を増やした場合との比較を行なっていきます。

余談ですが、CTR 予測を行う機械学習のモデル運用では、オンライン学習や強化学習により、どんどんモデルを更新していく手法が取られており、これは、サイト ID や広告 ID なんかを入れて対応させていることも起因しているかなと思いました。

個人的な感想としては、Pythonの実行環境構築に苦戦しました。使っているライブラリのバージョンなどがかなり違っていたり、後々分かったのですが、Python3.6 系統でしか動かないものもあったのでこの辺りが大変でした。

3day : 時間帯、Wifi有無、表示端末の機種モデルなどの特徴量の追加による検証

Pythonの機械学習ライブラリのバージョンに苦戦しました。Jupyter Notebookのサーバを用意して頂いたので、そこに開発環境を移していると、自作ライブラリのインストールやバージョンの設定などで時間がかかってしまいました。

昨日行ったベース値に対して、特徴量を増やした場合にどの程度精度が向上するのかを試してみました。

特徴量を増やした結果(WIfi、時間帯、機種モデル)

 model   N  pos. rate  Expecred click  AUC log loss mean entropy NE ECE
 train 3,279,148  0.113428  0.113321  0.706092  0.321479  0.353622  0.909102  0.002886
test  4,042,439 0.002305  0.002538  0.701241   0.015553 0.016297 0.954351 0.000234

特徴量追加前 Test データの NE: 0.956, 特徴量追加後のTest データの NE: 0.954, 精度向上:0.002 程度でした。
モデルのせいもありますが、あまり精度が上がらなかったのが少しショックでした。
OneHotエンコーディングをした大量のカラムもある中で、それらと一緒に学習させた影響もあるのかも知れないです。大量の特徴量の項目に埋もれてしまって、学習がうまくいっていない可能性もあります。

気を取り直して、どんどん試していきたいと思います!

次に、あまり広告業界のことは知らなかったので、こんなことを試してみました。

Count エンコーディングによる特徴量の変換

仮説:よく表示されているほど、いいサイト(キャンペーン)なのでは?

この仮説に基づき、OneHot エンコーディングではなく、Count エンコーディングを行い、モデルを作成していきました。

Count encoding の結果(広告のID etc. + WIfi、時間帯 etc.)

model N pos. rate Expecred click AUC log loss mean entropy NE ECE
train 3,279,148 0.113428 0.116982 0.570453 0.352621 0.353622 0.997168 0.020263
test 4,042439 0.002305 0.001706 0.589540 0.016390 0.016297 1.005701 0.000866

結果としては、NEが悪くなってしまいました。
この時の結果を見て、少し気付いたのですが、
現在のモデルはサイトID なども入れており、クリックされやすいサイトを判断する特徴もとらえたモデルになっている可能性もあるんだなと感じました。

4day:Optuna でのパラメータ調整のプログラムの実装

特徴量抽出に関してはこれ以上深くせず、機械学習モデルのハイパーパラメータの方に力を入れていきました。
ライブラリとしては、Optunaと呼ばれるベイズ系の最適化を行ってくれる物を使用してパラメータの探索を行っていきました。

実装自体の際、Trial ごとのトレーニングデータに対するNEなどを Optuna の user_attrs を使って、保存できるとメンターの方に教えてもらい、それを元に、過学習しているのかなどを見ていきました。

f:id:fan_s_fukuda:20200221164001p:plain
探索

上の図がパラメータの最適化を行っていった時の誤差(NE)の推移です。
作業に時間がかかってしまい、 あまり試行回数を増やすことができませんでした。

大量のトラフィックデータの解析をするのは、今回のインターンが初めてなのですが、
Random Forest のパラメータ調整では、時間がかかりすぎたため、ロジスティック回帰の精度を上回るパラメータを見つけることができず、データ量が多いと、このような影響が出てくるんだなと思いました。

Random Forest のアルゴリズムでは、決定木を大量に作っていきますが、一本の木の一つの分岐を作る際、情報利得や不純度の計算に全てのトラフィックデータにアクセスするため、時間がかかるんだと思いました。
この辺りは、データ量がそこまで多くないと気になりませんが、今回のケースのように数百万件のデータを学習させる場合は、時間がかかると知りました。

夕方からは、パラメータの探索をさせてる間に、明日の発表資料づくりを頑張ってました。

5day:インターンの内容の発表会

お昼の時間帯に、他部署の社員さんも交えて、インターン内容の発表会をしました!

ファンコミュニケーションでは、幅広い年齢層の方がワイワイ話している感じでした。
機械学習というなかなか尖った分野の発表ですが、エンジニアの方以外も温かい眼差しで発表を熱心に聞いてくださいました。

感想:色々経験できて良かったです!

5日間という短い期間でしたが、実際の業務で機械学習を使用する現場に混ざることができてとても良かったと思っています。

実際のデータを分析して、特に勉強になった点としては、

  • NN系のモデルを試すも、学習時間がかかり断念。(実際の用途ではRTBでは速度が大切と教えてもらった)
  • OneHot エンコーディングするとスパースデータにしないとメモリが足りない
  • IPアドレスから住所に変換するAPIを試そうとしたけど...
  • ハイパーパラメータのチューニングに時間がかかった

が経験できて、よかったです!