A/B テストのテスト一覧

# これは何
「A/Bテストが正しく実施できていない」ことを検知するためのテストをまとめたものです。
A/Bテストの正常ケースは理解しているが、実際に実施するさいに「これで大丈夫なんだっけ？」と不安がある人が想定読者です。

「これだけおさえておけばA/Bテストは大丈夫！（十分）」ではなく、「<b>これができてないとA/Bテストが正しく実施できているか怪しい</b>（必要）」を書いてます。他の例にもれず。A/Bテストのテストのカバレッジを100%に近づけることは非常に困難なので、"最低限これくらいは"を書きました。

この記事は、[Trustworthy Online Controlled Experiments : A Practical Guide to A/B Testing]( https://experimentguide.com/) （本記事ではカバ本と称します。[和訳](https://www.kadokawa.co.jp/product/302101000901)も出てます。） を参考にしました。これにほぼ必要な情報が非常に高い水準でまとまってます。非常に強くおすすめします。
ただ、さっとわかる一覧+この本にない機械学習モデル関連のテストもまとめたく、本記事を投稿しました。

以下、A/Bテストの段階別に意識すべき確認項目をまとめます。また最後に機械学習が絡む場合のテスト観点もほんの少しだけふれます。基本的には機械的に検知できるものをのせてます。一般的なシステム観点のテストは分量がだいぶ多いので本記事では割愛）もふれます。この手の話題に興味ある方はぜひ、カバ本も読んでみてください！


# A/B テスト実施前

ここではA/Bテストを実施する前に既にあるユーザーの行動ログからA/Bテストの計画に対してテストを行います。ここでのエラー検出によって、大幅な手戻りを防ぐことができます。

## 検出力の確認
テスト期間と介入群（変化を加える方）への実験単位（だいたいはユーザー、たまにセッションなどが該当）への割当割合が妥当か（十分か）を事前に確認（検出力の確認）をすることが望ましいです。カバ本によると、単に検出力不足で失敗したA/Bテストがそこそこあるそうです（第3章）。
これには「どのくらいの差を検知したいか」と「どのくらいの確率まで偽陰性（本当は差があるものを見落とす）を許容するか」を事前に決める必要があります。前者は実用上の理由から（つまり適当に）決めるしかなく、それが最小検出可能効果よりも大きいかを確認すします。偽陰性率は慣習的に20%と設定されることが多いらしいです。
最小検出可能効果は検出力(1-偽陰性率)を80%、介入群とコントロール群(基準値となる変化させない方)への実験単位の割当割合を1:1にした場合、以下の式で近似できます。便利。

$ n ← 16 \sigma ^2 / \delta ^2 $

$n$は各実験群に必要なサンプルサイズ（実験単位の数）で、ここからテストに必要な期間や介入群への割当割合を逆算して推定できます

$\sigma ^2$ は着目した指標の標本分散で、$ \delta $ は どのくらいの差を検知したいか、です。


## シミュレーションによるA/Aテスト
今回のA/Bテストで評価したいアイデアが「購入確認画面のUI変更で、購入数が向上するか」だとしましょう。
その場合、過去の「ユーザーの購入画面の行動ログ」から「購入数」の計算を、かぶりなく独立にユーザーをランダムサンプリングし、A/Bテストで用いる検定手法を実際に適用し、ｐ値を計算できます。この計算をランダムサンプリングの部分を多数繰り返すことでp値の分布が得られます。このp値の分布が一様分布になっていれば理論通りです（詳細はカバ本の第19章参照）。
以下のようなケースでは、p値の分布が一様にならず、正しいA/Bテストのためには対処が必要です。

### 無視できない外れ値がいる
99%の購入数が3回以下のところを、1,000回購入しているユーザーがいたとしたら、そのユーザーがサンプリングに含まれるか否かで結果が大きく変わります。特に極端な場合にはp値≒0.32あたりに山ができます。

### 実験単位と分析単位の不一致による分散の過小評価
これは例えば、「ユーザー単位でA/Bテストを振り分けているにも関わらず、指標がセッション単位の購入数」の場合に該当します。検定するさいに「セッション」を１サンプルとおくと、セッション同士はユーザーでつながっており、それぞれが独立にならず、分散が過小評価され、有意差が出やすくなります。このケースはp値の分布が少ない方向に偏ることで発見できます。

# A/B テスト実施中
想定通りにA/Bテストが動いていないことを早めに検知することは非常に重要です。中でも「実験割当割合のミス(Sample Ratio Mismatch)」は、A/Bテストの大前提である無作為抽出にエラーが起きていることの証拠なので、特に注意すべきです。

## 実験割当割合ミスの検知
<b>これが本記事で最も重要なテスト</b>です。
例えば、介入群とコントロール群で50%/50% のユーザー割当でのA/Bテストをしたとして、実際に介入群に割り当てられたユーザー数が、二項検定(帰無仮説は介入群の割当が50%)で有意差出た場合、何かがおかしい可能性が非常に高いです(第21章参照)。一標本の検定なので検出力はかなり高く、一見目で見てわからない差異を検出できるため、検定の実施を強く推奨します。
例えば、片方の条件にだけBotが流入してしまっているとか、割当制御にcookieを使ったが他のテストと干渉しているとか、原因は様々ですが、A/Bテストの大前提のランダム化に違反が起きている可能性があります。
この違反がおきたままA/Bテストを続けても得られる結果は少ないので、実験を緊急停止させ、エラーの原因を取り除くことを強く推奨します。

## 変わるはずがない指標が変わってないことを確認
例えば、購入完了画面のUI変更のテストでは、初回のトップページからの流入から検索行動、商品クリックまでは変化がおこらないはずです（あくまで論理的に帰結された仮定でしか無い点に注意）。
もし、そこで実験群間で変わるはずのない指標で変化があった場合

- 仮定が間違っている
- ランダムな割り当てができていない
- 前回のA/Bテストと独立に割り当てられてないなどの原因で、繰越効果などの影響が残ってる

などが考えられます。
仮定が間違っている場合は大きな学びを得るチャンスなので「なにを仮定しているか」（どこに因果関係があるとしているのか）を因果ダイアグラムなどの形で明示化することをおすすめします。
ランダムな割り当てができていない、は割当のランダム性をデータから直接示すことは困難なので、コードの確認をしたほうが良いです（実験割当割合ミスの検知にもひっかかることが多い）
繰越効果の方は、前回のA/Bテストとちゃんと独立な割当を設定することで回避できるはずです。

これの特別な場合が「なにも変化をさせない」A/Aテストです。

## 異常な数値変化が起きていないか
Botの混入やデータ基盤のデータ連携ミスなどの、実験以外の要因による変化の可能性があります。実験終了時の分析にも影響を与えるため、検知できておくことが重要です。
なかでも、実験群・ブラウザやスマホOSごとに画面遷移率などの変化の監視は、特にフロントエンドでの変更を伴うA/Bテストにおいて、思わぬブラウザ間の挙動の違いによるバグなどが起きていないことを確かめる（万が一、起きた場合は迅速に検知する）ために重要です。事前にテストしきるのはとてもつらいし難しいので、監視もしっかりしたほうが良いです。

## あってはならない変化がおきてないか
例えば、介入郡によりサーバーのCPU利用率が著しく高まり、サービス継続自体が困難になった場合はA/Bテストしている場合ではありません。すぐA/Bテスト停止です。
ここまで極端ではなくても、例えば介入群とコントロール群でDBを共有している場合（割とよくある）、介入群のクエリのせいでDB側でリクエストが詰まるなどコントロール群にも悪影響が及ぶことがあります。この場合、A/Bテストの停止までするかは判断が必要ですが、少なくても介入効果の推定にはなんらかしらの工夫が必要になり、正確性が損なわれます。

# A/B テストの結果の分析時
最後の最後で詰めをあやまると今までやってきたことが台無しになります。ここでは「こんなリスクも有るのか！」を知り、それを防ぎましょう。ここは機械的なテストが難しい箇所です。

## Intention-to-Treat的な話
途中で実験を離脱した人がいる場合、最後の分析でその離脱した人を含めないと、離脱によるバイアスの影響を受けてしまう。改めて書かれるとアタリマエのようだが、実際にはこの手のバイアス（生存バイアスなど）は見落とされやすいです。そこで、A/Bテストの結果を分析するさいには「その人が最初に割り当てられた実験条件」を使う（Intention-to-Treatともよばれる）といったテクニックがあります。（第３章参照）

## 外的妥当性の観点
外的妥当性とは、今回の結果がどこまで一般化できるか、といった視点からの妥当性です。（第３章参照）
この妥当性が選ばれるケースはいくつも考えられます。例えば、ノベルティ効果（新規性効果とも。新しいとそれだけで好まれてしまい、A/Bテスト期間中に得られた結果が実は持続しないケース）でないことや、季節性の影響でないことを確認するなどといった方法があります。かなり長くなる話なので、興味のある方はカバ本の第３章や第23章を参考にしてほしいです。

## シンプソンのパラドックス
介入群への割当をA/Bテスト途中で変えた場合、例えば実験開始初期は介入の副作用をおそれて僅かな割合でA/Bテストを開始するとか、”割当変更前でも後でも介入群が勝っていたのに、全期間をまとめて集計すると介入群が負けた”、といった現象が数学的には起こりえます。しかし、我々の直感とこの結論が反するように感じるためパラドックスとよばれています。これは、全期間をまとめたほうが正しくなく、直感と反するのはただの誤謬です。詳しくは Causality (Pearl 2009)をご参照ください（カバ本よりも読解難易度は遥かに高いですが、こちらも読む価値あります。というか素晴らしい本です。和訳もあります） 

# 機械学習モデル関連
ここではデータからアルゴリズムを動的に更新しつづけるシステムのアルゴリズム部分とその実装を機械学習モデルと称しています。この部分のテストは、観点色々ありますし、抑えるべきポイントも多岐にわたるので、ここでは「最低限ここ見ておく」を書きます。この辺りに興味身ある方は少し古いですが、　[What’s your ML test score? A rubric for ML production systems](https://research.google/pubs/pub45742/) なんて良いかもしれません。これでは特徴量とデータ、開発、インフラ、モニタリングの4項目を用意し、各項目ごとに7つのチェックポイントを設けてます。この手の話題で他にも良い提案がいっぱい出てると思うので、良いものあったら教えてほしいです。
「最低限ここだけ」のために、最終出口だけ抑えます。「機械学習モデルの出力の分布」だけみる方法を考えます

## 機械学習モデルの出力の分布が期待通りに偏っているか
$y=f(\textbf{x})$ のy を機械学習モデルの出力、xが特徴量ベクトル、fを機械学習モデルとしたとします。オフラインでの分析時に、xの一部の$x_1 =1$ のとき、 $x_1 =0$のとき、yの取る値が高くなる傾向にあったとします（ある程度単純なモデルならそこそこ見つけられるはず）。そのさいに機械学習モデルのデプロイ後に$x_1 =0$のときと、$x_1=1$のときとで実際のyの分布を見て、それが仮説通りになっているか確認します。
もし、そうなっていない場合

- どこかにバグがある（学習が収束しなかったりとか）
- オフラインで分析したときからデータが無視できないほど性質が変わっている

などが考えられ、機械学習モデルの品質向上のために原因の調査をしたほうが良いです
また、解釈しやすい偏りが見つからなかった場合、出力の分布を直接確認する方法もあります。


# まとめ
最低限、<b>実験割当割合ミスの検知は絶対にしたほうが良い</b>です。その他にも検出力の検定やA/Aテストのシミュレーションなど実施がさほど難しくなさそうなやつは、まだやっていない場合はすぐにでも取り入れたほうが良いです（そこで何も起きなければラッキー。なにかあったら発見できてラッキー）
あと、<b>カバ本は超おすすめです</b>。この記事の100倍くらい詳しいですし(この記事では扱ってない実験群間での情報リークやp-hackingなどまだまだ観点あります)、扱ってるトピックがA/Bテストのテストだけでなく、非常に広範にわたるのでA/Bテストに関わる人は一読を非常に強くおすすめします（確か３回目）。