A/Bテストをやっていると、最終的にこんな会話になりがちです。
- 「で、差はあったの?」
- 「p値は?」
- 「0.05切ってるなら、B案で進めよう」
この流れ、かなり自然です。
実際、意思決定のスピードも必要なので、現場ではこういう短いやり取りになりやすいと思います。
ただ、自分もA/Bテストや分析まわりを見ていて思うのは、
t検定は便利な一方で、結果の読み方を間違えると普通に危ない ということです。
この記事では、A/Bテストでよく使われる t検定について、
- p値をどう読むべきか
- どの t検定を使えばいいのか
- 施策判断の前に何を確認すべきか
- なぜサンプルサイズ設計が大事なのか
を、実務寄りに整理してみます。
t検定は「差があるか」を見る道具。でも、それだけでは足りない
t検定は、ざっくり言うと
2つの平均の差が、偶然のブレでは説明しにくいかを調べる方法 です。
A/Bテストだと、たとえば次のような場面で使われます。
- AパターンとBパターンで平均購入単価に差があるか
- 施策前後で平均滞在時間に差があるか
- 過去の平均値と今回の平均値が違うか
ここでよくあるのが、
「p < 0.05 ならOK」という1行理解で止まってしまうこと です。
もちろん、それ自体は統計的な判断としてはひとつの基準です。
でも、実務ではそれだけだと判断材料としてかなり足りません。
なぜなら、施策判断で本当に知りたいのは
差があるか ではなく、
その差を根拠に意思決定してよいか だからです。
p値は「この施策が当たりである確率」ではない
まず一番大事なところです。
p値はしばしば誤解されます。
たとえば p = 0.03 という結果が出たときに、
- この施策が正しい確率が97%
- B案が勝っている確率が97%
- 次回も同じ結果になる可能性が高い
のように読んでしまうケースがあります。
でも、p値はそういう意味ではありません。
p値は、
「本当は差がないと仮定したときに、今回観測された差以上のものが偶然に出る確率」
です。
つまり、p値が小さいのは
差がないと考えるには少し無理がある
という話であって、
この施策は成功だ と直接言っているわけではありません。
このズレがあると、A/Bテストの結果をそのまま事業判断に接続したときに事故ります。
実務でよくある3つのズレ
1. 有意差がある = 重要な差がある、になっている
統計的に有意でも、差の大きさが小さければ、
実務上は「誤差みたいなもの」です。
たとえば平均購入単価が
- A: 5,000円
- B: 5,015円
で、十分大きなサンプルを集めた結果 p < 0.05 になったとしても、
その15円差が本当に意味のある改善かは別問題です。
実務では、統計的有意差 と ビジネス上の意味 を分けて考えないといけません。
2. 非有意 = 効果なし、になっている
これもかなり多いです。
p >= 0.05 だったときに、
「差がなかった」「この施策はダメだった」と即断してしまうケースです。
でも実際には、
- サンプルサイズが不足していた
- ばらつきが大きすぎた
- 効果はあるが検出できなかった
だけかもしれません。
つまり、差がないことが示された のではなく、
差を確認できるだけの条件が揃っていなかった 可能性があります。
3. とりあえず t検定、になっている
A/Bテストの文脈だと、検定そのものより前に
どの比較をしているのか を整理しないといけません。
同じ t検定でも、見るべき状況は違います。
- 1標本t検定
- 2標本t検定
- 対応のあるt検定
これを雑に選ぶと、そもそも前提がズレます。
t検定は最低でも3パターンある
1標本t検定
「今回の平均」が「ある基準値」と違うかを見る方法です。
たとえば、
- 今月の平均購入単価は、過去平均 5,000円 と違うか
- 今回のキャンペーン後の平均スコアは、目標値 60 を上回るか
のようなケースです。
2標本t検定
A/Bテストで一番よく出てくるのがこれです。
独立した2グループの平均を比較 します。
たとえば、
- LPデザインAとBで平均滞在時間に差があるか
- メルマガ件名A/Bで平均購入金額に差があるか
みたいなケースですね。
ただしここでも注意点があって、
分散が同じとみなせるかどうかで扱いが変わります。
実務では、迷ったら Welchのt検定 を使うことが多いです。
分散が等しいことを強く仮定しなくてよいためです。
対応のあるt検定
同じ対象の前後比較に使います。
たとえば、
- 同一ユーザーの施策前後の利用時間
- 同一社員の研修前後テスト
- 同じ商品の改善前後の評価
のように、データがペアになっているケースです。
これを独立2群として処理すると、情報の持ち方を間違えます。
Pythonでやると、違いが見えやすい
Qiitaなので、最小限のコードも置いておきます。
2標本t検定(Welch)
import numpy as np
from scipy import stats
a = np.array([5100, 4800, 5300, 5000, 4950, 5050, 4900])
b = np.array([5200, 5150, 5400, 5100, 5000, 5250, 5300])
t_stat, p_value = stats.ttest_ind(a, b, equal_var=False)
print("t値:", t_stat)
print("p値:", p_value)
ここで equal_var=False にしているのがポイントです。
独立2群で、分散が同じとは限らない前提なら、まずはこちらを意識したほうが安全です。
対応のあるt検定
before = np.array([62, 58, 71, 69, 65, 60, 66])
after = np.array([65, 61, 73, 72, 67, 63, 68])
t_stat, p_value = stats.ttest_rel(before, after)
print("t値:", t_stat)
print("p値:", p_value)
同じ人・同じ対象の前後比較なら ttest_rel です。
この違いは、現場だと地味に大事です。
A/Bテストで p値の前に見るべきこと
自分の中では、A/Bテストの結果を見るときに、最低でも次の順番で確認するようにしています。
1. 何を比較しているのか
- 独立した2群か
- 同じ対象の前後か
- 基準値との比較か
2. 指標は平均で見るのが妥当か
平均が意味を持つ指標かどうかは意外と重要です。
極端な外れ値の影響を強く受ける指標だと、平均比較だけでは危ういです。
3. サンプルサイズは十分か
ここを後回しにすると、
「有意差が出なかった理由」が施策の弱さなのか、単なる観測不足なのかが分からなくなります。
4. 差の大きさは実務的に意味があるか
p値だけでなく、平均差や効果量も見たいところです。
5. 結果を都合よく切り出していないか
途中で何度も集計して、
有意になった瞬間に止める、というのはかなり危ないです。
いわゆる p-hacking 的な動きに近くなります。
サンプルサイズ設計をやらないA/Bテストは、かなり不利
実務で一番軽視されがちなのに、一番効くのがここかもしれません。
A/Bテストを始める前に、
- どれくらいの差を検出したいのか
- どれくらいの確率で見つけたいのか
- 何人くらい必要なのか
を決めておくことです。
これをやらないと、テスト後に
- 有意差が出なかった
- でも本当に差がなかったのかは分からない
- じゃあもう少しだけ延長する?
- いつ終わるの?
みたいな、微妙な運用になりやすいです。
必要サンプルサイズは Python でも計算できる
効果量ベースのシンプルな例なら、statsmodels で計算できます。
from statsmodels.stats.power import TTestIndPower
analysis = TTestIndPower()
required_n = analysis.solve_power(
effect_size=0.3,
alpha=0.05,
power=0.8,
ratio=1.0
)
print(required_n)
もちろん実務では、
「効果量0.3って何?」
という話が次に来ます。
ここで大事なのは、統計だけで決めるのではなく、
事業として意味のある改善幅 から逆算することです。
たとえば、
- CVRをどれだけ改善したいのか
- 平均購入単価が何円上がれば意味があるのか
- その改善が開発コストを回収できるのか
という問いとセットで考えないと、
サンプルサイズ設計だけしても空回りします。
「分析した」ではなく「判断できる」がゴール
A/Bテストや t検定の話をしていると、
どうしても統計手法そのものに意識が向きがちです。
でも実務で大事なのは、
正しい検定を実行したか より、
その結果を使って無理のない判断ができるか だと思っています。
たとえば、こんな状態ならかなり危ないです。
- p値だけ見ている
- 検定の種類をなんとなく選んでいる
- サンプルサイズ設計なしで始めている
- 有意差が出るまで見続けている
- 差の大きさより「有意かどうか」だけを見ている
逆に、このあたりを押さえるだけで、
A/Bテストの解像度はかなり上がります。
まとめ
A/Bテストで t検定を使うときは、少なくとも次の4つを意識したいです。
- p値は万能な判断指標ではない
- t検定は状況に応じて使い分ける必要がある
- 有意差と実務上の意味は別物
- サンプルサイズ設計を先にやると判断が安定する
t検定自体は入門的な手法ですが、
実務に乗せた瞬間に「何をどう比べて、どう解釈するか」が急に難しくなります。
だからこそ、数式だけで覚えるより、
Pythonで動かしながら、ケースごとに体感で理解する のがかなり相性いいなと思っています。
おまけ:このあたりをまとめて学べる形にしました
この記事で触れたような内容、つまり
- p値の見方
- サンプリングの考え方
- 3つのt検定の使い分け
- サンプルサイズ設計
- 実務A/Bテストでのレポート作成
あたりを、Pythonベースで手を動かしながら学べるように、講座として整理しました。
Qiitaの記事では概念整理までに留めましたが、
実際に numpy, scipy, statsmodels を使って
「どう実装して、どう判断につなげるか」まで通したい人には合うと思います。
半額リンクはこちらです(有効期限30日)
https://www.udemy.com/course/pythonab/?couponCode=277B0E7A6B67F5304A7F