A/B が組めない時の
効果測定
「全顧客に新機能をリリースした後で、効果を測ってほしいと言われた」「TVCM を打った地域と打たなかった地域があるが、CM の効果はどう出すのか」「キャンペーン応募者は、応募していなければどうなっていたのか」。これらの問いに答えるのが 因果推論 です。A/B テストを仕込めなかった施策でも、観察データから「もし施策がなかったらどうなっていたか」を推定し、純粋な効果の数字を取り出す道具です。
たとえば BtoB SaaS で新機能を全社一斉公開した後、機能を使った顧客と使わなかった顧客の解約率を単純比較すると、もともと熱量の高い顧客が機能を触りやすいという自己選択バイアスで効果を過大評価してしまいます。「機能利用群の解約率が低い」のは機能のおかげではなく、もとから解約しにくい顧客が機能を使っただけかもしれません。こうした観察データから施策の純粋な効果を取り出すやり方が 因果推論 です。
A/B テストが組めない時の効果測定は、比較相手をデータからどう作るかで決まります。実務で使われるのは主に 2 パターン:差分の差分法(介入前後 × 介入有無の 2×2 で取る)と 傾向スコアマッチング(似た背景の対象同士を組み合わせる)。どちらも「もし介入が起きなかった場合の値(反実仮想)」をどう作るかの工夫であり、並行トレンドや共通サポートのような仮定の妥当性チェックがセットになります。
- 因果推論:無作為割付ができない観察データから、施策の純粋な効果を統計的に推定するやり方。
- 反実仮想(カウンターファクト):もし介入が起きなかった場合の、推定される結果値。
- 差分の差分法:介入前後 × 介入有無の 2×2 で、両群のトレンドの差から介入効果を取り出す方法。
- 傾向スコア:観察データから「この対象が介入を受ける確率」を、共変量(業種・契約年数・利用頻度など)で条件付けて推定したもの。
- 並行トレンド仮定:差分の差分法の前提。介入がなかった場合、両群の時系列が平行に動いていただろうという仮定。
- 共通サポート:介入群と対照群の傾向スコア分布に十分な重なりがあること。重なりがないと数字は出ても解釈には使えない。
01.まず結論:A/B できない時の効果推定は『どこを比較対象にするか』が勝負
因果推論の各手法は、結局のところ「介入を受けなかったらどうなっていたか」という 反実仮想(カウンターファクト)(もし介入が起きなかった場合の、推定される結果値)をどう作るかの違いです。手法ごとに、どこから比較相手を持ってくるかが変わります。最初にやるのは「自分の手元のデータがどの形(時系列か / 横断か)か」を確認することです。
| 手法 | 反実仮想の作り方 | 向く場面 |
|---|---|---|
| 差分の差分 | 対照群の介入前後の差を、介入群に重ねる | 介入前後の時系列データがある。全社施策後の効果測定、一部地域施策の評価など |
| 傾向スコアマッチング | 介入を受ける確率が似た対照を 1 対 1 で紐付ける | 横断データで顧客属性が豊富。1 時点だけの介入評価 |
02.因果推論が必要になる場面|全員施策・自己選択・観察データ
因果推論を持ち出すのは、無作為割付が物理的・倫理的・運用的に難しい場面です。実務でぶつかる典型は次の 3 つに整理できます。
| 状況 | 起きていること | 単純比較の落とし穴 |
|---|---|---|
| 全員に施策をリリース済み | 新機能・新UI を全顧客にロールアウト後、効果を後付けで測りたい | 対照群が存在しない。介入前と介入後の単純比較は季節要因と効果が混ざる |
| 自己選択(オプトイン) | ユーザーが自分で機能をオンにする/キャンペーンに応募する | もともと熱量の高い人が選ぶので、効果ではなく素性の差を見ている |
| 観察データのみ | ログから過去の介入と結果を後から突き合わせる | 観測されていない交絡変数(業種・規模・担当者の熱量)が残り、相関 ≠ 因果 |
| 地域・部署単位の段階導入 | 東京から大阪・名古屋へ順に展開 | 順番に意味がある(先行地域はもともと成績が良い等)と、対照として使えない |
BtoB SaaS で機能利用群の解約率が 5%、非利用群が 12% だったとして、差の 7 ポイントを「機能の効果」と読むのは早計です。機能を使う顧客は、もともと製品にコミットしていて解約しにくい層が多い。共変量(業種・契約年数・MAU・担当者ロール)で条件をそろえないと、自己選択バイアスを効果と取り違えます。
03.差分の差分|全員に施策が出た後でも効果を測れる
差分の差分(Difference-in-Differences)は、介入を受けた群と受けなかった群を、介入前後で並べて 2×2 の表で差を取る方法です。介入前後に共通する季節・市況のトレンドを対照群から差し引くことで、純粋な施策効果だけを残します。
図:差分の差分(DID)の考え方|効果 = 介入群実測 − 反実仮想
介入時点(縦線)の前後で、介入群と対照群の動きを並べる。介入がなかったら介入群はどう動いていたか(点線=反実仮想)を対照群の傾きで延長し、実測値との差(矢印)を効果として読む。
反実仮想は対照群のトレンドを介入群に重ねたもの。両群が介入前から平行に動いていた(並行トレンド仮定)ことが、この延長線の妥当性の根拠になる。
| 手順 | やること | ツール |
|---|---|---|
| 01. 介入群と対照群を決める | 顧客セグメント / 地域 / 部署などで、施策を受けた群と受けなかった群を分ける | BigQuery / pandas で抽出 |
| 02. 介入前後の期間を切り出す | 介入前 3〜6 ヶ月と、介入後同じ長さの期間を切り出す | SQL / pandas |
| 03. 2×2 表に平均値を入れる | 介入×時期で 4 セル(介入群×前後 / 対照群×前後)に、平均値(CV 数・滞在時間など)を入れる | pivot_table |
| 04. 差の差を計算 = 介入の効果 | (介入群の差)−(対照群の差)が介入の効果。回帰式 <code>y ~ treat * post</code> の交互作用項の係数と一致 | 電卓 / statsmodels |
例:BtoB SaaS の新機能を 7 月に一部顧客にリリース。月次セッション数の平均を 4 マスで集計。
・介入群:介入前 100、介入後 130(差 +30)
・対照群:介入前 80、介入後 95(差 +15)
単純比較では介入群が +30 伸びていますが、対照群でも +15 伸びているため、これは季節要因や全社的な伸び。差の差で +30 − +15 = +15 が、新機能の純粋な効果になります。
# 実際の業務でやるなら、まずこの形(顧客 ID × 月次 × 介入フラグ × 結果値)でデータを準備する。
# 集計が終わっていれば、差の差は statsmodels で 1 行。
import statsmodels.formula.api as smf
# df の列:y(結果値), treat(介入群=1/対照群=0), post(介入後=1/前=0)
model = smf.ols("y ~ treat * post", data=df).fit()
print(model.summary())
# treat:post の係数が「差の差」(介入の純粋な効果)04.傾向スコアマッチング|似た者同士で比較する
傾向スコアマッチングは、介入群の各対象に「業種・契約年数・利用頻度などが似ている対照群」を 1 対 1 でペアにして、ペアごとの結果差を集計する方法です。介入前後のパネルがなくても、横断データだけで効果を測れるのが強みです。
| 手順 | やること | ツール |
|---|---|---|
| 01. 共変量を 4〜6 個ピックアップ | 業種・契約年数・利用頻度・プランなど、介入の有無に影響しそうな変数を 4〜6 個選ぶ | BigQuery / pandas |
| 02. 介入を受ける確率を予測 | ロジスティック回帰で「介入を受ける確率」を予測。0〜1 の値が各対象に付く | scikit-learn LogisticRegression |
| 03. 最近傍マッチングで 1 対 1 のペアを作る | 介入群の各対象に、傾向スコアが最も近い対照を 1 件割り当てる(離れすぎは除外) | NearestNeighbors |
| 04. ペアごとの結果差を平均(= 介入効果) | マッチしたペアごとに結果値の差を出し、その平均を取る | pandas の groupby 差分 |
# 実際の業務でやるなら、まずこの形(顧客 ID × 共変量 × 介入フラグ × 結果値)でデータを 1 枚に揃える。
# 揃ったら scikit-learn だけでマッチングできる。
import pandas as pd
from sklearn.linear_model import LogisticRegression
from sklearn.neighbors import NearestNeighbors
X = df[["industry", "mau", "contract_years", "plan_tier"]]
# 1. 傾向スコアの推定
df["ps"] = LogisticRegression(max_iter=1000).fit(X, df["treat"]).predict_proba(X)[:, 1]
# 2. 1:1 最近傍マッチング(caliper=0.05 で離れ過ぎは除外)
treated = df[df["treat"] == 1]
control = df[df["treat"] == 0]
nn = NearestNeighbors(n_neighbors=1).fit(control[["ps"]].values)
dist, idx = nn.kneighbors(treated[["ps"]].values)
keep = dist[:, 0] < 0.05
matched_treated = treated.iloc[keep]
matched_control = control.iloc[idx[keep, 0]]
# 3. 結果差の平均(介入の効果)
effect = matched_treated["y"].mean() - matched_control["y"].mean()
print(f"効果: {effect:.3f}")マッチング後、共変量ごとに介入群と対照群の平均差が小さくなっているかを目視確認します。標準化平均差(SMD)が 0.1 未満(10%)に収まっていれば概ね揃った判定です。揃わない変数があれば、共変量を増やすか、最近傍距離の閾値(caliper)を狭めて再マッチングします。
05.仮定チェックと落とし穴|並行トレンド・共通サポート・隠れ交絡
差分の差分と傾向スコアマッチングは、それぞれ「成立するための前提」が違います。仮定が崩れていると、数字は出ても解釈には使えません。推定値を施策評価に出す前に、最低限この 3 つだけは手を動かして確認します。
| チェック項目 | やること | OK の目安 |
|---|---|---|
| 並行トレンド | 介入前 3〜6 ヶ月で介入群と対照群を重ねてプロット(目視) | 両群の折れ線が同じペースで動いている |
| 共通サポート | 傾向スコアの分布が重なっているか、ヒストグラム重ね描きで確認 | 両群の分布が広い範囲で重なっている |
| 隠れ交絡 | 共変量を入れ替えた複数モデルで効果量の符号と大きさが安定するか確認 | 符号が変わらず、効果量が大きく動かない |
図:共通サポート(Common Support)|介入群と対照群の傾向スコア分布の重なり
オレンジが介入群、青が対照群。左は重なりが十分でマッチング可能。右は片側に寄って重なりが薄く、外挿に依存するため推定が不安定になる。
右側の状態では「対照群側に介入群に似た対象がほとんどいない」ため、マッチングしても無理な相手を引き当ててしまい、推定値の信頼性が落ちる。マッチング前に必ず分布の重なりを確認する。
並行トレンドは介入後の動きでは確認できません。最初にやるのは、介入前の 3〜6 ヶ月で両群を重ねてプロットし、目視で平行か確認することです。補助として「介入時点より前にダミーの介入日を置いて差分の差分を回し、効果がゼロ近傍に収まるか」を見るプラセボテストも有効です。
共通サポートはヒストグラムを重ね描きすれば一目で判断できます。重なりが薄ければマッチ可能な範囲に対象を絞る、対照プールを別事業部・別期間から広げる、といった手前の設計に戻る判断が必要です。
並行トレンド・共通サポート・隠れ交絡の 3 つを目視と再推定で確認し、いずれも OK なら、その推定値は施策評価の根拠としてそのまま使えます。逆に 1 つでも崩れていたら、数字を出すのを止めて、対照プールの取り直し・共変量の追加・手法の切り替えに戻る判断が必要です。
観察データの最大の脅威は、観測していない交絡変数(隠れ交絡)です。E-value は「観測共変量で説明できない隠れた交絡が、結果を逆転させるためにはどれだけ強い必要があるか」を数値で表す指標で、目安は 1.5 程度なら脆弱、3 を超えれば比較的頑健です。共変量を入れ替えた複数モデルで効果量が安定するかも合わせて確認します。
因果推論は専用 SaaS が少なく、Python / R ライブラリでの自前実装が中心です。代表的な選択肢は次のとおり。
- Python(汎用・大手 OSS):DoWhy(Microsoft、因果グラフでモデル化)/ CausalML(Uber、機械学習ベース)/ EconML(Microsoft、計量経済学手法)/ statsmodels(差分の差分や OLS、王道)。最初の入り口は statsmodels で OK。
- Python(時系列の介入分析):CausalImpact(Google、ベイズ構造時系列で介入効果を推定)。コアアップデート前後の SEO 流入や、キャンペーン期間の売上を測るのに向く。
- R(計量経済学の本流):MatchIt(傾向スコアマッチング)/ twang(IPW)/ rdrobust(回帰不連続)/ fixest(パネル固定効果)。論文水準の実装。
- SaaS / クラウド:Databricks(CausalML 統合)/ AWS SageMaker(一部因果モジュール)/ Hex・Deepnote(ノートブック型分析)。専用 SaaS は少なく、Python / R を回せる環境を整えるのが主流。
- BI ダッシュボード化:上記のいずれかで効果量を出した後、Looker Studio / Tableau で月次レポートに組み込むのが現実的。
選び方の指針:(a) まず差分の差分なら statsmodels.formula.api の ols("y ~ treat * post") で 1 行から始める、(b) 傾向スコアマッチングなら scikit-learn + DoWhy か、本格的にやるなら R の MatchIt、(c) 介入分析は CausalImpact。SaaS を待たずに Python / R で動かせます。
06.よくある質問(FAQ)
差分の差分と傾向スコアマッチング、どちらから試せばよいですか?
手元のデータで決めるのが早道です。介入前後の時系列データ(月次の利用回数、CV 数など)があり、介入を受けなかった対象(別事業部・別地域・別セグメント)を比較対照として使えるなら、差分の差分から試します。横断データしかなく、顧客属性(業種・契約年数・MAU・プランなど)が豊富に取れるなら、傾向スコアマッチングが直感的です。両方走らせて、効果量の符号と大きさが揃うかを確認すると頑健性が増します。揃わない場合は、どちらかの仮定が崩れているサインです。
並行トレンドの仮定はどう確認しますか?
まずは介入前の 3〜6 ヶ月で両群の時系列を重ねてプロットし、視覚的に平行に動いているかを確認します。補助として、実際の介入時点より前のダミー時点を「介入時点」として差分の差分を回し、効果がゼロ近傍に収まるかを見る プラセボテスト(事前トレンド検定)が定番です。介入前の係数が有意になるなら、両群はもともと別の動きをしており、並行トレンドの仮定が崩れているサインです。共変量で条件付けた差分の差分や、対象を絞った再分析を検討します。
共通サポートが弱い時はどうすればよいですか?
最初の手当は 傾向スコアの重なる範囲(共通サポート)に対象を絞る ことです。たとえば傾向スコアが 0.05〜0.95 に入る対象だけで推定し、母集団の解釈を「両群に類似対象が存在する範囲」と限定します。次に 対照プールを広げる。社内データだけで対照が薄いなら、別事業部・別期間からの追加を検討します。それでも重なりが薄いなら、傾向スコア系の手法ではなく 差分の差分など別の識別戦略に切り替えるのが筋です。
因果推論と A/B テストはどちらが信頼できますか?
無作為割付の A/B テストは、未観測の交絡まで含めて期待値ベースで揃うので、追加の前提がほとんど要らないという点で最も信頼できます。因果推論は「A/B が組めない場面で次に良い手段」と位置づけるのが現実的で、並行トレンドや背景の揃え方のような仮定が成り立つ前提で初めて A/B に近い解釈が可能になります。施策の意思決定では、まず A/B が組めないかを真剣に検討し、組めない時に因果推論で支える、という順番がおすすめです。
観測されていない交絡が残っていそうな時、どうすれば良いですか?
観察データで完全に交絡を消すのは難しいので、感度分析で「観測共変量で説明できない隠れた交絡が、結果を逆転させるためにはどれだけ強い必要があるか」を定量化します。E-value が代表的な指標で、1.5 程度なら脆弱、3 を超えれば比較的頑健、というのが大まかな目安です。あわせて、共変量を入れ替えた複数モデルで効果量の符号・大きさが安定するかも確認すると、隠れ交絡への耐性を読みやすくなります。
07.まとめ
A/B テストが組めない時の効果測定は、反実仮想(介入がなかったら結果はどう動いていたか)をどう作るかの設計です。介入前後のパネルがあれば差分の差分で対照群のトレンドから作り、横断データで共変量が豊富なら傾向スコアマッチングで似た背景の対象から作る。並行トレンドと共通サポートを目視確認し、隠れ交絡の感度分析を 1 度通せば、施策評価に使える数字になります。
最初にやるのは A/B テストが組めないかを真剣に検討することです。組めない時に、差分の差分と傾向スコアマッチングを並走させ、両手法で効果量の符号と大きさが揃うかを確認するのが、実務での向き合い方です。揃わないなら、どこかの仮定が崩れているサインです。
SEO 統計入門
コアアップデートの介入分析(CausalImpact)など SEO データの統計的読み方を整理しています。
A/B テスト設計の基礎
無作為割付できる時の検定の使い分けを整理しています。
予測モデル評価の指標
F1・ROC-AUC・MAE・Pearson などの評価指標を整理しています。
データ分析アルゴリズム全体図
類似度・一致度・予測モデル評価の3カテゴリで指標を整理した総合解説です。
観察データから施策効果を推定する設計をご相談ください
A/B テストが組めない場面での効果測定、差分の差分や傾向スコアマッチングを使った観察データ分析の伴走支援を行っています。お気軽にお問い合わせください。

