ほくそ笑む

R言語と統計解析について

施策効果測定におけるメタアナリシスの応用

はじめに

マーケティング施策を行うときに、その施策効果を測定するために、コントロールグループ(施策を適用しないユーザ)を作る場合がある。 例えば、販促メールを送るという施策を行うときに、一部のユーザには送らないようにする。 仮にメールを送らなかったユーザの平均売上が1000円であり、メールを送ったユーザは平均1100円だとすると、その差である100円が1人あたりの施策効果となる。

しかし、施策を適用しないユーザの数を増やすと、全体の売上効果はそれだけ減少してしまう。 つまり、全体のユーザ数を1万人とすると、全員にメールを送れば100万円の売上効果があるが、半分の5千人をコントロールとすると売上効果も半分の50万円となる。 したがって、コントロールグループに割り当てる人数はなるべく小さくしたいという要求がある。

ただし、コントロールグループの人数を少なくすると、効果測定の精度が落ちるという問題がある。 今、1万人のユーザがいるECサイトで、メール施策を行うことを考えよう。 このとき、コントロールグループは全体の 1% である 100人しか取れないとする。 ユーザの作り出す売上がポアソン分布に従うとして、

  • メールを送らないユーザは平均 1000 円の売上
  • メールを送ると平均 1100 の売上

すなわちメール施策の真の効果は 100円としてシミュレーションしてみる。

set.seed(17744)
# 施策未実施ユーザ 100人の個々人の売上
control_group   <- rpois( 100, 1.0) * 1000
# 施策実施ユーザの 9900人の個々人の売上
treatment_group <- rpois(9900, 1.1) * 1000

# それぞれのグループに対して10人の売上を表示
head(control_group, 10)
#> [1] 1000 2000 2000 2000 1000 1000    0    0    0 4000
head(treatment_group, 10)
#> [1] 4000 1000 3000 1000    0 1000 2000 1000 1000 1000

こうして得られた各ユーザの売上を使って、施策効果を推定する。 各グループの平均売上の差が施策効果である。

effect <- mean(treatment_group) - mean(control_group)
effect
#> [1] 47.3

施策効果は 47 円と算出され、真の効果である 100円から大きくずれてしまった。

また、施策に本当に効果があったかは統計的仮説検定を用いて判断することが多い。 ここでは Welch t-test を使ってみよう。

t.test(treatment_group, control_group)
 Welch Two Sample t-test

data:  treatment_group and control_group
t = 0.41425, df = 100.68, p-value = 0.6796
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -179.1100  273.6555
sample estimates:
mean of x mean of y 
 1087.273  1040.000 

検定の結果より、p-value = 0.68 なのでこの施策には有意な効果はないと判断されてしまう。

つまり、コントロールグループの人数が少ないことが原因で

  • 施策効果の推定値が真の値から大きくずれてしまう
  • 検定を行なっても有意な効果がないと判断されてしまう

という問題が起こる。

ただし、このようなマーケティング施策は繰り返し行われることが多い。 例えば、販促メールを毎週水曜日に送るなどである。 この場合、メタアナリシスを用いて上記の問題を解決できる。

今、上記のメール施策を毎週水曜日に5回繰り返したとする。 このときのメタアナリシスの結果を下図に示す。

f:id:hoxo_m:20180809192359p:plain

各週のメール施策において算出された効果は Effect 列に記載されている。 これはばらつきが大きく、マイナスになることもあることがわかる(2018-08-08)。 右側のグラフは、四角が Effect であり、そこから左右に伸びる線が信頼区間を表している。縦線は 0円であり、2018-08-22を除いて各施策は 0 をまたいでいるため、検定結果は有意でない。

メタアナリシスによってこれらの結果を統合することで、推定精度を向上させることができる。 メタアナリシスによる推定結果は上図の Summary に記されている。 これによると、効果の推定値は 114 円であり、真の効果 100円に近い。 また、信頼区間は 26円から 202円となり、0円をまたがないので検定は有意になる。

本記事ではRでこれを行う方法を説明する。

メタアナリシスの実践

次のように、5回の施策に対して、その効果と信頼区間を求める。

# 8/1(水) から 8/29(水) までの水曜日の日付を取得
begin <- as.Date("2018-08-01")
end   <- as.Date("2018-08-29")
dates <- seq(begin, end, by = "weeks")

result <- data.frame()
for (i in seq_along(dates)) {
  date <- dates[i]
  
  # 売上のシミュレーション
  set.seed(as.integer(date))
  control_group   <- rpois( 100, 1.0) * 1000
  treatment_group <- rpois(9900, 1.1) * 1000
  
  # 売上効果の算出
  effect <- mean(treatment_group) - mean(control_group)
  
  # Welch t-test による信頼区間の推定
  t <- t.test(treatment_group, control_group, conf.level = 0.95)
  lower <- t$conf.int[1]
  upper <- t$conf.int[2]

  # # ブートストラップ法による信頼区間の推定
  # library(simpleboot)
  # boot <- two.boot(treatment_group, control_group, mean, R = 1000)
  # ci <- boot.ci(boot, conf = 0.95, type = "perc")
  # lower <- ci$perc[4]
  # upper <- ci$perc[5]

  res <- data.frame(date, effect, lower, upper)
  
  result <- result %>% bind_rows(res)
}

print(result)
        date     effect     lower    upper
1 2018-08-01  47.272727 -171.8910 268.2418
2 2018-08-08  -4.545455 -224.9838 181.0983
3 2018-08-15  18.181818 -171.9945 194.4213
4 2018-08-22 306.969697  150.0565 465.5196
5 2018-08-29  92.323232 -129.1142 297.0604

それぞれの施策実施日について、効果と信頼区間が算出された。 ここでは信頼区間の推定にt検定を用いたが、売上が正規分布に従わないことが不安ならブートストラップ法を使うと良い。 ただし以下では信頼区間は平均について対称であることを仮定している。

この結果に対して『Rで楽しむ統計』(p.108) を参考にメタアナリシスを行う。

Rで楽しむ統計 (Wonderful R 1)

Rで楽しむ統計 (Wonderful R 1)

library(dplyr)

summary <- result %>%
  mutate(weight = 1/(upper - lower)^2, 
         effect = effect * weight / sum(weight)) %>%
  summarise(effect = sum(effect), sd = sqrt(1/sum(weight))/2) %>%
  mutate(lower = effect - sd, upper = effect + sd) %>%
  select(-sd) %>%
  mutate(date = "Summary") %>%
  select(date, everything())

print(summary)
     date   effect    lower    upper
1 Summary 114.2419 26.44446 202.0394

それぞれの施策に対して信頼区間の幅を2乗して逆数を取ったものを重みとする。 それぞれの施策効果に対して重み付けを行い、全てを足し合わせたものが統合された施策効果となる。 また、信頼区間は重みの総和の逆数の平方根によって算出される。 メタアナリシスによって算出された施策効果は 114円であり、真の効果100円と近い値が算出された。 また、信頼区間は 26円から202円であり、0円をまたがないため、統計的に有意な結果であることが言える。 ここではメタアナリシスのモデルとして固定効果モデルを用いたが、一般的には施策効果にはぶれが生じるため、それを考慮したい場合はランダム効果モデルを用いる。

メタアナリシスの可視化にはフォレストプロットというものが使われる。 これは次のように作成できる。

library(forestplot)

nrow <- nrow(result) # 施策の回数

# 施策結果とメタアナリシスの結果を統合
df <- result %>% 
  mutate(date = as.character(date)) %>% 
  bind_rows(summary)

# フォレストプロットの左側に表示される表データの作成(日付と効果)
labeltext <- list(c("Date", as.character(df$date)),
                  c("Effect", round(df$effect)))

# フォレストプロットの描画
forestplot(labeltext, mean = c(NA, df$effect), 
           lower = c(NA, df$lower), upper = c(NA, df$upper),
           is.summary = c(TRUE, rep(FALSE, nrow), TRUE),
           hrzl_lines = gpar(col="#444444"))

f:id:hoxo_m:20180809192359p:plain

それぞれの施策における効果と信頼区間、そして統合された結果が可視化された。

まとめ

マーケティング施策効果の測定において、

  • 施策を実施しないコントロールグループが作られる
  • コントロールグループの人数が少なく効果測定の精度が低い
  • 同じ施策が繰り返される

という場合において、メタアナリシスを用いて推定精度を向上させる方法を説明した。

参考文献

Rで楽しむ統計 (Wonderful R 1)

Rで楽しむ統計 (Wonderful R 1)