恥ずかしながら普段はバナー広告のA/Bテストをほぼ行っていないのですが、そろそろ真面目に勉強しようと思って色々と調べてみました。
色んな方のブログがありましたが、僕の中では、この方の考えが合点がいったところがあります。
基本的にはこの方の考えに賛同し、比較についてはクリック数を棒グラフにして信頼区間を見ながら考えよう、というスタンスですが、
今回の記事では、そこに加えて、「では実際のデータでやってみようとしたらどういうことが起きうるか?」を考えてみたいと思います。
まず手元にあるデータってこんな形してません?
実際に自分の手元のデータでA/Bテストをしようとしてみると、色々と簡素化されたデータでは省略されていた問題が出てきて、どうしたらいいものか?と思うことはいでしょうか?(私が今そういう状況です)
適当に作ってみたデータ例です。
Creative Campaign Size Device IMP CTs 1 TYPE_A targeting_1 300 x 250 PC_Tab 2200 5 2 TYPE_A targeting_1 300 x 250 SMF 487200 820 3 TYPE_A targeting_1 320 x 100 PC_Tab 100 0 4 TYPE_A targeting_1 320 x 100 SMF 103500 40 5 TYPE_A targeting_1 320 x 50 PC_Tab 2100 10 6 TYPE_A targeting_1 320 x 50 SMF 550600 7500
例えば、GDNでバナーのデザイン別のレポートって、だいたいこんな感じではないでしょうか?
つまり、入稿したサイズ別*1、配信デバイス別、ターゲティングも”リマーケティング”、”アフィニティカテゴリー”、”トピックターゲット”等、「ん?これは一概に扱っていいのかね?」というデータで出てくると思います。
先ずは、データをプロットしてみる
先ほどのブログの通り、クリック率で比較するとして、データからクリック率(CTR)を求め、かつ二項分布と仮定して信頼区間をだします。
インプレッション数がサンプルサイズということになります。
#データの読込
df <- read.csv("test.csv",header=T)
#CTRの計算
df$CTR <- df$CTs/df$IMP*100
#負の二項分布だと仮定して信頼区間を入れてみる
df$lower <- qbinom(0.025,size=df$IMP,prob=df$CTR)/df$IMP
df$upper <- qbinom(0.975,size=df$IMP,prob=df$CTR)/df$IMP
head(df)
残念ながら信頼区間が出せないレベルのIMP数のものがあります。
Creative Campaign Size Device IMP CTs CTR lower upper 1 TYPE_A targeting_1 300 x 250 PC_Tab 2200 5 0.22727273 0.21000000 0.24500000 2 TYPE_A targeting_1 300 x 250 SMF 487200 820 0.16830870 0.16725780 0.16935961 3 TYPE_A targeting_1 320 x 100 PC_Tab 100 0 0.00000000 0.00000000 0.00000000 4 TYPE_A targeting_1 320 x 100 SMF 103500 40 0.03864734 0.03747826 0.03982609 5 TYPE_A targeting_1 320 x 50 PC_Tab 2100 10 0.47619048 0.45476190 0.49761905 6 TYPE_A targeting_1 320 x 50 SMF 550600 7500 1.36215038 NaN NaN
欠損値のあるレコードを除くことにします
df <- na.omit(df)
ggplot2を使ってクリック率を棒グラフにします。
library("ggplot2", lib.loc="C:/R-3.2.3/library")
g <- ggplot(df,aes(x=Creative,y=CTR,fill=Creative))
g <- g + theme_gray(base_family="Japan1GothicBBB")
g <- g + geom_bar(stat="identity",position="dodge")
g <- g + facet_grid(Size~Campaign+Device)
g <- g + geom_errorbar(aes(ymin=lower,ymax=upper,width = 0.3))
g <- g + geom_text(aes(x=Creative,y=0,label=round(CTR,2)),vjust=-1.2,size=8)
g <- g + theme(axis.text.x=element_text(angle=0,size=8,color="black"))
plot(g)
ggsave(file="df.png",plot=g,height=8.27,width=11.69,scale=1)
facet_gridを使って、縦方向をサイズ別、横方向をターゲティング別+デバイス別、としました。
geom_errorbarを使ってエラーバーとして信頼区間を加えています。
しかしここで、「クリック率が高いこの施策の組み合わせが一番いいのだ!!」と早合点してはいけないと思います。
インプレッション数も一緒に考えてみたい*2
先ほどのデータでは、IMPがやたら多いものと少ないものとがあったと思います。
そもそも余り配信されない組み合わせは強化してもインパクトが少ない筈です。
g <- ggplot(df,aes(x=Creative,y=CTR,fill=Creative))
g <- g + theme_gray(base_family="Japan1GothicBBB")
g <- g + geom_bar(stat="identity",position="dodge")
g <- g + facet_grid(Size~Campaign+Device)
g <- g + geom_errorbar(aes(ymin=lower,ymax=upper,width = 0.3))
g <- g + geom_text(aes(x=Creative,y=0,label=round(CTR,2)),vjust=-1.2,size=8)
g <- g + theme(axis.text.x=element_text(angle=0,size=8,color="black"))
g <- g + geom_point(aes(x=Creative,y=0.4,size=sqrt(IMP)),color="blue",alpha=0.5) +
scale_size_continuous(range = c(min(sqrt(df$IMP))/50,max(sqrt(df$IMP)))/50)
g <- g + geom_text(aes(x=Creative,y=0.4,label=IMP),alpha=0.8,size=4)
plot(g)
ggsave(file="df2.png",plot=g,height=8.27,width=11.69,scale=1)
ということで、geom_pointを使ってインプレッション数をバブルチャートで加えてみました。
バブルチャートの場合、面積が大きさとなりますので、サイズ=半径については、平方根(SquareRoot)をとる方がよいのかなと思いました。
この中で、IMP数が多いターゲティングのうち、明らかにクリエイティブ別のクリック率に差があるものがあれば、そこにクリエイティブを併せていく、というのが良いのではないかと思います。
ターゲティング1でスマートフォンでの配信、ターゲティング2でスマートフォンでの配信が配信数が多そうです。その場合タイプAの方がクリック率が高いようですが、積極的にAだけにしよう!とする程の差でもない気がします。*3
ところでデバイスやサイズについての評価は?
A/Bテストといっても、そもそもクリエイティブの影響とターゲティングの影響とデバイス別の影響と、どれが一番影響しているの?クリエイティブを確認することに意味はあるの??
という疑問もあると思います。
そこで、回帰分析をしてみます。
#使わない値を外す
df <- df[,-which (colnames(df) %in% c("IMP","CTs","lower","upper"))]
#カウントデータなので二項分布を使ったロジスティック回帰
df_lm <- glm(CTR ~.,family=binomial,df)
summary(df_lm)
結果
Coefficients: Estimate Std. Error z value Pr(>|z|) (Intercept) -2.1547 1.4890 -1.447 0.148 CreativeTYPE_B -0.1318 1.0718 -0.123 0.902 Campaigntargeting_2 0.2168 1.0730 0.202 0.840 Size320 x 100 -1.9741 2.7654 -0.714 0.475 Size320 x 50 1.3091 1.6717 0.783 0.434 Size468 x 60 1.0124 1.3297 0.761 0.446 DeviceSMF 0.3110 1.2376 0.251 0.802
Estimateが影響の指数になるわけですが、このままではみにくいので、図示してくれる便利なパッケージを使いグラフで見ます。
library("coefplot", lib.loc="C:/R-3.2.3/library")
g <- coefplot(df_lm)
g <- g + theme_gray(base_family="Japan1GothicBBB")
plot(g)
ggsave(file="df_lm.png",plot=g,height=8.27,width=11.69,scale=1)
こんな感じです
ところでサイズって4つありましたよね?
一つ減っているのは、Rの優秀さの現れです。
サイズ、クリエイティブのタイプ、デバイス というのは数値ではなくカテゴリカルなデータです。本来は、0,1のデータに変換しないと回帰分析はできません。
例えば、クリエイティブの列は、クリエイティブAを「1」、クリエイティブBを「0」とする列に変換しないといけません。サイズだと、サイズAかどうか?で1列、サイズBかどうか?で1列、サイズCかどうか?で1列、サイズDかどうか?で1列、と作ります。
ただし、そのままだと情報が各カテゴリーで1つずつ余分になります。例えば、サイズAでもBでもCでもないとわかればDであることは明白ですのでサイズDに関する列は情報として余分です。
どれか一列を基準としてはずさないといけないのですが、Rのlmやglmは、勝手に一つ減らしてくれるのです。
逆に言うと、表やグラフを見るとき、それを思い出しつつ注意してみないといけません。
因みにこのグラフを見ると、クリエイティブタイプやターゲティングより、バナーのサイズの方の影響の方が多そうですね。
結論
残念ながら今回のテストデータでは、クリエイティブをどちらにすべきか?については、余り判断に足る情報は得られませんでした。
今回はテストデータでしたが、実際の施策でも結構そんなものじゃないかと思います。最初からちゃんとターゲティングができていれば無理にPDCAを回す必要なんてないからです。PDCAを回して何か小さな改善をしていくことよりも、事業へのインパクトの有無を判断軸にしておきたいと思います。
----------------------------
その他参考にしたサイト
■カテゴリカルデータの分析について
■バブルチャートについてsutchy.cocolog-nifty.com
■信頼区間について
http://cse.naro.affrc.go.jp/takezawa/r-tips/r/60.html
■エラーバーの出し方について
geom_bar | ggplot2で棒グラフや積み上げ棒グラフを描く方法
■coefプロットについて