Open7

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

hanatahanata

はじめに

ABテストを実施する際に、CVRやCTR等の割合値をKPIとすることがある。
観測されたKPIの差分に基づいた意思決定のために、母比率の差の検定を実施することが多い。

母比率の差を検定する方法はいくつか存在するので、本稿ではそれぞれまとめる。

hanatahanata

サンプルサイズの計算

Rでは pwr というパッケージにはサンプルサイズや検出力の計算を行う関数が実装されている。

pwr.2p.test は、サンプルサイズの等しい2群における母比率の差の検定に対応した関数である。
サンプルサイズが異なる検定については、 pwr.2p2n.test が対応している。

効果量について

効果量を表すパラメータとして h が設定されているが、これは cohen's h のことである。

https://en.wikipedia.org/wiki/Cohen's_h

test群の母比率を p_t、control群の母比率を p_c とすると、cohen's h は以下のように定義される。

h = | 2arcsin(\sqrt{p_t}) - 2arcsin(\sqrt{p_c}) |

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と同じ値が得られることが分かる。

hanatahanata

理論的な話

なぜZ検定になるのかを説明するために、簡単ではあるが理論的な話をする。

まずはじめに、問題設定としてtest群、control群の成功数がそれぞれ二項分布に従うと仮定する。

X_t \sim Bin(n_t, p_t), X_c \sim Bin(n_c, p_c)

n \to \infty を満たす時、中心極限定理により hoge が正規分布に従うことが分かる。

更にデルタ法により、これをarcsinで変換した fuga も正規分布に従うことが分かる。

以上より、変数変換したhogeとfugaが標準正規分布に従うことから、Z検定を実施すれば良いことが分かる。

hanatahanata

別のZ検定を行う場合のサンプルサイズ計算

arcsinで変換せずとも、Z検定を行うことが出来る。

Rでの実装

Pythonでの実装

statsmodels に実装されている statsmodels.stats.proportion.samplesize_proportions_2indep_onetail を用いれば良い。こちらはサンプルサイズが2群で等しくない場合にも適用することが出来る。

https://www.statsmodels.org/dev/generated/statsmodels.stats.proportion.samplesize_proportions_2indep_onetail.html

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'
)
hanatahanata

理論的な話

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

...

hanatahanata

2つのZ検定の比較

今回の設定(ABテストでCVRやCTRをKPIとして差分を検定する)の場合、どちらを利用するのが望ましいだろうか。
結論から言うとどちらでも良さそうである。そもそも2つで大した差分が出てこない。

仮定の違い

どちらも統計量を定義するまでに、いくつかの仮定を置いている。
まずは角変換を行う方では、①n -> 無限を仮定している。