A/B テスト — p 値より先に見るもの
一言でいうと
A/Bテストの結論は、p値1つでは出ません。① 割り当ての比率は設計どおりか(SRM)、② 効果を捉えるのに十分な人数が集まったか(検出力)、③ あらかじめ決めた時点で1回だけ見たか(途中観察)、④ 何回比較したか(多重比較)。この4つを先に確認し、その後で、信頼区間で効果の大きさを語ります。
なぜ必要なのか
小さなチームほど、実験を急ぎます。トラフィックが少ないので、毎日ダッシュボードを開いて見て、pが0.05を下回った日に、「勝った」と言ってデプロイします。結果が出なければ、デバイス別・新規/再訪別に分けて見ているうちに、1つが有意に出たら、そのセグメント向けの機能を作ります。どちらもよくあることで、どちらも、偶然を発見と取り違える、最も速い方法です。
JohariらのPeeking at A/B Tests(KDD 2017)は、古典的なp値と信頼区間が、標本サイズをあらかじめ決めておいたときだけ成り立ち、ダッシュボードを見続けて、有意になった瞬間に止めると、偽陽性の確率が大きく膨らむと報告しています。また、Fabijanらの標本比の不一致の研究(KDD 2019)は、観測された割り当て比率が期待と違うSRMを、さまざまなデータ品質の問題の「症状」として扱い、SRMがある実験の分析は信頼できないと書いています。
どう動くのか
SRM: 最初に確認します。50:50で分けたなら、両側のユーザー数は近くなければなりません。期待値との差を、カイ二乗適合度検定(自由度1)で測り、このラボはp < 0.001をSRMとみなします。片側のユーザーの一部が記録から抜けるバグ(リダイレクトの失敗、ボットフィルター、アプリのバージョン)は、コンバージョン率まで、片側に傾けます。SRMが見えたら、コンバージョン率を解釈せず、原因を先に探します。
2つの比率のz検定と信頼区間: 差 = Bのコンバージョン率 − Aのコンバージョン率です。検定統計量は、「両側が同じ」という仮定のもとで、プール比率で標準誤差を求め、95%信頼区間は、それぞれの比率で求めた非プールの標準誤差に、1.96(正確にはNormalDist().inv_cdf(0.975))を掛けます。Python標準ライブラリのstatistics.NormalDistが、正規分布のcdfとinv_cdfを提供するので、外部パッケージは必要ありません。信頼区間が0を含まず、正の方向なら、「Bが優れている」に加えて、どれだけ優れているか(下限がいくつか)を言えます。
検出力と標本サイズ: 基準のコンバージョン率p1から、絶対差δだけの違いを、有意水準α(両側)と、検出力1−βで捉えるには、片側に必要な人数は、正規近似で、次の式になります。
n = ⌈ ( z(1−α/2)·√(2·p̄(1−p̄)) + z(1−β)·√(p1(1−p1) + p2(1−p2)) )² / δ² ⌉, p2 = p1 + δ, p̄ = (p1+p2)/2
基準のコンバージョン率11%の近くで、1%ポイントを、α=0.05、検出力80%で捉えるには、片側に1万人を大きく超えます(例)。標本が足りない実験で有意に出た効果は、実際より大きく推定される傾向があります。GelmanとCarlin(2014)が、これをType M(大きさ)の誤りと呼びました。そのため、標本サイズは、実験を始める前に決めます。
途中観察: A/A実験(両側が同じ画面)でも、累積p値を毎日計算すれば、いつか0.05を下回ることがあります。決めておいた日に1回だけ見れば、その日のpが結論です。毎日見たいなら、逐次検定のように、その目的のために設計された方法を使います。
多重比較: バリアント5つを対照群とそれぞれ比べたり、セグメント10個に分けたりすると、効果がなくても、0.05を下回るものが1つくらい出るのが自然です。Holm(1979)のステップダウン法は、p値を小さいものから、k番目に(m−k+1)を掛けてαと比べ、最初に超えたところで止めます。ボンフェローニより保守的でなく、全体の偽陽性の確率を、α以下に抑えます。
現場での姿
- 「Bが3日で勝った」。3日目に1回、有意になっただけでした。2週間後のpは、0.6でした。
- 変更側のユーザーが、2%少なく記録された実験。原因は、新しい画面の読み込みが遅く、イベントが送信される前に去った人たちでした。残った人だけを見れば、コンバージョン率が高く見えます。
- 全体では差がないのに、「タブレットの新規」でだけ有意だというレポート。セグメントを10個見れば、よく起きることです。
間違いに気づく方法
- 割り当ての比率から見ます。50:50の実験で、片側が数パーセント少ないなら、コンバージョン率は解釈しません。
- 結論を出した日付が、実験の前に決めた日付と同じかを見ます。違うなら、途中で覗いたのです。
- レポートに、比較を何回したか(バリアント数 × 指標数 × セグメント数)が書かれているかを見ます。書かれていなければ、補正もなかった可能性が高いです。
- 効果量を、点推定1つで語っているなら、信頼区間の下限も一緒に書きます。
次のラボですること
4つの実験で、SRMの検査、2つの比率のz検定と信頼区間、標本サイズの計算を、関数として作り、A/A実験の日付別の累積pで、途中観察の落とし穴を、バリアント5つとセグメント10個で、Holm補正の前後の違いを確認します。最後に、実験ごとにデプロイの判断を、1枚で出します。採点ツールは、あなたの関数を、ランダムな入力で再び呼び出します。