AI × データ分析基礎知識集 / 因果推論

A/B テストできない施策の効果測定|差分の差分と傾向スコアで観察データから効果を取り出す


「新機能を全顧客にリリースした後、効果を測ってほしい」と言われた——という場面に多くの担当者が直面します。本記事では、A/B テストが組めない時に観察データから効果を取り出す実務手順を、差分の差分と傾向スコアマッチングの 2 パターンで整理します。学術的な解説ではなく、実際に集計・コードを動かすところまで降りた手順としてまとめています。

公開2026.05.15
最終更新2026.05.15
読了 15 分 / 約6,500字
この記事をシェアポスト
AI × データ分析『A/B が組めなかった施策は、本当に効いたのか?』を数字で答える

A/B が組めない時の
効果測定

「全顧客に新機能をリリースした後で、効果を測ってほしいと言われた」「TVCM を打った地域と打たなかった地域があるが、CM の効果はどう出すのか」「キャンペーン応募者は、応募していなければどうなっていたのか」。これらの問いに答えるのが 因果推論 です。A/B テストを仕込めなかった施策でも、観察データから「もし施策がなかったらどうなっていたか」を推定し、純粋な効果の数字を取り出す道具です。

たとえば BtoB SaaS で新機能を全社一斉公開した後、機能を使った顧客と使わなかった顧客の解約率を単純比較すると、もともと熱量の高い顧客が機能を触りやすいという自己選択バイアスで効果を過大評価してしまいます。「機能利用群の解約率が低い」のは機能のおかげではなく、もとから解約しにくい顧客が機能を使っただけかもしれません。こうした観察データから施策の純粋な効果を取り出すやり方が 因果推論 です。

C
結論
A/B テストできない時は『どこを比較対象にするか』を設計してから推定する

A/B テストが組めない時の効果測定は、比較相手をデータからどう作るかで決まります。実務で使われるのは主に 2 パターン:差分の差分法(介入前後 × 介入有無の 2×2 で取る)と 傾向スコアマッチング(似た背景の対象同士を組み合わせる)。どちらも「もし介入が起きなかった場合の値(反実仮想)」をどう作るかの工夫であり、並行トレンドや共通サポートのような仮定の妥当性チェックがセットになります。

i
用語の整理
本記事で押さえる主要用語
  • 因果推論:無作為割付ができない観察データから、施策の純粋な効果を統計的に推定するやり方。
  • 反実仮想(カウンターファクト):もし介入が起きなかった場合の、推定される結果値。
  • 差分の差分法:介入前後 × 介入有無の 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
i
数値例で見る差の差
2×2 表の差し引きで効果が見える

例: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}")
!
マッチ後の確認
背景が本当に揃ったかを 1 度確認する

マッチング後、共変量ごとに介入群と対照群の平均差が小さくなっているかを目視確認します。標準化平均差(SMD)が 0.1 未満(10%)に収まっていれば概ね揃った判定です。揃わない変数があれば、共変量を増やすか、最近傍距離の閾値(caliper)を狭めて再マッチングします。

05.仮定チェックと落とし穴|並行トレンド・共通サポート・隠れ交絡

差分の差分と傾向スコアマッチングは、それぞれ「成立するための前提」が違います。仮定が崩れていると、数字は出ても解釈には使えません。推定値を施策評価に出す前に、最低限この 3 つだけは手を動かして確認します。

チェック項目やることOK の目安
並行トレンド介入前 3〜6 ヶ月で介入群と対照群を重ねてプロット(目視)両群の折れ線が同じペースで動いている
共通サポート傾向スコアの分布が重なっているか、ヒストグラム重ね描きで確認両群の分布が広い範囲で重なっている
隠れ交絡共変量を入れ替えた複数モデルで効果量の符号と大きさが安定するか確認符号が変わらず、効果量が大きく動かない

図:共通サポート(Common Support)|介入群と対照群の傾向スコア分布の重なり

オレンジが介入群、青が対照群。左は重なりが十分でマッチング可能。右は片側に寄って重なりが薄く、外挿に依存するため推定が不安定になる。

良い例:重なり十分01傾向スコア悪い例:重なり弱い01傾向スコア介入群対照群

右側の状態では「対照群側に介入群に似た対象がほとんどいない」ため、マッチングしても無理な相手を引き当ててしまい、推定値の信頼性が落ちる。マッチング前に必ず分布の重なりを確認する。

並行トレンドは介入後の動きでは確認できません。最初にやるのは、介入前の 3〜6 ヶ月で両群を重ねてプロットし、目視で平行か確認することです。補助として「介入時点より前にダミーの介入日を置いて差分の差分を回し、効果がゼロ近傍に収まるか」を見るプラセボテストも有効です。

共通サポートはヒストグラムを重ね描きすれば一目で判断できます。重なりが薄ければマッチ可能な範囲に対象を絞る、対照プールを別事業部・別期間から広げる、といった手前の設計に戻る判断が必要です。

C
チェックの結論
上記 3 つが OK なら推定値を施策評価に使える

並行トレンド・共通サポート・隠れ交絡の 3 つを目視と再推定で確認し、いずれも OK なら、その推定値は施策評価の根拠としてそのまま使えます。逆に 1 つでも崩れていたら、数字を出すのを止めて、対照プールの取り直し・共変量の追加・手法の切り替えに戻る判断が必要です。

!
隠れ交絡(観測していない交絡変数)
観察データで完全に交絡を消すのは難しい。感度分析で頑健性を測る

観察データの最大の脅威は、観測していない交絡変数(隠れ交絡)です。E-value は「観測共変量で説明できない隠れた交絡が、結果を逆転させるためにはどれだけ強い必要があるか」を数値で表す指標で、目安は 1.5 程度なら脆弱、3 を超えれば比較的頑健です。共変量を入れ替えた複数モデルで効果量が安定するかも合わせて確認します。

i
自前 vs ツール
因果推論はどう実装するか

因果推論は専用 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 テストが組めないかを真剣に検討することです。組めない時に、差分の差分と傾向スコアマッチングを並走させ、両手法で効果量の符号と大きさが揃うかを確認するのが、実務での向き合い方です。揃わないなら、どこかの仮定が崩れているサインです。

お問い合わせ

観察データから施策効果を推定する設計をご相談ください

A/B テストが組めない場面での効果測定、差分の差分や傾向スコアマッチングを使った観察データ分析の伴走支援を行っています。お気軽にお問い合わせください。

お問い合わせはこちら

データ分析・アルゴリズム 基礎知識集

一覧に戻る →
07

モデル構築の自動化

この記事をシェア
澤田 翔太(Shota Sawada)
この記事を書いた人

澤田 翔太

株式会社クリプタル 代表取締役

1988年生まれ、慶應義塾大学卒。創業メンバーとして関わった株式会社セールスサポートを株式会社ネオマーケティング(東証STD 4196)に売却。株式会社クリプタルでも複数の事業立ち上げと売却を経験し、2022年9月には婚活・恋愛メディア「シッテク」「婚活会議」を株式会社ベビーカレンダー(東証GRT 7363)へ売却。現在はAI業務支援事業、TANTOU事業、グロースハック支援事業、メディア事業、SEOコンサルティング事業を手がける。