渋谷駅前で働くデータサイエンティストのブログ

元祖「六本木で働くデータサイエンティスト」です / 道玄坂→銀座→東京→六本木→渋谷駅前

改善施策の効果検証はどうやるべきか?

最近「効果検証」というキーワードを見聞きする機会が増えてきたので、僕のこれまでの経験に基づいてちろっと書いてみます。


シンプルにA/Bテストをやる場合


色々なところで既に言われていますが、独立性の検定*1一択でしょう。そもそも独立性の検定って、古典的な統計学の世界では

  • 予防接種が効いたor効かなかった
  • 工場のある工程への改善が効果があったorなかった

といったテストに使われる手法なんですよね。これはどこからどう見てもその当時のA/Bテストそのものです。単にwebで全自動でできるかできないかぐらいの違いしかないです。


ということで、例えばこういう例を考えてみましょう*2

CVしなかった CVした CVR
施策打つ前 2892 447 13.3%
施策打った後 2422 439 15.3%


物凄くボリューム感が小さいんですが(笑)、そこは置いといて。さて、これは効果があったと言えるんでしょうか?


独立性の検定って、数式さえ覚えていればExcelでもできるんですが、RやSPSSなどでやった方が圧倒的に手っ取り早いです。Rなら以下のような感じでいけます。

> x<-matrix(c(2892,447,2422,439),ncol=2,byrow=T) # データ入力
> chisq.test(x) # カイ二乗検定

	Pearson's Chi-squared test with Yates' continuity correction

data:  x 
X-squared = 4.6596, df = 1, p-value = 0.03088 # 有意差あり(施策の効果あり)

> fisher.test(x) # フィッシャーの正確確率検定

	Fisher's Exact Test for Count Data

data:  x 
p-value = 0.02899 # 有意差あり(施策の効果あり)
alternative hypothesis: true odds ratio is not equal to 1 
95 percent confidence interval:
 1.014403 1.355613 
sample estimates:
odds ratio 
  1.172651


ということで、このケースでは「改善施策の効果あり」という結論になりました。勿論、何が何でも統計学的に正確でなければいけない!ってことはないんですが*3、一つのキーポイントになるのは間違いないと思います。


テレビCMのGRPなど施策のボリュームが定量的に表せる場合


色々やり方はあるんでしょうが、僕はGRPの時系列とKPIの時系列とを合わせてVARモデルにして、その因果性を調べるというやり方をしていました。

> x1<-matrix(rep(0.5,30))
> x2<-matrix(rep(1,30))
> x3<-matrix(rep(0.3,30))
> x<-rbind(x1,x2,x3)
> x<-ts(x) # GRPの時系列のつもり

> y1<-matrix(rnorm(32)+5)
> y2<-matrix(rnorm(30)+7.5)
> y3<-matrix(rnorm(28)+2.5)
> y<-rbind(y1,y2,y3)
> y<-ts(y) # KPIの時系列のつもり

> z<-cbind(x,y) # 2つの時系列を合わせる


f:id:TJO:20130611110020p:plain


上のxがGRP、yが何がしかのKPIということにしましょう。一般にGRPは事前に数週間or数ヶ月先まで計画されているものなので、予め取得することが可能な数値データと見て良いと思います。


そこで、これらを表現するVARモデルを推定し、これに基づいて両者の因果関係をチェックしてみましょう。

> VARselect(z) # VARモデルの次数を推定する
$selection
AIC(n)  HQ(n)  SC(n) FPE(n) 
     2      1      1      2  # AICによればp = 2が最適らしい

$criteria
                 1          2           3           4           5
AIC(n) -4.44412676 -4.4618461 -4.44926151 -4.40074093 -4.36952182
HQ(n)  -4.37250006 -4.3424683 -4.28213255 -4.18586083 -4.10689060
SC(n)  -4.26547476 -4.1640928 -4.03240685 -3.86478493 -3.71446450
FPE(n)  0.01174819  0.0115448  0.01169769  0.01229174  0.01270175
                 6           7           8           9          10
AIC(n) -4.34575727 -4.29779199 -4.21675912 -4.13121919 -4.18302645
HQ(n)  -4.03537492 -3.93965850 -3.81087449 -3.67758344 -3.68163956
SC(n)  -3.57159862 -3.40453200 -3.20439780 -2.99975654 -2.93246247
FPE(n)  0.01303726  0.01372121  0.01494159  0.01636309  0.01564099

> z.var<-VAR(z,p=2) # VARモデルを推定する
> causality(z.var) # Granger因果性を検定する
$Granger

	Granger causality H0: x do not Granger-cause y

data:  VAR object z.var 
F-Test = 16.292, df1 = 2, df2 = 166, p-value = 3.464e-07 # x⇒yなる有意な因果関係がある


$Instant

	H0: No instantaneous causality between: x and y

data:  VAR object z.var 
Chi-squared = 0.3957, df = 1, p-value = 0.5293 # x⇔yなる相互影響はない


> z.irf<-irf(z.var,n.ahead=15,ci=0.95) # 向こう15期までのインパルス応答関数を推定する
> plot(z.irf)


f:id:TJO:20130610171403p:plain


Granger因果性検定では、x⇒yなる因果関係があるという結論になっています。


またインパルス応答関数を見ると、x(GRP)に1標準偏差の分だけ変動を与えるとy(KPI)にショックが伝わって、遅延つきのインパルス応答が生じているのが分かります。すなわち、x⇒yなる因果関係がある!ということですね。ちなみにこれを逆にするとこういう遅延つきのインパルス応答は見られないので、逆は成り立たないという結論になります。


ともあれこれで、「GRPが変動した分だけKPIにもその変動が伝わる ⇒ CMの効果がKPIに表れている」ということが(間接的ながら)言えるわけです。


また、GRPは未来の値まで事前に分かっているケースが多いので、今回求めたインパルス応答関数を用いてKPIの予測値を出すことも出来ます。


なお、VARモデルなのでお決まりの「見せかけの回帰」「共和分」の問題に注意が必要です*4。お忘れなく。


特定の導線設定などユニークユーザーベースで施策を行う場合


この場合はもう仕方ないので、「その導線をたどったか否か」でユーザー行動データそのものを分けて抽出し、それに対して色々分析をやっていくしかないです。つまり、DBから抜いてくる時点でその辺の条件分岐をかけていく必要があります。


つまり、Hadoop + Hiveなんかだと延々と"JOIN"文 vs. "LEFT OUTER JOIN ... WHERE a IS NULL"文みたいなのを繰り返すことになるわけで、はっきり言ってダルいです。個人的にはかったるくて仕方ないので、対象となる範囲に絞って生テーブルをローカルのMySQLとかに落として、そこから抽出した方が得策だろうと思ってます。


抽出してきたデータの分析方法は何でも良いと思いますが、きちんと「施策を打つ前vs.後」という構図に持ち込む必要があります。というか、そうでなければ効果検証になんてなりませんので。。。


そもそも「効果検証」って意味あるの?


以前の記事(「毎日の数字を追いかけ、毎日改善する」ことの意外な落とし穴)でグサグサ刺した通り、結局あたふた焦って「毎日カイゼン毎日効果検証」なんてしていたら意味がないわけです。


大事なことはどういう方法を使うかではなくて、どれくらい大局的かつ明確なトレンドをしっかり捕まえ、それが自分たちの放った改善施策とどう関係しているか?をきちんとロジカルに考えることだと、僕は思ってます。

*1:適合度検定の発展バージョン

*2:数字そのものは『自然科学の統計学』(東京大学出版会)からの孫引きです笑

*3:このケースではいくら統計学的に意味があったって2%しか差がないわけで

*4:ただしインパルス応答関数の推定は見せかけの回帰や共和分にそこまで大きくは左右されないことが近年の研究で分かっているそうで、そこにしか興味がないのであれば気にしなくても大丈夫みたいです