FANCOMI Ad-Tech Blog

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

共変量シフトへ対応したCTR予測

 インターンに参加させて頂いた濱武です.「データ分析」コースに5日間参加し,「共変量シフトへ対応したCTR予測モデルの評価」を課題として取り組みました.

共変量シフトとは

 機械学習は訓練データ,テストデータが等しい確率分布にしたがっていることを前提としています.しかしながら,実際に等しい確率分布に従っていることはほとんどありません.このように訓練データとテストデータの確率分布が異なる状況で,入出力関数は等しいという状態を「共変量シフト」と呼びます.

対策案

 共変量シフトへの対策案の1つとして,訓練データとテストデータそれぞれの確率分布の比によって定義される「重要度」という指標を利用し損失関数を重み付けする手法*1があります.簡単な直線モデルを最小二乗法によって適合させる場合は以下の数式のようになります.

{ f(x) = \theta_1 + \theta_2x}

{ \min \sum_{i=1}^{n} (f(x_i) - y_i)^{2} }

そこで,二乗誤差に対して重要度 { w(x)} を利用して重み付けした重要度重み付き最小二乗法で適合することで,テストデータに対する予測精度が向上します(より詳しい内容は脚注の論文に書かれてあります).

{ \min  \sum_{i=1}^{n} w(x_i)(f(x_i) - y_i)^{2} }

しかし,データの確率密度を求めることは困難であり,重要度をデータから推定する必要があります.この手法も様々あるのですが,今回はこちらのパッケージを利用しました.

分析の流れ

 モデルとしてロジスティック回帰を使用し,重要度を利用していないモデルと比較することで,重要度適応モデルの評価を行うという方針で進めました.分析の流れは以下のような感じです.

  1. データ取得
  2. 重要度推定
  3. One-Hotベクトル化
  4. 学習
  5. 評価

なお,重みの適応は,ロジスティック回帰のsample_weightに推定した重要度を利用しました.

結果

 インターン最終日,上述したパッケージは大規模データでの利用を想定しておらず,大量のデータを食わせるとMemoryErrorが発生することが分かりました.そのため大幅に削減したデータでの学習を余儀なくされてしまい,また,本筋とは離れた細かいトラブルへの対処に時間をかけてしまったせいで,評価をする前にタイムアップを迎えてしまう,というとても不甲斐ない結果となってしまいました.提案手法結果のカリブレーションカーブ*2(簡単な説明は他のインターンの方が書かれています)は以下のようになりましたが,散々な結果であり,テータ削減の影響や重要度の平滑度合いを調整するべきだったとか,様々に原因が考えられます.

f:id:k_hamatake:20190823182023p:plain
カリブレーションカーブ

学べたこと・反省点

 私は独学でプログラミングや機械学習,データ分析を学んでいますが,やはり実データを利用できる機会はほとんどありません.今回インターンに参加し,データベースの扱いや大規模実データのハンドリングを学ぶことができ,5日間とても貴重な経験を積まさせていただきました.

 だた反省点として,メイン手法とは別に代替妥協案みたいなものを用意して,インターン期間にきちんと課題を終了できるようなプランニングをするべきだったと感じています.重要度推定にこだわり過ぎず,例えば日付が新しいほど重みが増加するような関数を使用する方針にある段階で切り替えておけばもっと良い結果になったかなあ,と思っています.インターンで得られた知見や反省点を活かして精進していきたいです.

 

*1:杉山将 他. (2014). 非定常環境での学習:共変量シフト適応,クラスバランス変化適応,変化検知. 日本統計学会誌 第44巻 第1号 pp.113~136.

*2:https://scikit-learn.org/stable/auto_examples/calibration/plot_calibration_curve.html#sphx-glr-auto-examples-calibration-plot-calibration-curve-py

文系大学生、初めてのエンジニアインターン

初めまして、牛嶋(うしじま)と言います。この度8月19日~23日までの1週間、ファンコミュニケーションズでインターンに参加してきました。このブログでは1週間何をしたのか、インターンの感想などを書いています。

まず私の簡単な自己紹介をします。

  • 熊本の文系大学に通っています
  • プログラミングは1年弱やってきました
  • プログラミングの勉強は独学です

こんな感じです。
インターンはITどころか、他の職種でもやったことがなかったので、初日は緊張しておりました。

インターンの内容

今回、私は「業務体験インターン」に参加しました。参加できる期間は1週間と短期だったので、自身の技術力をあげるよりも実際の業務を体験したいと思ったからです。
私に与えられた業務はnendというスマホ広告サービスのissue潰しでした。使用されている言語はPHP、フレームワークはCakePHPで、今回のインターンまでに触ったことがなく頑張って勉強してきました。

1週間でやったこと

nendにおける広告がクリックされてからの流れの理解

「業務体験インターン」という内容だったため、まずは運営しているnendというサービスを理解する必要がありました。これはnendに関わる新入社員さんが体験することでもあり、サービスの中身を知るよい機会でした。コンバージョンといったアドテクならではの専門用語が多く、内容の理解には手こずりました。

issueについて

あまり具体的に書くと怒られそうなので、簡単にやってきた内容を説明します。

不必要となったダウンロードリンクの削除

最初に対応したissueです。使わなくなったダウンロードリンクを削除するという内容でした。削除なので、取り組む内容は難しくなかったのですが、実際に稼働しているサービスのコード、ファイル量が多く該当する箇所を見つけることに苦労しました。nendでのコードの全体像がよくわかるようになりました。最終日には本番環境にデプロイされ、嬉しかったです。
また、リファクタリングのissueもありましたが、難易度が高く、インターン期間内に終わりそうにないです。自分の技術力不足を感じました。

新しいタブの作成

特定のリンクへ行くためのタブを復活させるissueでした。前にあった機能みたいだったので、ある程度のファイルは存在していましたが、自分でファイルを新しく作る必要もありました。新しくファイルやコードを増やすことがとても怖く、プルリクエスト後のレビュー待ちの時は、何もないレビュー画面をずっと見ていました。これを毎日やっていると思うと、エンジニアの方々はすごいと思います。最終日に駆け込みで終わらせました。

フィルタリング機能の追加

広告で流れる動画の縦・横動画のフィルタリング機能の追加するissueでした。最初は順調にコードを書き進めていましたが、ペアプロ時のメンターさん曰く、クエリが長くて私(牛嶋)の手に負えないらしく、断念しました。完全に食い散らかした状態で悔しかったです。

辛かったこと

  • 退勤後のスクランブル交差点

退勤してからのホテルへの帰り道、スクランブル交差点は熊本の祭りよりも人がいたように思えました。人多い、真っ直ぐ歩けない、傘当たる、怖い

  • 渋谷駅のダンジョン

インターン初日の出勤前、渋谷駅で迷いました。地下ダンジョンでした。これに加え指定されたビルと違うビルにいってしまい、初日は遅刻でした。恐るべき渋谷。

まとめ

初めてのインターンでエンジニアの働き方、裁量労働制、技術的にはPHPやCakePHP、Gitを動いているサービスを通して学ぶことができました。実際に、3日目にはメンターさんがリモートワークだったので、slackを使いながら働いていました。わからないことや疑問に感じたことをすぐに質問することができ、とても感謝しています。自分のレベルにあった内容の業務をさせていただき、比較的のびのびしたインターンとなりました。1週間お世話になりました。

広告のCTR(クリック率)を時系列分析してみた

初めまして、ファンコミュニケーションズさんで5日間のインターンでお世話になった澤祐斗です。データ分析でのインターンということで、ビッグデータに触れられる機会を楽しみにしていました。
まずは簡単な自己紹介

  • 東京の理系大学生(非情報系)
  • データ分析歴は3カ月(プログラミングは半年程度)
  • インターン初

今回自分が行ったのは、広告のCTRが時間経過に伴ってどのような変化をするのか、その予測モデルを立てる分析です。

なぜCTRを時系列モデルで分析するか?

CTRは時間によって周期的かつトレンドを持って変動しており、そこを正確にトレース出来る予測モデルを立てることで異常なCTRが得られた際の早い反応や、何か施策を行った時のABテスト的な評価軸にもなると考えられるからである。

CTRの時系列予測

環境

データベース:Treasure Data
クエリ:hive
データ加工:python 3.6
統計解析:Rstudio 1.2

データ抽出

今回一番頭を悩ませたのがこのデータ抽出だった。データベースにある広告に関するログから一時間当たりのインプレッション数、クリック数をを集計し一時間当たりの平均CTRを算出するのだが、後々の回帰分析で用いる説明変数の取り扱いは難しかった。例えば名義尺度などのカテゴリカルな値は、通常の機械学習で用いる際にはOneHotEncodingなどで特微量抽出するのだろうが、今回は一時間当たりで集計するため分散が小さくなったり意味のある特微量抽出が難しくなったりと、その特微量抽出法に苦戦した。結果として、unique countや横持ち変換によって出来るだけ意味を失わないように特微量を抽出できた。
今回最終的に抽出した特微量は以下の通りである。
・OSの種類
・mediaの種類数
・性別(一部のサードパーティから同意の上で取得した情報)
・通信地域における男女比
・広告の形態
・Wifi環境か?
・広告の素材
・再生された広告
・ビデオの長さ など計17種

これらの特微量はpythonのjupyter notebook上でHiveを使ってTreasureDataから抽出した。
今回は7月1日から7月25日までのデータを一時間ごとにまとめて取得したが、Hiveの特性を活かしきれてなかったからか、一回の抽出に30分ほどかかった。打ち間違い等で実行後に誤りを見つけた時は抽出のし直しが面倒だった。

データ加工(xts型への変換)

jupyter notebook上でdataframe形式で受け取ったデータはそのままpythonでpandasでcsv変換し保存し、それをRstudioで読み込んでR上でのデータ加工をした。
Rでは時系列データを簡単に扱うためのデータ型であるxts型(ts型の改良?版)があり、読み込んだデータをxts型に変換した。プロットしたものが以下である。
f:id:yutosawafancs:20190823181321p:plain

CTRは特徴は?

ggtsdisplay関数によりCTRの自己相関を調べた。
f:id:yutosawafancs:20190823181420p:plain
左の図より24時間の周期性があり、右の図より一次の自己相関が確認できた。
次にCTRがどのような分布になっているか確認した。f:id:yutosawafancs:20190823181437p:plain
少し歪んで見えたので、対数変換することに
f:id:yutosawafancs:20190823181455p:plain
シャピロ・ウィルクテストにより比較すると対数変換後の方が正規分布に近いことが確認できた。


モデリング

モデル作成

Rのbsts packageを使って状態空間モデルでモデリングした。
モデリングには
ローカルレベルモデルorローカル線形トレンドモデル
一次の自己相関ありorなし
回帰成分ありorなし   などの観点から計9つのモデルを作成した

モデル評価

予めデータを約二週間ずつ訓練データとテストデータに分けておいた。
訓練データを用いて作成したモデルで予測系列を作り、それとテストデータとのRMSE(二乗平均平方誤差)により評価した。

モデルの決定

映えある優勝者は、説明変数による回帰成分(事前分布の緩和あり)、24時間周期成分、ローカル線形トレンドモデルから構成されるモデルだった。
その予測結果は以下の図である。(赤色が予測系列)
f:id:yutosawafancs:20190823181515p:plain
まあだいたい追えてるんじゃないかな?
RMSEはCTRがだいたいわかってしまうので書けないが、予測値と実値の比より誤差の絶対値をパーセントで計算すると誤差の平均は5.3%程度だった。
誤差は最大で20%くらい。誤差の標準偏差が4%くらいだったので、95%くらいの確率で誤差比13%以内にはあるとわかった。
とすると、誤差比が15〜20%を超えてくると、異常値として何かCTRに異変が起きているかもしれないと通報を受けデータベースのパトロールに迎うことができる。
他にも、何か施策を行った時もこの水準を超えれば有意な差があると判断できるだろう。

説明変数による回帰

bsts packageでは、説明変数の回帰を含んだモデルに対し各特微量の係数を表示できる。

白帯は正の係数で、黒帯は負の係数である。
wifiでの接続数だったり、広告の形態だったりとまあ予想通りな結果も含みつつ、男女比やiOSでの接続数など意外なものもあった。

まとめとインターンを通しての感想

  • 状態空間モデルは理論やアルゴリズムの難しさの割に簡単に実装できた。
  • 実データを用いた分析は面白かった。
  • 職場の雰囲気は比較的静かで集中できた。


まだまだ勉強の日が浅くわからないことも多かったですが、メンターの片桐さん及び片桐さんが書いた記事(Rについて調べたら結構たどり着く)に助けていただきなんとかやり遂げることが出来ました。
毎日お昼ご飯にも連れて行ってくれ、色んな話も出来て楽しかったです。ありがとうございました。中華多めの渋谷ランチでした。
ファンコミュニケーションズは割と定期的にインターン生を迎えていることもあってインターン生も居心地よく作業できる環境が整っています。
実データに触れて分析がしてみたいなど考えている学生の方にはオススメだと思います。
最後に、5日間という短い間ですが初日にお昼ご飯に連れて行ってくださった皆さん、卓球サークルでお世話になった皆さん、インターン生の全体的なサポートをしてくださった長田さん、内田さん、ありがとうございました。

Domain Adaptation Neural Networkを使ったCTR予測

5日間のデータ分析のインターンに参加させていただいた田中です。普段はデータサイエンスをやっています。

内容

今回のインターンでは、Domain Adaptation Neural Networkを使ったCTR予測を行いました。

Domain Adaptation Neural Networkとは転移学習のひとつで、ラベルのあるデータとラベルのないデータを使って、ラベルのないデータに対しても予測できるように学習します。

通常のNeural Networkを使用したCTR予測では、インプレッションすることが出来たデータしか学習に使用できません。よって、インプレッションすることが出来なかったデータに対しては予測精度が著しく落ちることがあります。しかし、Domain Adaptation Neural Networkの場合、インプレッションすることが出来たデータとインプレッションすることが出来なかったデータを使うことで、すべてのデータについて高い精度で予測することが出来ます。

1日目

午前は、アドテクについて教えていただきました。

午後からは、論文をいくつか読んで、Domain Adaptation Neural Networkを構築しました。 Domain Adaptation Neural Networkの構築にはPytorchを使いました。

2日目

始めは、データの前処理とデータの読み込みを実装し、Domain Adaptation Neural Networkの学習をしました。

次に、評価関数の実装を行いました。使った評価関数は、Log Loss、Normalized Entropy、AUC、ECE(期待カリブレーション誤差)です。

CTR予測では、クリックされる確率を予測したいのであって、2クラス分類をしたいわけではありません。つまり、Log Lossなどの評価指標は不十分です。そこで、クリックされる確率を評価するのにより適切なECEという指標を用います。ECEの計算方法は、まずカリブレーションカーブを求めます。カリブレーションカーブとは、データをいくつかのグループにわけて, それぞれのグループ内での予測確率と, データの頻度が一致していることを評価します。そして、対角線とカリブレーションカーブの平均絶対誤差を計算することで求められます。この指標を使うことで、より良いCTR予測モデルを作ることが出来ます。

f:id:yuk_tanaka:20190809185539p:plain
カリブレーションカーブ

3日目

テストデータを使って、Domain Adaptation Neural Networkのテストを行いました。この時に、実装した評価関数を使って評価しました。

4日目

GPUインスタンスを借りて、Domain Adaptation Neural Networkの学習をしました。ここで、実際に運用するときのことを考慮した前処理に修正しました。

5日目

修正したデータと修正した前処理を使ってデータを加工し、Domain Adaptation Neural Networkの学習とテストと評価を行いました。また、一般的なNeural NetworkとDomain Adaptation Neural Networkの比較を行いました。

結果は以下の通りになります。3つの評価関数において、Domain Adaptationを使ったほうが良いという結果になりました。

Neural Network Domain Adaptation Neural Network
Log Loss 0.674 0.661
Normalized Entropy 0.998 0.970
AUC 0.685 0.664
ECE 0.089 0.086

参考文献

www.jstage.jst.go.jp

感想

ハイパーパラメータチューニングと検証ができなかったのが少し残念です。わからないところは非常にわかりやすく教えてもらえるのでよかったです。改善のためのアドバイスもしていただきました。5日間という短い期間でしたが、とても成長できて楽しかったです。

ミニDSPを作りました!

こんにちは!8月5日~8月9日の期間でインターンに参加させていただいた伊東です。
今回ファンコミュニケーションズさんの【ミニDSP構築】のインターンに参加してきました!

とても楽しく、学びのあった一週間だったので、この場を借りて振り返っていきたいと思います!

このインターンを知ったきっかけ

2019年6月20日に開催されたサポーターズさんのエンジニア向け1on1面談会でファンコミュニケーションズさんと出会ったことがきっかけでした。

面談を通じてアドテクノロジーや働き方など様々なお話を聞くことができました。そこでとてもアドテクノロジーに興味が湧いたので、インターンに申し込みました。

面接

面接はとても楽しい雰囲気でお話しすることができました。質問はプログラミング経験や、プログラミングへの思いなどを多く聞かれました。
(夜に面接して、次の日の昼に合格の連絡がきたのでとても驚きました笑)

インターン参加前

インターンの使用言語はPHPでした。今までC言語やRubyを使っていたのですが、PHPは全く触ったことがありませんでした、、、(面接でPHP未経験なことは伝えてました笑)

そこでインターン前から猛勉強を初めて、基本的な参考書を1冊終わらせました。このレベルで大丈夫か不安でしたが、メンターさんが優しく教えてくれたので、無事作り切ることができました!

1日目

午前中は入社手続きや、社内案内などをしてもらいました。とても広く綺麗なオフィスだったので感動しました。特に昇降机がとても気に入って、疲れた時など実際に立って開発をしていました。笑

f:id:n_ito:20190809145303j:plain

午後からは【ミニDSP構築】の課題に取り組みました。DSPとは「Demand-side Platform」の略で、広告を表示させる仕組みの一部分のようなものです。少し複雑な仕組みなので、興味のある人は調べてみてください!

午後は課題の説明、パソコンのセッティングを主にしました。会社から支給されるパソコンなので、初期設定や環境構築などが少し大変でした、、、

今回のインターンではあるリクエストを受け取り、最適な広告、値段を返すAPIを作ることが課題でした。この時点ではあまりAPIもわかってなかったので、とても不安でした、、、笑


2日目

2日目から本格的に開発に取り組みました。とにかく仕様書通りに構築していきました。わからないところはメンターの方がなんでも教えてくれたので、どんどん開発が進んでいきました。

仕様書を読むこと自体もとても勉強になりました。簡単な仕様書ではありましたが、実際にプログラマーの業務を体験できたような気がしました。

3日目

3日目の終盤ではかなり完成に近いものができました。1、2日目でかなりDSPの仕組みについても理解できてきたので、一人でもかなり開発することができました。

ローカル環境でAPIを叩いて、仕様書通りのレスポンスが返せた時はとても感動しました。APIは漠然としたイメージしか知らなかったのですが、実際に作ることで理解がかなり深まりました。

ちなみにお昼にはエンジニアのピザパーティがあって、休憩時間中にピザを食べてました。笑
ざっくばらんに社員の方と話せてとても楽しかったです!ピザを食べ過ぎて午後の開発は少し眠かったです、、、笑

4日目

4日目はこれまでに作ったのDSPを負荷テストしたり、AWSを使って仮想サーバ上に動かしたりしました。AWSを使ったことなくかなり苦戦しましが、ここでもメンターさんが丁寧に教えてくれたのでなんとか使うことができました。

実際に自分の作ったDSPが返した広告がブラウザに表示された時はとても感動しました!AWSではメンターさんや他のインターン生と表示させる広告のオークションなどを行いました。

この日の夜は日本酒会という集まりに参加させていただきました!各自でお酒を持ち寄り、社員の方やインターン生みんなで飲んでいました。ただの会社の飲み会ですね、、、笑

5日目

午前中は退社手続きや細かい修正などをしました。書類を書いている時は少し寂しかったです、、、

午後からはインターン全体フィードバックや応用の課題に取り組みました。応用課題は難しくて、完成させることができませんでした、、、笑
応用課題は中途半端に終わってしまったので、家で完成させたいと思います。

全体の感想

とにかく5日間楽しく、学びのあるインターンでした!社員の方が楽しそうに働いているので、緊張することなくインターンの期間をを過ごすことができました。

会社の雰囲気を知れたこともとても良かったです。5日間エンジニアの方達と同じ空間にいたので、実際に働いている姿を見ることができました。一緒にいるからこそわかる自由な風土や、文化を知れてとても良かったです。

またわからないことがあってもメンターの方に聞ける環境だったので学べること多く、成長することができました!実際のDSPを作った時に出てくる課題など、様々な実践的なことも学べたのもとても良かったです。

5日間ありがとうございました!