母比率の差の検定について

はじめに
ABテストを実施する際に、CVRやCTR等の割合値をKPIとすることがある。
観測されたKPIの差分に基づいた意思決定のために、母比率の差の検定を実施することが多い。
母比率の差を検定する方法はいくつか存在するので、本稿ではそれぞれまとめる。

参考文献

サンプルサイズの計算
Rでは pwr
というパッケージにはサンプルサイズや検出力の計算を行う関数が実装されている。
pwr.2p.test
は、サンプルサイズの等しい2群における母比率の差の検定に対応した関数である。
サンプルサイズが異なる検定については、 pwr.2p2n.test
が対応している。
効果量について
効果量を表すパラメータとして h
が設定されているが、これは cohen's h のことである。
test群の母比率を
ES.h
を利用すれば、割合の値から効果量に変換してくれる。
p_t = 0.4
p_c = 0.3
h_from_pwr = ES.h(p_t, p_c)
h_raw = 2 * asin(sqrt(p_t)) - 2 * asin(sqrt(p_c))
print(c(h_from_pwr, h_raw))
# 0.2101589 0.2101589
Rでの実装
サンプルサイズを計算したい場合、 n
に NULLを設定して実行すれば良い。
pwr.2p.test(h = ES.h(0.4, 0.3), n = NULL, sig.level = 0.05, power = 0.8,
alternative = "two.sided")
Difference of proportion power calculation for binomial distribution (arcsine transformation)
h = 0.2101589
n = 355.4193
sig.level = 0.05
power = 0.8
alternative = two.sided
NOTE: same sample sizes
1群あたり355のサンプルサイズ(2群合計で710)が必要であることが分かる。
Pythonでの実装
Pythonでは statsmodels
に実装されている、 statsmodels.stats.power.NormalIndPower
を用いる。後述するが、この検定はZ検定を行っているため、それに対応した関数を用いることになる。
効果量についても statsmodels
で算出することが出来る。
import statsmodels.api as sm
print(sm.stats.proportion_effectsize(0.4, 0.3))
# 0.2101589252771574
solve_power
というメソッドでサンプルサイズを求める。Rとは異なり、2群のサンプルサイズが異なる場合にも対応している。2群のサンプルサイズを揃えたい場合は、 ratio=1.0
を指定すれば良い。総サンプルサイズは、nobs1 + nobs1 * ratio
で求めることが出来る。
import statsmodels.stats.power as smp
import statsmodels.api as sm
es = sm.stats.proportion_effectsize(0.4, 0.3)
n = smp.NormalIndPower().solve_power(
effect_size=es
, nobs1=None
, alpha=0.05
, power=0.8
, ratio=1.0 # 2群で等しいサンプルサイズにしたい
, alternative='two-sided'
)
print(n)
# 355.41923591440724
Rと同じ値が得られることが分かる。

理論的な話
なぜZ検定になるのかを説明するために、簡単ではあるが理論的な話をする。
まずはじめに、問題設定としてtest群、control群の成功数がそれぞれ二項分布に従うと仮定する。
更にデルタ法により、これをarcsinで変換した fuga も正規分布に従うことが分かる。
以上より、変数変換したhogeとfugaが標準正規分布に従うことから、Z検定を実施すれば良いことが分かる。

別のZ検定を行う場合のサンプルサイズ計算
arcsinで変換せずとも、Z検定を行うことが出来る。
Rでの実装
Pythonでの実装
statsmodels に実装されている statsmodels.stats.proportion.samplesize_proportions_2indep_onetail
を用いれば良い。こちらはサンプルサイズが2群で等しくない場合にも適用することが出来る。
diff
は母比率の差分、prop2
はいずれかの母比率を指定する。
from statsmodels.stats.proportion import samplesize_proportions_2indep_onetail
samplesize_proportions_2indep_onetail(
diff=(p2-p1)
, prop2=p1
, power=0.8
, ratio=1.0 # 群間でサンプルサイズが等しい場合
, alpha=0.05
, alternative='two-sided'
)

理論的な話
こちらの場合、どのような理論でサンプルサイズ計算がなされるのか。
...

2つのZ検定の比較
今回の設定(ABテストでCVRやCTRをKPIとして差分を検定する)の場合、どちらを利用するのが望ましいだろうか。
結論から言うとどちらでも良さそうである。そもそも2つで大した差分が出てこない。
仮定の違い
どちらも統計量を定義するまでに、いくつかの仮定を置いている。
まずは角変換を行う方では、①n -> 無限を仮定している。