機械学習で広告の効果を推定したいお話。

こんばんは。

数学ができなくて悩む今日この頃です。

が、データ分析は数学そのものでは無いので気にせずコツコツやっていこうと思う今日でもあります。

さて、 Japan.Rで発表してまいりました。

内容は「機械学習を使って広告の効果を推定する」という予測モデルを使って因果推論を試みる内容でした。

今回は内容の補足と解説を書きます。

P1010982

発表した資料はこちらです

 

1. Hal Varianのアプローチ

そもそもこのトピックに興味を持ったのは Varianの書いた Big Data: New Tricks for Econometricsというペーパーと、 それに影響を受けたNBERのDemand Estimation with Machine Learning and Model Combinationというペーパーを読んだからです。

なので、このアプローチの事をちゃんと知りたいという人はこのブログなんか読んで無いでさっさと上の二つを読んでくださいw

あと因果推論をかじった事が無い方はそもそもこんな事なんでやるんだっけ?という状態になってしまうと思うので、かじりましょう。

 

さて、Hal Varianの取ったアプローチとは、

広告の売り上げへの効果を考える時に「広告の効果を受けて無いデータ」で予測モデルを作ってそれを広告の効果を受けているデータへ適応し、

予測結果を広告がなかった時の売り上げの予測と考えて、予測値と実データとの差分を広告の効果だと考えようという物でした。

Hal Varianは上記の論文の中では主にBayesian Structural Time Series(BSTS)という変数選択と状態空間モデルが組み合わさったモデルを利用して、時系列の問題として捉える方法について述べています。

ちなみにこのBSTSを使ったアプローチはCausal Impact PackageとしてGoogleから公開されています。

今回の発表においては、 NBERの論文と同様に機械学習を予測モデルとして用いています。

 

2. データの準備

さすがに業務で使ってるデータを使うわけにはいかなかったので、今回はkaggleで似たような条件設定にあるデータを探してきました。

偶然今コンペをしているRossmann Store Salesを使いました。

このデータにはPromoとPromo2という二つの宣伝に関わる変数があります。

  • Promo - indicates whether a store is running a promo on that day
  • Promo2 - Promo2 is a continuing and consecutive promotion for some stores: 0 = store is not participating, 1 = store is participating
  • Promo2Since[Year/Week] - describes the year and calendar week when the store started participating in Promo2
  • PromoInterval - describes the consecutive intervals Promo2 is started, naming the months the promotion is started anew. E.g. “Feb,May,Aug,Nov” means each round starts in February, May, August, November of any given year for that store

データの説明を見ると、promo2が継続的である事からすこし広告とは違う気質の物であると考えられます。(ここは残念ながら仮定です。)

一方でpromoの方は広告の可能性が高いですが、値引きによる宣伝といったような物も含まれていると考えられます。

ただ、今回はアプローチの流れを紹介できれば一旦良いので、ここはpromo=1の場合には広告を行っているという風に定義してしまいます。

 

3. データセットの整形

Rossmann Store Salesのサイトからデータを落としてきて、ここにある天気データ(ポストの中の1,2のデータのみ利用)も紐づけています。

純粋な予測問題を解くときには天気は手に入らないのでどーなんだろうという話はあるのですが、今回の場合には広告の効果だけわかれば良いので罪悪感なく使うことができます。

Competitionは競合店との距離をある日時において表す変数ですがNAの時には999999を代入しています。

学習データからOpen ==1 だけどSales == 0というデータは省いてます。

データセットの準備が出来たら、広告アリのデータとナシのデータの二つに分割します。(dplyrでfilter使えばサクッとできますね。)

広告ナシデータはさらに30%ほどを検証用データとしてまた切り出します。

なので・・・

①広告アリデータ

②広告ナシ学習用データ

③広告ナシ検証用データ

 の3つのデータセットを持っている状態になります。

 

4. 学習

②のデータを使ってGBDTで売り上げの予測モデルを学習します。

GBDTとは何ぞや?という感じの方は、

TJOさんの記事とか

このブログのこの記事とか

もしくは統計的機械学習の基礎とかを参照してもらえればと。

 

で、これをRでやろうと思うと、caret, xgboost, gbmの3つの選択肢があるのかなと。

caretは間接的にxgboostとgbmを使うものなので、計算の中身的にはxgboost or gbmという感じでしょうか。

今回はxgboostをそのまま使っています。理由はcaret慣れてないからです(汗

spm.xgb.np <- sparse.model.matrix(~ .-1, xgb.data.np %>% select(-Sales))
label.np <- log(xgb.data.np$Sales)

cv.gbdt <- xgb.cv(data = spm.xgb.np,
label = label.np,
booster = “gbtree”,
objective = “reg:linear”,
nrounds = 3000,
max_depth = 5,
eval_metric = “rmse”,
eta = 0.5,
nfold = 10)

設定はこんな感じですね。

特にちゃんとグリッドサーチしているわけではないですが、一応10fold CVしてるという状態。

ちゃんとやったらeta下げて木の本数増やす事になりそうだなーとなんとなく思ってます。

あとはxgboost関数で②のデータからモデル作り直して、①と③に対しての予測値を出します。

5. 結果

スライドにもありますが、結果はこんな感じです。

横軸が予測された値(売り上げ)で、縦軸がそのデータの実際の値(売り上げ)です。

桁が一桁なのはlog(Sales)を学習してるからです。

赤が①の広告アリデータの結果。

青が③の広告ナシデータの結果。

黒の線が傾き1の線です。(完璧な予測はこの線上に乗る)

screenshot_2015_12_4

 

ちょっと被って醜いのと、密度がよくわからないので分けてgeom_hex()使ってみるとこんな感じ。

screenshot_2015_12_4 (1)

見てわかる通り、③のデータはそれなりに予測と実際のデータの値が近しいといえます。

②の状況と③の状況に大きな変化がないと考えられるので、②で学習した予測モデルが③でもうまく機能するのは納得ですね。

一方で①のデータでは結構予測が外れている結果になっています。

ただ、今回は①の予測精度を高めるという話ではありません。

①における予測値が広告が無いと仮定したときの売り上げの値を取り、実測値が広告の影響を受けているときの売り上げの値を取っていると考え、その差分を広告の効果だと主張したいわけです。

この時、①における予測値と実測値の差の平均は0.46です。

なので、広告で売り上げが46%ほど上がっていると考えられます。(対数差分の近似と捉えてますがいいのかな?)

 

5. +αで出来る事。

広告自体の表現を0 or 1でやっているので、出稿量などによる効果差などは特に考えられていません。

また、広告の恩恵を受けやすい店舗や条件もあるはずですが、上記の推定の仕方のみだとそれも加味されていません。

これはVarianの論文には書いてありませんでしたが、この差分自体を被説明変数として分析をする事が可能だと思います。

slideの最後のページではGBDTで学習して、その結果における各変数のimportanceをxgb.importance()から出しています。

あらかじめどういった要素が広告の効果を受けやすくするかが分かっていれば、ここで純粋な因果推論のモデルを持ち込んでもいいかもしれないですね。

 

6. このアプローチの良いところ&悪いところ

データの集計が適切にできていて、ちゃんとした精度を持った予測モデルができていれば、このアプローチはかなり便利だなと思います。IVみたいに余計なことをごちゃごちゃ考えずに結果を出せるので。。

また、上で参考にあげている論文の中では、持っているデータのサンプルサイズが大きいときにはこの手法を使う方がより適正であろうということが語られています。

NBERの方では従来の計量経済学の手法を用いると効果がむしろ負の値を取ったと言ったような事がレポートされていました。

悪いところを考えてみると、集計が適切にできないケースは事前知識の有無で簡単に起こってしまうところでしょうか。ただ、これが従来の方法より対策が難しいとは思いません。

また、サンプルサイズが大きくなければ予測モデルの精度もあまり上がってこないので、問題がありそうです。

 

 

 

とまぁ、こんな感じですね。

自分でやってみるまで結構半信半疑だったんですが、やってみると結構明確に結果がでましたし、効果を受けやすい店舗について思いを馳せるのも楽しかったです。

ちなみにこのアプローチでGBDTみたいなモデルってどーなんだろうなーと思ってます。

ちゃんとした回帰モデルで解いた方が良い気がしてます。GBDTで特徴選択して正則化付きの回帰とかですかね。

あとこういう使い方するときにHashing Trickみたいな次元圧縮とかはどう考えれば良いのかなーとか気になって仕方がない状態です。

カテゴリー: R, データマイニング, 経済学, 統計学   パーマリンク


コメントを残す