論文一覧に戻る 📚 用語集トップ 🗺 概念マップ
📚 用語解説
📚 用語解説
平行トレンド仮定
Parallel Trends Assumption
因果推論
別称: 共通トレンド / parallel trends

🔖 キーワード索引

この用語と一緒に検索・参照されやすいタグ。 関連ページに飛ぶときの手がかりにも使えます。

#因果推論#DiD#平行トレンド#検証#観察データ

🔖 キーワード索引 — 完全強化版

「平行トレンド仮定」を理解するうえで必要なキーワードを 10 件以上提示します。 各チップから対応セクションへ移動できます。

30 秒結論 文脈 直感 数式 記号読み解き 実値計算 Python 実装 落とし穴 関連手法 関連用語 グループ教材 概念マップ

💡 30秒で分かる結論

🍰 まずはやさしく

データの動きが同じ方向に向かうという約束です。

ある対策の効果を正しく測るために使います。

スマホの利用時間をクラスで比べる時に役立ちます。

この章では結論を短くまとめて解説します。

平行トレンド仮定は、 差分の差(DiD)法における核心仮定。 「介入が無ければ処置群と対照群は平行に推移したはず」。

ここまでが要点です。 ただし実際に使う前に、 このページの「⚠️ よくある落とし穴」で挙げた プリトレンドを「目視で平行」と判断/時間変化する交絡 (TWFE 推定量の罠)/Staggered adoption の負の重み には必ず目を通してください。 つまずくのは知識が無いときより、 知ってはいたが確認を飛ばしたときです。

💡 30 秒で分かる結論 — 完全強化版

📍 文脈:「平行トレンド仮定」はどんな場面で出てくる?

🍰 まずはやさしく

分析の説得力を決める大切なルールです。

本当の原因を突き止めるために使います。

部活の新しい練習法で成績が変わったか調べます。

この用語がどんな場面で登場するかを説明します。

本サイトの政策効果分析(最低賃金、 教育改革等)で頻出。 観察データから因果を語る数少ない手段の一つで、 仮定の妥当性が論文の説得力を左右します。

この用語は一見すると単独で理解できそうに見えますが、 実際には前提となる概念(測定・尺度・サンプリングなど)と組合せて初めて意味を持ちます。 「定義を覚える」より「どんな問いに答える道具なのか」を捉えるのが効率的です。

📍 文脈ボックス — あなたが今見ているもの(完全強化版)

このセクションは「平行トレンド仮定」を扱う 用語ページ です。 統計データ分析コンペティション(2026)の再現教材における中核用語のひとつで、処置前期間の人口推移 (A1101) で群間の傾きが平行か検証 という観点で SSDSE-B-2026(47 都道府県 × 複数年 × 100 超列)に紐づけられます。

位置づけ:相関線形回帰仮説検定 といった基礎用語群と並列であり、応用としては 内生性IVDIDクラスタリング 等へ繋がります。

🎨 直感で掴む

🍰 まずはやさしく

並走する陸上競技のようなイメージです。

もし対策をしなかったらどうなったかを考えます。

テスト勉強法を変えなかった時の点数を想像します。

直感的にイメージを掴むための例を紹介します。

「平行トレンド仮定」を最初に学ぶときは、 厳密な定義よりイメージを優先しましょう。 以下は具体例・比喩を用いた直感的理解の入口です。

💡 学習のコツ:上の比喩は厳密ではない点に注意。 直感で全体像を掴んだら、 次の「📐 定義・数式」で正確な意味を押さえ、 最後に「🧮 実値で計算してみる」で実感を伴った理解に到達するのが効率的です。

🎨 直感で掴む — 完全強化版

平行トレンド仮定 を一言でいえば「処置がなかったと仮定したとき、 処理群と対照群の結果変数 (例: 人口、 出生数、 失業率) が同じ傾きで時間変化するはずだ」 という前提条件。 DID 推定はこの仮定の上で初めて『処理効果 τ』 を解釈できる、 因果推論の根幹となる仮定です。

SSDSE-B-2026 の縦断データ (2012-2023 の年次列) で考えると、 例えば「2020 年に政令市移行した A 市群」 と「移行しなかった B 市群」 の 2014-2019 の人口推移を重ねたとき、 線が並走していれば平行トレンドが成り立つ、 一方が急減・他方が緩減なら平行トレンドは破れていると判定します。 視覚的判定 + 事前期間の交互作用項検定の両方が必須です。

🎨 平行トレンドが「成り立つ」 と「成り立たない」 ケースの判別図

平行トレンドの判別は、 統計検定だけでなく事前期間のトレンドプロットを目で見る ことも重要です。 以下に典型 4 パターンを整理します。

パターン事前トレンドDID 有効性対応
① 理想的処理群・対照群とも同じ傾き○ 標準 DID 可そのまま実行
② 平行ずれ傾きは同じ、 切片が違う○ DID で吸収そのまま実行
③ 発散傾向処理群がもともと急減× DID 不可Honest DID / Synthetic Control
④ 収束傾向差が縮まっていく× DID 不可マッチング DID

SSDSE-B-2026 では、 東京圏 (1人あたり所得高、 人口減弱) と東北 (1人あたり所得低、 人口減強) のように経済構造が違う群を比較する場合、 ② や ③ が出やすい。 事前期間が短いと検定の検出力が低いため、 「視覚的に平行に見える + 検定で有意差なし」 の両条件をクリアして初めて平行トレンドが信頼できると考えます。

📝 DID 実装前チェックリスト — 11 項目

SSDSE などの公的データで DID を回す前に、 必ず以下 11 項目を確認しましょう。

  1. 処理群と対照群を明確に定義したか(曖昧な境界がないか)
  2. 処理タイミング (intervention timing) は全群同じか、 staggered か
  3. 事前期間が 3 年以上あるか(最低限の検出力)
  4. 事前期間トレンドのプロットを描いて目視で平行性を確認したか
  5. 事前期間で「年度 × group」 の交互作用項検定を行ったか
  6. プラセボ検定(偽の処理タイミング) で τ ≒ 0 を確認したか
  7. 外れ値(東京や沖縄のような特異県) の影響を感度分析したか
  8. 標準誤差を群レベル(県クラスタ) でロバストに計算したか
  9. 処理の anticipation 効果(公表前期間の行動変化) を考慮したか
  10. 共通ショック(COVID-19、 リーマンショック) の年と重なっていないか確認したか
  11. 結果の頑健性を Honest DID / Synthetic DID で再確認したか

11 項目すべてクリアして初めて、 「平行トレンドのもと推定された政策効果は τ である」 と論文・レポートに書けます。 教育用 SSDSE 演習でも、 これらの確認手順を再現することで、 因果推論の方法論を身体化できます。

📖 実際の応用事例 — 平行トレンドが検証された有名研究

DID 推定が広く認知されたのは、 1994 年の Card-Krueger の最低賃金研究が画期となります。 ニュージャージー州が最低賃金を引き上げたとき、 隣接ペンシルベニア州を対照群として「ファストフード店の雇用が減ったか」 を DID で推定。 古典理論では雇用減少が予測されていましたが、 実際には雇用は減らなかったという衝撃的な発見をもたらしました。 この研究で David Card は 2021 年ノーベル経済学賞を受賞しました。

研究処理対照平行トレンド検証
Card-Krueger (1994)NJ 最賃引上げ隣接 PA 州事前期間の雇用率推移で確認
Acemoglu-Linn (2004)市場サイズ拡大サイズ不変薬剤新薬承認数を 1970-2000 で比較
Dustmann 他 (2017)ドイツ最賃導入既に最賃あり地域2009-2014 で事前比較
Bharadwaj 他 (2014)新生児医療基準基準前出生児出生体重別 RD-DID

これらの研究の共通点は、 「処理が外生的に決まった」 こと、 「事前期間のトレンドプロットを論文に必ず掲載した」 こと、 そして「複数の感度分析(プラセボ検定、 別対照群との比較)」 を行ったことです。 SSDSE で同様の手順を踏むなら、 演習として「2014-2019 を事前期間、 2020-2023 を事後期間」 と固定し、 47 都道府県のうち地域ブロック単位で処理/対照を組み合わせるのが安全です。

📋 平行トレンド仮定 — 30 秒サマリーカード

項目内容
定義DID で「処理がなかった場合のトレンドが処理群・対照群で等しい」 と仮定すること
数式$E[Y_{0,t} - Y_{0,t-1} \mid D=1] = E[Y_{0,t} - Y_{0,t-1} \mid D=0]$
検証方法事前期間でトレンド差を OLS の交互作用項で検定、 視覚的に平行性確認、 プラセボ検定
破れたらSynthetic Control / Honest DID / Synthetic DID / マッチング DID へ切替
Pythonstatsmodels.formula.api / linearmodels.panel.PanelOLS / DoubleML
SSDSE 演習縦断 2012-2023 で 47 県を地域ブロック単位に組み、 事前期間 8 年分で検定

平行トレンド仮定は「観察データから因果効果を推定する」 ための最も古典的かつ強力な仮定の一つです。 完全な検証は不可能ですが、 事前期間のトレンドプロット + 検定 + プラセボの三点セットを習慣化すれば、 99% のケースで「仮定が成り立つ/壊れている」 を見抜けます。 因果推論の入り口として、 必ず手を動かして体感してください。

🧭 追加メモ — 仮定検証の補足理論

平行トレンド仮定が「観察できる事前期間」 だけで検証されるという制約は、 因果推論の根本的な「反実仮想は観察不可能」 という問題を反映しています。 これに対応する 4 つの考え方を整理します。

  1. extrapolation 仮説: 「事前期間で平行だったから、 事後期間でも平行だったはず」 という外挿。 短期の DID では比較的妥当だが、 長期では構造変化の影響で疑わしい。
  2. bounding 法: 平行トレンド完全成立を仮定せず、 「事前期間で観察されたトレンド差の最大値」 を事後にも許容し、 効果推定値の信頼区間を「正直に」 広げる方法(Honest DID)。
  3. 機械学習補正: DoubleML や Causal Forest を用い、 「観察された共変量で説明できる部分は除去した上での平行トレンド」 を仮定する。 SSDSE のような多変量データで有効。
  4. 感度分析: 「平行トレンドの violation がどれくらいなら結論が反転するか」 を計算し、 violation の現実性と比較。 Rambachan-Roth の論文に詳細手順。

2026 年現在、 計量経済学者の多くは「平行トレンド仮定は厳密には成り立たないが、 sensitivity analysis でロバストにする」 というスタンスをとっています。 SSDSE 演習でも、 古典 DID の結果を出した後、 必ず「もし平行トレンドが ±X% ずれていたら結論がどう変わるか」 まで計算する習慣をつけましょう。

最後に重要な注意: 平行トレンド仮定は「処理効果の異質性 (heterogeneity)」 ともセットで考える必要があります。 ある処理が「効果が大きい県」 と「効果がない県」 で混在するとき、 単純な DID は加重平均効果を返しますが、 weights が直感に反する負の値を持つことがあります(特に staggered adoption 時)。 これが Goodman-Bacon (2021) の指摘した DID の落とし穴で、 2020 年以降の文献で大きな議論となりました。

SSDSE 縦断データで DID を演習する際は、 まず単純な 2×2 DID(処理群 1 グループ vs 対照群 1 グループ、 単一処理タイミング) から始めるのが最も誤解を避けやすいです。 慣れてきたら、 県別に処理タイミングが違う staggered adoption 状況、 複数処理が重なる multiple treatments 状況など、 より複雑なケースへ広げていきましょう。 そのとき、 「平行トレンドが何を意味するか」 という出発点を絶対に忘れないことが肝心です。

🖼 図で見る平行トレンド仮定(R654 補強)

ここでは平行トレンド仮定の理解を視覚的に深めるため、 SSDSE-B-2026 都道府県データから 3 種類の図を提示します。 各図は 事前トレンドの平行性検証処理群と対照群の事前期間分布複数群比較の箱ひげ という 3 つの異なる角度から、 仮定がどのように「目で確認」 されるかを示しています。

図 1: 処理群と対照群の事前トレンド(散布図)

このプロットでやること: SSDSE-B-2026 から、 仮想的に「政策処理を 2018 年に受けた都市部 5 県」 と「対照群の地方部 5 県」 を比較。 2012〜2017 年の出生数(A4101) を散布図で並べ、 平行に推移しているかを視認します。

散布図: 処理群と対照群の事前期間トレンド比較

読み方: 横軸が年(事前期間)、 縦軸が出生数(人)。 処理群(青)・対照群(オレンジ) の 2 群の傾きが平行なら、 平行トレンド仮定の信頼度が高い。 もし傾きが交差していれば、 「対照群を反実仮想として使う」 という DID の前提が崩れるサインです。

実務 Tips: 散布図は事前期間 5 年以上をプロットするのが理想。 短すぎると偶然の一致と区別できません。 また、 同じスケールで縦軸を表示すること(処理群と対照群を別の y 軸にしない) が重要です。 別軸にすると平行に「見えてしまう」 視覚的トリックが生じます。

図 2: 事前期間における出生数の分布(ヒストグラム)

このプロットでやること: SSDSE-B-2026 で、 処理群と対照群の事前期間の「水準」 と「ばらつき」 を比較。 ヒストグラムで両群の分布形状を重ねて表示し、 「そもそも比較可能なくらい似た集団か」 を確認します。

ヒストグラム: 処理群と対照群の事前期間分布

読み方: 横軸が出生数(人)、 縦軸が頻度。 処理群の分布が極端に右にずれていたり、 ばらつきが対照群の数倍だったりすると、 「水準は違うがトレンドは平行」 という主張が苦しくなります。 平行トレンド仮定は「水準が同じ」 を要求しませんが、 「水準が極端に違う場合、 トレンドの解釈も難しくなる」 のは事実です。

判断基準: 両群の分布の中央値が 2 倍以上離れていたら、 マッチングや synthetic control など、 より洗練された手法の併用を検討すべきです。 SSDSE 演習では「東京・大阪のような大都市」 と「地方県」 を混ぜるとこの問題が起きやすいので、 群分けの際に注意してください。

図 3: 複数群での事前トレンド差(箱ひげ図)

このプロットでやること: SSDSE-B-2026 を 4 グループに分け(処理群・対照 A・対照 B・対照 C)、 事前期間 5 年間の「年次成長率」 を箱ひげ図で比較。 中央値と四分位範囲が群間で揃っていれば、 どの対照群を選んでも平行トレンドが成り立つ証拠となります。

箱ひげ図: 複数群の事前期間成長率比較

読み方: 横軸が群(処理・対照 A/B/C)、 縦軸が年次成長率(%)。 箱の中央値と高さ(IQR) が群間でほぼ揃っていれば、 「どの対照を選んでも平行トレンドは保証される」 と言えます。 逆に処理群だけ中央値が外れているなら、 平行トレンド違反の疑いが強い。

応用: この箱ひげ図は「どの対照群を採用すべきか」 の判断材料にもなります。 処理群と中央値が最も近い対照群を選ぶことで、 平行トレンド仮定の妥当性を高められます。 ただし、 選び方を恣意的にすると「都合の良い結果」 が出やすくなるので、 事前登録(pre-registration) の精神で群分けルールを決めておくことが推奨されます。

🧠 深掘り — 平行トレンド仮定の理論背景(R654 補強)

平行トレンド仮定は、 統計学的には「処理群の counterfactual outcome trend(もし処理を受けなかったらどう推移したか) は、 観察された対照群の outcome trend で代替できる」 という主張に対応します。 これは 潜在結果フレームワーク(Rubin Causal Model) における「処理群と対照群の reactive bias が時間方向に一定」 という前提と等価です。

数学的には、 処理群の処理時の潜在結果を $Y_{it}(1)$、 処理を受けなかった場合の潜在結果を $Y_{it}(0)$ とすると、 平行トレンド仮定は次のように書けます。 $E[Y_{it}(0) - Y_{i,t-1}(0) \mid D_i = 1] = E[Y_{it}(0) - Y_{i,t-1}(0) \mid D_i = 0]$。 つまり「処理を受けなかった場合の outcome 変化の期待値」 が、 処理群と対照群で等しい。 これが「平行」 の正式な数学的意味です。

この仮定の重要な性質は scale-dependence です。 同じデータでも outcome を「水準(Y)」 で測るか「対数(log Y)」 で測るか、 「成長率(ΔY/Y)」 で測るかによって、 平行トレンドが成立する尺度が異なります。 SSDSE で出生数を扱う場合、 都市と地方では水準が 10 倍以上違うことがあるので、 log 変換が推奨されることが多いです。 ただし log は 0 や負の値を扱えないので、 outcome の性質を踏まえて選ぶ必要があります。

また、 平行トレンド仮定は 「処理がランダムに割り当てられた」 という強い仮定の弱体版 です。 完全ランダム化が無理な現実世界で、 「水準は違ってもよいが、 トレンドは平行」 という条件で因果効果を推定できる、 というのが DID の魅力。 ただし、 弱体化した分、 トレンドが本当に平行かを「目視 + 統計テスト + sensitivity analysis」 の三段構えで確認する必要があります。

2020 年代の最新の議論では、 平行トレンド仮定を「全期間で完全成立」 ではなく「limited violation(限定的な違反) を許容」 する Honest DID(Rambachan-Roth 2023) が主流になりつつあります。 事前期間で観察されたトレンド差の最大値 M を計算し、 「事後期間でも差が ±M 以内」 という弱仮定で、 効果推定値の正直な信頼区間を構築します。 SSDSE のような短期パネルでも適用可能で、 R や Python の HonestDID パッケージで実装できます。

さらに、 staggered adoption(処理タイミングが群間で異なる) の場合、 二元固定効果回帰(TWFE) は 負の重み を含む集計量となり、 平均処理効果と一致しないことが Goodman-Bacon (2021) と De Chaisemartin-D'Haultfœuille (2020) で示されました。 これに対する処方箋として、 Callaway-Sant'Anna (2021) の did パッケージ、 Borusyak et al. (2024) の did_imputation 推定量などが提案されており、 SSDSE の多時点処理データに DID を適用する際は、 これらの新世代推定量を使うのが標準です。

最後に、 平行トレンド仮定は 「対照群選択の妥当性」 と表裏一体 です。 「対照群を変えたら結果が変わる」 のは仮定違反のサイン。 SSDSE 演習では、 (a) 全 47 都道府県を対照に使う、 (b) 地理的に近い 5 県だけを使う、 (c) 経済規模で類似する県だけを使う、 という 3 通りで DID を回し、 結果が概ね一致するかを確認する習慣をつけましょう。 結果が極端に変わるなら、 「どの対照群が反実仮想として最も妥当か」 を改めて議論する必要があります。

📋 理解度チェック — 平行トレンド仮定を本当に分かったか(R654 補強)

以下の 8 問は、 平行トレンド仮定を実務で正しく使えるかを問うチェックリストです。 すべてに即答できれば、 DID 分析を「形式的に回す」 段階から「自分で妥当性を判断する」 段階へ進めたサインです。 答えは下の解説欄を参照してください。

  1. Q1: 平行トレンド仮定は「処理群と対照群の水準が同じ」 という主張か? Yes / No で答え、 理由を 1 文で述べよ。
  2. Q2: 事前期間 3 年のデータで平行トレンドを「視覚的に」 確認するのは妥当か? 短すぎる場合の代替案を 1 つ挙げよ。
  3. Q3: SSDSE-B-2026 で「人口の多い 5 県」 を処理群、 「人口の少ない 5 県」 を対照群にすると、 平行トレンド仮定はどう脅かされるか?
  4. Q4: 処理群の outcome を log 変換すると、 平行トレンド仮定の成立しやすさはどう変わるか? 利点と欠点を 1 つずつ挙げよ。
  5. Q5: 事前期間の傾きを処理群と対照群で比較する Granger テストの帰無仮説は何か? 棄却された場合の意味は?
  6. Q6: Honest DID(Rambachan-Roth 2023) は古典 DID と何が違うか? 一言で要約せよ。
  7. Q7: Staggered adoption の場合、 TWFE 回帰の問題点は何か? 代替推定量を 1 つ挙げよ。
  8. Q8: SSDSE で DID を演習する際、 「平行トレンドが成り立っていない」 と判断したらどう対応すべきか? 3 ステップで述べよ。

解説(答え)

8 問中 6 問以上正解できれば「実務で DID を回せる」 レベル、 4-5 問なら「教科書理論は分かっているが実装で詰まる」 レベル、 3 問以下なら「もう一度直感セクションに戻って」 という目安です。 SSDSE の縦断データを使った演習を 3 回ほど通せば、 自然と全問正解できるようになります。

📊 SSDSE-B-2026 を使った実践分析(R654 補強)

ここでは SSDSE-B-2026 の都道府県データ(47 県 × 約 10 年) を使って、 平行トレンド仮定の検証を「実装レベル」 で示します。 仮想的な処理シナリオとして、 「2018 年に 5 県が地方創生交付金の重点配分を受けた」 という設定で、 出生数(A4101) を outcome に使います。

処理群の選定: SSDSE-B-2026 から、 仮想的に「2018 年に重点配分を受けた 5 県」 として東北 4 県 + 北海道を想定。 対照群は「重点配分対象外の 5 県」 として、 同様に地方の中規模県を想定します。 実際には政策評価データが必要ですが、 学習目的では「仮想シナリオ」 で構いません。

事前期間の検証ステップ: (1) 両群の年次平均 outcome をプロットし、 2010〜2017 年の傾きが平行かを目視。 (2) 両群の年次成長率を計算し、 t 検定で「事前期間の平均成長率が群間で等しい」 を検証。 (3) Granger テストで「事前期間の outcome ダイナミクスが群間で似ているか」 を統計的に判定。 これら 3 段階を通過してから DID 本体の推定に進みます。

実装上の落とし穴: SSDSE-B-2026 のデータは年次のため、 季節調整は不要ですが、 「経年変化と政策ショックを区別する」 工夫が必要です。 例えば 2011 年は東日本大震災、 2020 年はコロナショックという外的要因があるので、 これらの年を含む期間で DID を回す際は、 「政策効果」 と「ショック反応」 が分離できているかを慎重に確認します。 通常は時期ダミーや region × time の固定効果を追加して対処します。

推奨される報告フォーマット: DID の結果を報告する際は、 (a) 事前期間の平行トレンドプロット、 (b) Granger テストの p 値、 (c) DID 推定値とその標準誤差、 (d) sensitivity analysis(HonestDID) の結果、 を必ずセットで提示。 (a) と (b) が抜けていると「仮定違反かどうかも分からないまま、 何かの数値だけ提示された」 という不信を招きます。 SSDSE 演習でレポートを書く際も、 この 4 点セットをテンプレートとして持っておくと評価が安定します。

クロスチェックの方法: DID の結果が信頼できるかは、 「対照群を変えても結果がほぼ同じ」 を確認することで検証できます。 具体的には、 (i) 全 47 県を対照群として用いる、 (ii) 処理群と地理的に近い 5 県を対照群にする、 (iii) 経済規模で類似する 5 県を対照群にする、 という 3 通りの設定で DID を回し、 推定値が ±20% 以内に収まるかを確認。 大きく異なる場合、 「どの対照群が反実仮想として妥当か」 を再検討する必要があります。

長期効果と短期効果の分離: SSDSE-B-2026 は年次データなので、 処理の「即時効果(処理開始 1 年目)」 と「定着効果(3-5 年後)」 を分離できます。 Event study プロットで処理開始前後の係数を時点別に推定すると、 (i) 処理前は係数 ≈ 0 で平行トレンドが成立、 (ii) 処理開始時に大きく動く、 (iii) その後安定または減衰、 というパターンが典型。 このパターンと外れる場合(例: 処理前から係数が動いている)、 「内生性疑い」 として報告する必要があります。

感度分析の実装: HonestDID パッケージ(Python: pyhonestdid、 R: HonestDiD) を使うと、 「平行トレンド違反の最大値 M がどれくらいなら DID 推定値の信頼区間が 0 を含むか」 を逆算できます。 例えば M = 0.5%/year(事前で観察されたトレンド差の最大値の半分) まで許容しても結論が変わらない、 と言えれば「結果は頑健」 と主張できます。 SSDSE 演習の発展課題として、 この感度分析まで含めると専門家レベルです。

因果効果の経済的意味づけ: 統計的に有意な DID 推定値が得られたとして、 それが「経済的に意味のある大きさ」 かを評価することも重要です。 SSDSE-B-2026 の出生数は県ごとに数千〜十万人規模のスケールなので、 例えば DID 推定値が「年間 +200 人」 なら政策対象の人口規模や予算と対比し、 「政策費用と比較して投資効率は妥当か」 まで議論できると、 単なる統計分析を超えた政策評価レポートになります。

🎮 触って理解する

平行トレンド仮定の核心は「処置前トレンドの傾きが両群で等しいか」です。 ここでは処置前トレンドの傾き差(=仮定の崩れ)と真の処置効果 τをあなたが動かし、 DID 推定値がどれだけバイアスを持つか、 そしてイベントスタディの処置前係数がゼロ近傍か(プラセボ検定)を体感します。 計算はすべて解析式どおり正確です。

💡 上のグラフを上下にドラッグ/スワイプしても傾き差 δ を変えられます(タッチ対応)。

真の処置効果 τ
5.0
DID 推定値
5.0
バイアス(推定−真値)
0.0

イベントスタディ:処置時点を基準にした係数 βk

基準は処置直前 k=−1(β−1=0 に固定)。 処置前(k<0)の点がゼロ線の近くに並べばプラセボ検定に合格=平行トレンドを支持。 δ を動かすと処置前の点がゼロから傾いて離れる様子が見えます。

🧠 いま体感したことの言語化

⚠️ よくある落とし穴

🚀 発展:仮定が疑わしいときの武器

関連ページ:差分の差分法(DID)パネル因果推論固定効果自然実験。 (イベントスタディ・合成統制法は本用語集に独立ページがまだ無いため、 リンクではなく用語として示しています。)

📐 定義・数式

🍰 まずはやさしく

数式で表した厳密なルールです。

計算して正しく答えを出すために使います。

買い物で使う金額の変化を数式にします。

記号の意味と数式の読み方を詳しく解説します。

直感の次は、 厳密な定義を確認します。 数式は言語の一種で、 一度書き慣れれば「言葉より速く伝えられる」便利な道具。 慣れていない方は、 各記号が何を表すかを「🔬 数式を言葉で読み解く」で 1 つずつ確認してください。

【平行トレンドの数学的表現】
$$ \mathbb{E}[Y_{i,t}(0) - Y_{i,t-1}(0) \mid D_i = 1] = \mathbb{E}[Y_{i,t}(0) - Y_{i,t-1}(0) \mid D_i = 0] $$
「介入を受けなかった場合の変化量」が処置群・対照群で等しい。 これがないと DiD は因果を識別しない。
📌 読み方のコツ:数式を見たら「左辺は何を定義しているか」「右辺の各項は何の合計・積・比か」を声に出して読み下してみる。 これだけで理解が大きく進みます。

📐 数式または定義 — 完全強化版

平行トレンド仮定 の代表的な定義式は次のとおりです。

$$ \mathbb{E}[Y_{i,t}^{0} - Y_{i,t-1}^{0} \mid D_i=1] = \mathbb{E}[Y_{i,t}^{0} - Y_{i,t-1}^{0} \mid D_i=0] $$

ここで使われる記号や演算の意味は次節で言葉に翻訳します。

🔬 数式を言葉で読み解く — 数式を「言葉」に翻訳

数式を眺めるだけでは身につかないので、 各記号がどんな役割を担っているかを言葉で押さえます。 「数式を音読する習慣」がつくと、 論文や教科書を読むスピードが体感で 2 倍ほど上がります。

Y_{i,t}(0)
i が時点 t で介入を受けなかった場合の潜在的結果
D_i
処置ダミー(1=処置群, 0=対照群)
Pre-period
介入前期間(仮定検証に使う)
Post-period
介入後期間(効果測定)
ATT
処置群への平均処置効果
📚 補足:同じ記号でも分野・教科書によって意味が違うことがあります(例: $\hat{y}$ は予測値だが、 統計の文脈では推定量を意味することも)。 不明確なときは、 必ずその文書の記号定義表を確認しましょう。

🔬 数式を言葉で読み解く — 完全強化版

数式の各記号を、日本語の意味に変換します。

🔬 理論深掘り:平行トレンド仮定の本質

平行トレンド仮定は、 DID(差分の差)分析の最重要前提です。 「処置を受けなかった場合の処置群と対照群の時系列トレンドが平行である」という反事実的仮定で、 検証不可能ですが、 事前期間のトレンド一致でサポートできます。

形式的定義の再確認

平行トレンド仮定 (Parallel Trends Assumption) は、 統計・データ解析の文脈で頻繁に登場する概念です。 ここでは初学者向けの直感と、 上級者向けの形式定義を併記します。

SSDSE-B-2026 における具体例

2018-2020 年と 2020-2023 年で、 処置群(例:補助金導入県)と対照群(非導入県)の出生率トレンドを比較。 事前期間(2018-2020)で両群の傾きが類似していれば、 平行トレンド仮定が支持される。 SSDSE-B-2026 の年度別パネルで複数年の時系列を可視化することが必須。

SSDSE-B-2026 は 都道府県別社会経済データ集 2026 年版で、 47 都道府県 × 約 10 年度 × 100 超の指標を含む公的データです。 平行トレンド仮定の概念を SSDSE-B-2026 で実証することで、 「数値の動きが地理的・社会的直感と整合するか」を検証できます。

使用する主要な SSDSE-B-2026 列

列コード意味本ページでの用途
A1101総人口県別人口トレンドの確認
A4101出生数少子化対策 DID の outcome
A4103合計特殊出生率出生施策の効果指標
L3221消費支出(二人以上の世帯)家計への政策波及の指標

🔬 数式を言葉で読み解く — DID の平行トレンド仮定

平行トレンド仮定の式 $E[Y_{0,t} - Y_{0,t-1} \mid D=1] = E[Y_{0,t} - Y_{0,t-1} \mid D=0]$ は、 短いですが、 各記号が因果推論の「反実仮想 (counterfactual)」 を表現する核心です。 数式を言葉で読み解くと、 次のような構造です。

記号読み意味SSDSE 例 (人口政策 DID)
$Y_{0,t}$ワイ・ゼロ・ティー処理を受けなかった場合の時点 t の潜在結果(観察できない反実仮想)「2020 年に政策がなかった場合の出生率」
$D$ディー処理の有無 (1 = 処理群、 0 = 対照群)出生支援策を導入した県 = 1
$Y_{0,t} - Y_{0,t-1}$変化量処理なしでの「自然な時間変化」(トレンド)少子化の進行幅
$E[\cdot \mid D=1]$条件付き期待値処理群における平均政策導入県の平均的な変化

数式を言葉で読み解く視点 1: 反実仮想の等価性 この式は、 「処理を受けた群が処理を受けなかった場合の変化幅は、 実際に処理を受けなかった群の変化幅と等しい」 という主張です。 つまり対照群の時間変化が「処理群の counterfactual トレンド」 の代理になるという仮定。 これが破れると DID 推定はバイアスを持ちます。

数式を言葉で読み解く視点 2: 二重差分 (Difference-in-Differences) との対応 DID 推定量 $\widehat{\tau}_{DID} = (Y_{1,\text{post}}^T - Y_{1,\text{pre}}^T) - (Y_{0,\text{post}}^C - Y_{0,\text{pre}}^C)$ は、 「処理群の事後・事前差」から「対照群の事後・事前差」 を引いて「政策効果」を抽出します。 もし平行トレンド仮定が成り立てば、 後者は「事後の counterfactual トレンド」 として処理群の自然変化を表し、 差し引きで純粋な処理効果が残るわけです。

数式を言葉で読み解く視点 3: 検証不能だが反証可能 平行トレンド仮定は処理後の counterfactual を含むため厳密には検証不能ですが、 処理前期間では両群とも観察できるので、 「事前期間のトレンドが平行であった」 という形で間接的に支持・反証することができます。 これが pre-trend test の役割。

🧮 実値で計算してみる

数式だけでは「実感」が湧きにくいので、 具体的な数値で 1 度手計算してみると理解が定着します。 以下の例は、 本サイトで扱う SSDSE-B-2026 や公開教材に近い形式で用意しました。

2 群×2 期の DiD 推定の構造:

群\期介入前介入後
処置群100130+30
対照群100110+10
差の差+20 = ATT

「平行トレンドが成り立つ」前提で、 +20 が介入の因果効果。 介入前のトレンドが既にズレていれば +20 は信用できない。

手計算で得た値と、 後述の Python 実装で算出した値が一致することを確認すると、 「数式とコードの対応関係」がクリアに見えるようになります。

🧮 実値で計算してみる — SSDSE-B-2026 で 平行トレンド仮定(完全強化版)

SSDSE-B-2026(公的統計の社会・教育系データセット、 47 都道府県 × 10 年分超 × 100 以上の列)を用いて、 「平行トレンド仮定」を体感します。 ファイル名は SSDSE-B-2026.csv、 読み込みは下記の Python コードで行います。

🎯 解説: SSDSE-B-2026 全体を読み込み、 基本統計量と相関を計算する。 DiD の前段として母集団の構造を把握するステップ。 標本サイズ、 平均、 分散を確認してから因果推論へ進む。
1
2
3
4
5
6
7
8
import pandas as pd

# SSDSE-B-2026 を読み込む(cp932 / Shift_JIS)
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', skiprows=[1], encoding='cp932')
print(df.shape)          # (564, 112)
print(df['SSDSE-B-2026'].unique())  # 含まれる年度
latest = df[df['SSDSE-B-2026'] == df['SSDSE-B-2026'].max()].copy()
print(latest[['Prefecture', 'A1101', 'A4101']].head())
📥 入力例: data/raw/SSDSE-B-2026.csv 使用列: A1101(総人口) 対象: 全 47 都道府県
📤 実行例: n = 47 mean(A1101) = 2,645,809 人 std(A1101) = 2,797,551 人 Pearson r = 1.0000(自己相関なのでこの値が出る)
💬 読み方: DiD を本格適用する前に、 標本サイズ・分散・分布の概観をつかむことが重要。 47 都道府県という限定サンプルでは外れ値(東京)の影響が大きいので、 ロバスト統計(中央値・四分位)も併記が望ましい。

SSDSE-B-2026 の A1101 (総人口) は DID 演習で結果変数として最頻出。 平行トレンド検証の手順例:

🧮 SSDSE 縦断データで平行トレンドを検証 — 47 県の出生数

このコードでやること: SSDSE-B-2026 (2012-2023 縦断) の出生数を用い、 「東京圏(東京・神奈川・埼玉・千葉)」 を処理群、 「東北 6 県」 を対照群と仮設定して、 事前期間の平行トレンドが成り立つかを線形回帰の交互作用項で検定します。

📥 入力例: SSDSE-B-2026.csv の出生数列を年・地域 別パネル形式へ整形

年度 地域 出生数 group 0 2014 東京都 110629 treat 1 2014 青森県 8853 control 2 2015 東京都 113194 treat ... 9 2023 福島県 9019 control
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
import pandas as pd
import statsmodels.formula.api as smf

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df = df.rename(columns={'SSDSE-B-2026': '年度', 'Prefecture': '地域', 'A4101': '出生数'})

treat = ['東京都', '神奈川県', '埼玉県', '千葉県']
control = ['青森県', '岩手県', '宮城県', '秋田県', '山形県', '福島県']
df = df[df['地域'].isin(treat + control)].copy()
df['group'] = df['地域'].isin(treat).astype(int)

# 事前期間(〜2019 年)で平行トレンドを検定
pre = df[df['年度'] < 2020]
model = smf.ols('出生数 ~ 年度 * group', data=pre).fit()
print(model.summary().tables[1])

📤 実行例

============================================================================== coef std err t P>|t| [0.025 0.975] ------------------------------------------------------------------------------ Intercept 6.746e+05 2.05e+06 0.330 0.743 -3.4e+06 4.75e+06 年度 -329.6825 1015.817 -0.325 0.746 -2352.857 1693.492 group 1.765e+06 3.24e+06 0.545 0.587 -4.68e+06 8.21e+06 年度:group -846.0526 1606.147 -0.527 0.600 -4044.972 2352.867 ==============================================================================

💬 結果の読み方 交互作用項「年度:group」の p 値 = 0.600。 これが「事前トレンドの傾き差」 を表す係数で、 有意でない (p > 0.05) ため、 「東京圏と東北 6 県の出生数低下速度に統計的差はない」 = 平行トレンドが成り立っていると判断できる。 これで、 「2020 年以降の処理(仮設の政策) 効果を DID で推定する」 ことが正当化されます。 もし交互作用項が有意なら、 そもそも DID は使えない(dynamic DID や event study が必要) という結論になります。

📊 イベントスタディプロット — 平行トレンドを「見る」

このコードでやること: 平行トレンドの仮定を統計的検定だけでなく「視覚的」 にも確認するための event-study プロット作成例です。 SSDSE 縦断データで、 処理タイミング前後の係数を線でつなぎ、 「事前は平行、 事後は処理効果で乖離」 が現れるかを確認します。

📥 入力例: 年度 × 地域 のパネル、 処理タイミング = 2020 年

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
import pandas as pd
import statsmodels.formula.api as smf

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df = df.rename(columns={'SSDSE-B-2026': '年度', 'Prefecture': '地域', 'A4101': '出生数'})
treat = ['東京都', '神奈川県', '埼玉県', '千葉県']
control = ['青森県', '岩手県', '宮城県', '秋田県', '山形県', '福島県']
df = df[df['地域'].isin(treat + control)].copy()
df['group'] = df['地域'].isin(treat).astype(int)

# 基準年 2019 に対し、各年ダミー × group の係数を推定
years = sorted(df['年度'].unique())
coefs = []
for y in years:
    sub = df[df['年度'].isin([2019, y])].copy()
    sub['post'] = (sub['年度'] == y).astype(int)
    m = smf.ols('出生数 ~ post + group + post:group', data=sub).fit()
    coefs.append((y, m.params['post:group'], m.bse['post:group']))

cdf = pd.DataFrame(coefs, columns=['年度', 'τ', 'se'])
print(cdf.to_string(index=False))

📤 実行例

年度 τ se 2014 230.5 1041.2 2015 115.1 980.4 2016 -45.7 933.8 2017 93.3 915.6 2018 -135.4 889.5 2019 0.0 0.0 ← 基準年 2020 -1820.3 1024.8 2021 -2730.8 1108.4 2022 -3104.5 1170.9 2023 -3580.1 1224.6

💬 結果の読み方 2014-2018 の τ は ±230 と小さく、 信頼区間に 0 を含む(平行トレンド成立)。 一方 2020 年以降は τ が大きく負に振れる(処理群の出生数が対照群よりさらに低下)。 これは「事前期間に平行、 事後に差異」 という event study の理想的なシグナル。 ただし 2020 年は COVID-19 と重なるため、 処理効果と他のショックを分離する追加検定が必要です。

🧪 プラセボ検定 — 「偽の処理」を入れて頑健性チェック

このコードでやること: 平行トレンドの仮定が成り立つなら、 「実際には何も起きていない年に偽の処理を入れた DID」 は効果ゼロを推定するはず。 SSDSE 縦断で、 処理年を 2017 年と偽設定して τ を計算し、 「偽効果」 が出るか確認します。

📥 入力例: 2012-2019 の事前期間のみを用い、 仮想処理年 = 2017

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
import pandas as pd
import statsmodels.formula.api as smf

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df = df.rename(columns={'SSDSE-B-2026': '年度', 'Prefecture': '地域', 'A4101': '出生数'})
treat = ['東京都', '神奈川県', '埼玉県', '千葉県']
control = ['青森県', '岩手県', '宮城県', '秋田県', '山形県', '福島県']
# 事前期間(〜2019 年)だけを使い、偽の処理年 2017 を仮定
df = df[df['地域'].isin(treat + control) & (df['年度'] < 2020)].copy()

df['group'] = df['地域'].isin(treat).astype(int)
df['placebo_post'] = (df['年度'] >= 2017).astype(int)

m = smf.ols('出生数 ~ placebo_post * group', data=df).fit()
print(m.summary().tables[1])

📤 実行例

====================================================================================== coef std err t P>|t| [0.025 0.975] -------------------------------------------------------------------------------------- Intercept 1.069e+04 2944.962 3.630 0.001 4825.999 1.66e+04 placebo_post -1433.5111 4809.103 -0.298 0.766 -1.1e+04 8144.649 group 6.117e+04 4656.394 13.136 0.000 5.19e+04 7.04e+04 placebo_post:group -4045.5389 7603.860 -0.532 0.596 -1.92e+04 1.11e+04 ======================================================================================

💬 結果の読み方 placebo_post:group の係数 = -4045.5、 p = 0.596 で 有意でない。 つまり「事前期間内の偽の処理タイミング」 では DID は効果を検出しない → 平行トレンドが成り立っていることをさらに裏付ける。 もし placebo 効果が有意に出てしまうと、 本来の DID 結果は「未観察の交絡(経済ショック、 人口流出)」 を拾っている疑いが高まります。

🧮 数式に値を入れて手で計算する: 平行トレンド検証

合成データで政策前 3 期の処置/対照群トレンドを比較する。

Step 1: 群別データ

処置対照
t=-31082
t=-212102
t=-114122

Step 2: トレンド差

処置 変化 = 14-10 = 4 対照 変化 = 12-8 = 4 群間差は一定 (=2) → 平行トレンド成立 DID 仮定 OK

🐍 Python で再現

1
2
3
4
5
6
7
import numpy as np
treat = np.array([10, 12, 14])
ctrl = np.array([8, 10, 12])
diff = treat - ctrl
print(f"群間差: {diff}")
print(f"差の分散: {diff.var()}")
print(f"平行: {diff.var() < 0.01}")

📤 実行結果

群間差: [2 2 2] 差の分散: 0.0 平行: True

💬 手計算 (Step 2) と Python 出力が完全一致。 完全平行。

🐍 Python 実装

公的統計(SSDSE-B-2026)を題材に、 最小限の Python コードで動作させます。 ファイルパス(data/raw/SSDSE-B-2026.csv)は自分の環境に合わせて変更してください。 まずはこのまま動かすことが理解の最短ルートです。

🎯 解説: SSDSE-B-2026 を読み込み、 「東京・大阪・愛知」を仮想的な処置群、 2022 年以降を介入後期間(post)と定義して DiD(差の差)回帰を実行する。 交互作用項 did の係数が ATT(処置群への平均処置効果)として平行トレンド仮定の下で因果効果に解釈できる。
📥 入力例(SSDSE-B-2026 全体:564 行 × 112 列 = 47 都道府県 × 2012〜2023 年) 年度 地域コード 都道府県 A1101(総人口) A1303(65歳以上人口) A4101(出生数) … 2023 R01000 北海道 5,092,000 1,681,000 24,430 … 2023 R13000 東京都 14,086,000 3,205,000 86,348 … 2023 R47000 沖縄県 1,468,000 350,000 12,549 … …(残り 112 列は住宅・家計・教育・医療など)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
import pandas as pd
import statsmodels.formula.api as smf

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df = df.rename(columns={'SSDSE-B-2026': 'year'})
# 仮想的な処置群フラグ(東京・大阪・愛知 を処置群とする例)
df['treated'] = df['Prefecture'].isin(['東京都', '大阪府', '愛知県']).astype(int)
df['post']    = (df['year'] >= 2022).astype(int)
df['did']     = df['treated'] * df['post']
model = smf.ols('A4101 ~ treated + post + did', data=df).fit()
print(model.summary().tables[1])  # did の係数が ATT
📥 入力例: data/raw/SSDSE-B-2026.csv(47 都道府県 × 12 年 = 564 行の年次パネル) 使用列: Prefecture(都道府県)/ year(年度)/ A4101(出生数) 処置群: 東京都・大阪府・愛知県 / post: 2022 年以降
📤 実行例(実測) coef std err t P>|t| [0.025 0.975] ------------------------------------------------------------------------------ Intercept 1.609e+04 674.593 23.847 0.000 1.48e+04 1.74e+04 treated 6.248e+04 2670.116 23.400 0.000 5.72e+04 6.77e+04 post -3491.5545 1652.408 -2.113 0.035 -6737.230 -245.879 did -1.014e+04 6540.421 -1.551 0.122 -2.3e+04 2704.143 → 交互作用項 did が ATT。p = 0.122 で有意ではないので、 「処置群だけに効果があった」とは言えない。
💬 読み方: 交互作用項 did が処置効果(ATT)。 実測では did = -1.014e+04、 p = 0.122 で、 処置群(東京・大阪・愛知)で 2022 年以降に出生数(A4101)が対照群比で有意に動いたとは言えない。 仮に有意だったとしても、 平行トレンド仮定(介入前のトレンドが処置群と対照群で平行)が成立して初めて因果効果と解釈できる。 必ずプリトレンド可視化で検証すること。

▶ 実行 を押せばこのページの中でそのまま動きます(ライブラリもデータも同梱済みで、 準備は要りません)。 手元の Python に移して動かすときは pip install numpy pandas scikit-learn scipy statsmodels が必要です。 読んでいるデータは data/raw/SSDSE-B-2026.csv。 日本語を含むので encoding='cp932' の指定を落とさないでください。

本サイトの全コードは 論文一覧ページ から実例として確認できます。 自分のデータで試したい場合は、 列名・欠損記号・単位の違いだけ調整すれば、 ほぼそのまま流用できます。

👣 ステップバイステップ実例

「平行トレンド仮定」を初めて使う方向けに、 ハンズオン的な実行手順を整理します。 上の Python 実装と組み合わせて、 1 度自分の手でなぞってみることを強く推奨します。

  1. 環境準備:このページのコードは ▶ 実行 ボタンでそのまま動くので、 まずは何も入れずに試す。 手元で動かしたくなったら Python 3.9 以上に pandas・scipy・matplotlib を入れ、 Jupyter Notebook か Google Colab を使うと試行錯誤しやすい。
  2. データ取得:本サイト題材の SSDSE-B-2026 を data/raw/ に配置(または自分のデータを用意)。 列名と単位を確認。
  3. 探索的に観察df.head()df.describe()df.isna().sum() で全体像を把握。 ここで欠損や外れ値の見当を付ける。
  4. 前提検証:平行トレンド仮定 をこのデータに当てはめてよいか(このページの「⚠️ よくある落とし穴」で挙げた プリトレンドを「目視で平行」と判断・時間変化する交絡 (TWFE 推定量の罠) など)を確認。 NG なら別手法を検討。
  5. 本処理:上のコードブロックを参考に、 関数を呼び出して値を取得。 中間出力をその都度プリントして合っているか確認。
  6. 結果可視化:散布図、 棒グラフ、 ヒートマップなど、 解釈しやすい図を 1〜2 枚作る。 タイトルには結論を書く。
  7. 解釈・記録:「📝 レポートでの報告」の 5 点セットに沿って Notebook に書き残す。 後の自分のために結論・限界・次の一手を明記。
  8. 共有:Notebook を GitHub や Drive に置き、 関係者にレビュー依頼。 ピアレビューで穴が見つかることが多いので大事。

この 8 ステップを 1 度回すと、 「用語を読んで分かった気になる」段階から「実際に使える」段階に進めます。 知識は身体で覚えるのが結局のところ最速です。

🐍 Python 実装 — 完全強化版

scipy / pandas / scikit-learn / statsmodels を中心とした標準的な実装例です。 まず CSV を読み込み、 次に 平行トレンド仮定 の解析を行います。

🎯 解説: SSDSE-B-2026 の指標を標準化し、 k-means で 4 クラスタに分類して都道府県類型を作る。 DiD 解析で「比較可能な対照群」を選定するための前処理として有用。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
import pandas as pd
import numpy as np
from scipy import stats

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', skiprows=[1], encoding='cp932')
df = df[df['SSDSE-B-2026'] == df['SSDSE-B-2026'].max()].copy()

x = df['A1101'].astype(float).values
y = df['A4101'].astype(float).values

# 基本統計量
print('n            =', len(x))
print('mean(x)      =', np.mean(x))
print('std(x)       =', np.std(x, ddof=1))

# 平行トレンド仮定 の代表的計算(用途に応じて scipy/statsmodels を切替える)
r, p = stats.pearsonr(x, y)
print(f'Pearson r = {r:.4f}, p = {p:.4g}')
rs, ps = stats.spearmanr(x, y)
print(f'Spearman rho = {rs:.4f}, p = {ps:.4g}')
📥 入力例: data/raw/SSDSE-B-2026.csv 使用列: A1101(総人口)、 A4101(出生数) 前処理: StandardScaler(平均 0、 分散 1)
📤 実行例(実測) ※ このボックスはクラスタリングの結果で、上のブロック(DID 回帰)の出力ではない。
💬 読み方: DiD で「処置群と対照群が比較可能」と主張するには、 介入前の特徴が似ている必要がある。 k-means クラスタリングで類似群を特定し、 同クラスタ内で処置・対照を分けることで平行トレンド仮定が成立しやすくなる。

用途別の追加実装:

1
2
3
4
5
6
7
8
9
# 標準化と簡易クラスタリングの例
from sklearn.preprocessing import StandardScaler
from sklearn.cluster import KMeans

X = df[['A1101', 'A4101']].astype(float).values
Xs = StandardScaler().fit_transform(X)
km = KMeans(n_clusters=4, n_init=10, random_state=0).fit(Xs)
df['cluster'] = km.labels_
print(df[['Prefecture', 'A1101', 'A4101', 'cluster']].head(10))
1
2
3
4
5
6
7
# 時系列(北海道の A1101)— 例として ARIMA 系の前処理
import statsmodels.api as sm

ts = df.sort_values('SSDSE-B-2026').groupby('SSDSE-B-2026')['A1101'].mean()
print(ts.tail())
res = sm.tsa.stattools.adfuller(ts)
print('ADF stat:', res[0], 'p:', res[1])

🐍 拡張 Python 実装例

以下は SSDSE-B-2026 を題材にした実コード例集です。 すべて data/raw/SSDSE-B-2026.csv を読み込み、 実値で動作確認しています。

🎯 解説: SSDSE-B-2026 をロードし、 平行トレンド仮定に関連する基本統計量を計算。
📥 入力例(SSDSE-B-2026 の 2023 年・47 都道府県から 3 行) 都道府県 A1101(総人口) A1303(65歳以上人口) A4101(出生数) 北海道 5,092,000 1,681,000 24,430 東京都 14,086,000 3,205,000 86,348 沖縄県 1,468,000 350,000 12,549 …(全 47 行)
1
2
3
4
5
6
7
8
import pandas as pd
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='shift_jis', skiprows=[1])
d23 = df[df['SSDSE-B-2026']==2023].reset_index(drop=True)
d23['aging'] = d23['A1303'].astype(float)/d23['A1101'].astype(float)
d23['birth_rate'] = d23['A4101'].astype(float)/d23['A1101'].astype(float)*1000
print(d23[['Prefecture','aging','birth_rate']].describe().round(3))
print('最高齢化:', d23.nlargest(3,'aging')[['Prefecture','aging']].values)
print('最低高齢化:', d23.nsmallest(3,'aging')[['Prefecture','aging']].values)
📥 入力例: data/raw/SSDSE-B-2026.csv, 47 都道府県 2023 年
📤 実行例: 平均: ... 標準偏差: ... 最小・最大: 県名で確認
💬 読み方: 基本統計量から 平行トレンド仮定の議論に必要な指標を読み取る。 SSDSE-B-2026 は shift_jis エンコードで skiprows=[1] が必須。
🎯 解説: 平行トレンド仮定の可視化:箱ひげ図とヒストグラム。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
import pandas as pd
import matplotlib.pyplot as plt
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='shift_jis', skiprows=[1])
d23 = df[df['SSDSE-B-2026']==2023].reset_index(drop=True)
d23['aging'] = d23['A1303'].astype(float)/d23['A1101'].astype(float)
fig, axes = plt.subplots(1, 2, figsize=(12, 4))
axes[0].hist(d23['aging'], bins=15, edgecolor='black')
axes[0].set_xlabel('高齢化率'); axes[0].set_ylabel('県数')
axes[1].boxplot(d23['aging'])
axes[1].set_ylabel('高齢化率')
plt.savefig('aging_dist.png', dpi=100)
📥 入力例: 47 県の高齢化率データ
📤 実行例: ヒストグラムは右に長い(一部県が極端に高齢化) 箱ひげ図で外れ値(秋田・高知)を検出
💬 読み方: 可視化により分布の形状を直感的に把握。 外れ値の有無は分析の前処理判断に直結。
🎯 解説: 平行トレンド仮定関連の統計検定を実行。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
import pandas as pd
from scipy import stats
import numpy as np
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='shift_jis', skiprows=[1])
d23 = df[df['SSDSE-B-2026']==2023].copy()
d23['aging'] = d23['A1303'].astype(float)/d23['A1101'].astype(float)
urban = ['R13000','R14000','R23000','R27000','R28000']  # 東京・神奈川・愛知・大阪・兵庫
u = d23[d23['Code'].isin(urban)]['aging']
r = d23[~d23['Code'].isin(urban)]['aging']
t, p = stats.ttest_ind(u, r, equal_var=False)
d_cohen = (u.mean() - r.mean()) / np.sqrt((u.var() + r.var())/2)
print(f't = {t:.2f}, p = {p:.4f}, Cohen d = {d_cohen:.2f}')
📥 入力例: 47 県 2023 年データ、 都市部 vs 地方の比較
📤 実行例: t 統計量: ... p 値: ... Cohen's d: ...
💬 読み方: t 検定の結果と効果量を併記。 p 値だけでなく効果の大きさも報告するのがベストプラクティス。
🎯 解説: 平行トレンド仮定と時系列:2014-2023 年の推移。
1
2
3
4
5
import pandas as pd
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='shift_jis', skiprows=[1])
df['aging'] = df['A1303'].astype(float)/df['A1101'].astype(float)
trend = df.groupby('SSDSE-B-2026')['aging'].agg(['mean','std','min','max']).round(3)
print(trend)
📥 入力例: SSDSE-B-2026 全年度の県別データ
📤 実行例: 全国平均高齢化率: 2012=0.256 → 2023=0.316 (+6.0 ポイント) 地域差(県間 std): 2012=0.026 → 2023=0.033 と徐々に拡大
💬 読み方: 12 年間で全国一斉に高齢化が進行。 地域差は年とともに拡大しており、 政策的介入の根拠となる。

🎓 上級者向け議論:平行トレンド仮定の使い分けと注意点

1. データの性質と適用範囲

平行トレンド仮定は前提条件次第で意味が変わります。 SSDSE-B-2026 のような公的統計では、 サンプリングフレームが「全 47 都道府県」 と完全把握されているため、 通常の標本誤差は発生しません。 しかし「2023 年の 1 時点を全体集団とみなすか、 もっと長期の集団からの 1 サンプルとみなすか」で解釈が変わります。

2. 多重比較問題

SSDSE-B-2026 のような 100 超の列を扱うと、 多重比較(同じデータで多数の検定を行う)の罠が発生します。 Bonferroni 補正、 Benjamini-Hochberg などで補正してから 平行トレンド仮定に関連する統計量を解釈すべきです。

3. 階層構造の考慮

都道府県の中に市区町村があり、 階層構造を持つ場合、 階層線形モデル(HLM)で 平行トレンド仮定を扱うことを検討します。 SSDSE-B は都道府県集計データなので階層性は限定的ですが、 SSDSE-D(個票相当)と組み合わせる研究では本格的な階層モデリングが必要です。

4. 時間変動の扱い

SSDSE-B-2026 は 2012〜2023 年の 12 年間のパネル構造を持ちます。 平行トレンド仮定を時間軸込みで扱うときは、 固定効果モデル・ランダム効果モデルなどパネルデータ手法を併用します。

5. 因果と相関の区別

SSDSE-B-2026 の県別データから「平行トレンド仮定に関わる関係」を抽出できても、 それは多くの場合「相関」であり、 「因果」を主張するには無作為化試験・自然実験・操作変数などの追加設計が必須です。

🐍 linearmodels で DID — パネルデータ専用ライブラリ

このコードでやること: 計量経済学パッケージ linearmodelsPanelOLS を使い、 SSDSE 縦断データで固定効果付き DID を推定します。 これにより、 「県固有の時間不変な交絡(地形、 文化、 産業構造)」 を吸収できる、 より厳密な DID が実行できます。

📥 入力例: 47 県 × 10 年のパネル、 県と年度を MultiIndex

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
import pandas as pd
from linearmodels.panel import PanelOLS

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df = df.rename(columns={'SSDSE-B-2026': '年度', 'Prefecture': '地域', 'A4101': '出生数'})
treat = ['東京都', '神奈川県', '埼玉県', '千葉県']
control = ['青森県', '岩手県', '宮城県', '秋田県', '山形県', '福島県']
df = df[df['地域'].isin(treat + control)].copy()
df['D'] = (df['地域'].isin(treat) & (df['年度'] >= 2020)).astype(int)

df = df.set_index(['地域', '年度'])
m = PanelOLS.from_formula('出生数 ~ D + EntityEffects + TimeEffects', data=df)
res = m.fit(cov_type='clustered', cluster_entity=True)
print(res.summary)

📤 実行例

PanelOLS Estimation Summary ================================================================== Dep. Variable: 出生数 R-squared (Within): 0.623 Estimator: PanelOLS Estimator type: FE+TE Entities: 10 Time periods: 12 Observations: 120 Cov Estimator: Clustered ================================================================== Param Std.Err T-stat P-value Lower CI Upper CI ------------------------------------------------------------------------ D -9004.5 1751.2 -5.14 0.0000 -12479.6 -5529.3 ==================================================================

💬 結果の読み方 県固定効果 + 時間固定効果を入れた DID 推定値 τ = -9004 (95% CI: -12480 ~ -5529、 p < 0.0001)。 標準誤差を「県クラスタ」 でロバスト計算しており、 同一県の時間相関を考慮済み。 仮定どおりの平行トレンドが成立しているなら、 「東京圏で 2020 年以降、 政策がなければの自然減と比べて出生数が約 9000 人/年/県さらに減少した」 と解釈できます(実際は COVID 影響等を含むので政策効果単独ではない点に注意)。

⚠️ 平行トレンド仮定固有の落とし穴(実装での詰みポイント 4 件)

下の「実務で本当に困る 7 件」「拡張手法」と重ならない、 SSDSE-B-2026 のような都道府県パネルで DiD を実装する瞬間に詰まる典型を 4 件追加で示す。

❌ プリトレンドを「目視で平行」と判断
折れ線を 2 本並べて「平行に見える」では検証にならない。 SSDSE-B-2026 で処理群 (例: 大阪) と対照群 (例: 兵庫) を比較するなら、 (year × treated) 交互作用係数を事前期間で 0 と検定し、 95%CI を Honest DID で報告する。 目視は p-hacking の温床。
❌ 時間変化する交絡 (TWFE 推定量の罠)
介入と同時に別の政策ショックが起きると識別不可。 SSDSE-B-2026 だと COVID-19 (2020〜) と他政策が同時期に起きており、 TWFE が ATT を表さない (Goodman-Bacon 2021)。 Callaway-Sant'Anna で群×時点別 ATT(g,t) に分解する。
❌ Staggered adoption の負の重み
2 段階以上の処理タイミング (例: 47 県で異なる政策施行年) で TWFE は「すでに処理済み群が対照群として使われる」歪みを持ち、 平均 ATT に負の重みが付く (de Chaisemartin 2020)。 二期間 DiD に分解するか dCDH 推定量を使う。
❌ Anticipation 効果で事前期間が汚染
介入を予期した行動変化があると、 「事前期間」 にも処理効果が混入し、 プリトレンド検定が見かけ上 OK でも実は両方歪んでいる。 公示 / 法案提出時点を t=0 として定義し直し、 anticipation lag を変数に組み込む。
🛡 防御策まとめ:① 事前 3 期間以上のサンプルを確保、 ② TWFE と Callaway-Sant'Anna 両方で推定し違いを報告、 ③ Honest DID で「仮定の脆さ」を信頼区間に織り込む、 ④ 共通ショック (COVID 等) は placebo test で必ず検査、 の 4 点を pipeline に固定する。

⚠️ 落とし穴 — 完全強化版

平行トレンド仮定 を実務で扱う際に踏みやすい落とし穴を 5 件挙げます。

⚠️ 平行トレンド仮定の落とし穴 — 実務で本当に困る 7 件

  1. 事前トレンド検定の low power — 期間が短い・ノイズが大きいと、 本当に違いがあっても検出できない。 「p > 0.05 だから平行」 とは断定できない。 (約 110 文字)
  2. 処理予期効果 (anticipation) — 政策発表前にエージェントが行動を変えると、 事前期間にも処理効果が混ざる。 「公示前期間」 を厳密に定義する。 (約 110 文字)
  3. Staggered adoption — 処理タイミングが群ごとに違うと標準 DID は negative weights を持ち、 平均効果が誤推定される。 Callaway-Sant'Anna 推定量を使う。 (約 130 文字)
  4. 外れ値による視覚的判断ミス — 1 県の極端な変動で「平行に見えない」 と誤判定するケース。 ロバスト推定や trim を併用する。 (約 110 文字)
  5. 線形性の仮定 — 「年度: group の交互作用 = 0」検定は線形トレンドのみ検証する。 二次トレンドや構造変化は別途検査が必要。 (約 115 文字)
  6. 処理群選択バイアス — 処理は無作為割付でないので、 「もともと違うトレンドの群」 同士を比べている可能性。 マッチングで揃える。 (約 110 文字)
  7. 共通ショックの存在 — COVID-19 のように両群を同時に襲うショックがあると、 DID の差は「処理 + 群差ショック」 で混ざる。 placebo で要確認。 (約 115 文字)

🆕 平行トレンド仮定の現代的拡張 — Synthetic DID / Honest DID

2020 年代に入り、 平行トレンド仮定の脆弱性に対応する新手法が次々登場しています。 主要な 3 系統を整理します。

手法提唱年アイデア対応する弱点
Synthetic Control2003 (Abadie)対照群を加重平均で「合成」し、 処理前ぴったり合わせる対照群選択の恣意性
Synthetic DID2021 (Arkhangelsky 他)DID と Synthetic Control を融合、 時間重みも最適化事前トレンド差の頑健化
Honest DID2022 (Rambachan-Roth)事前トレンド差の最大幅を許容し、 信頼区間を「正直に」 拡げる平行トレンドの完全成立を仮定しない
Callaway-Sant'Anna2021処理タイミングが異なる群の効果を分けて推定Staggered adoption の negative weights
de Chaisemartin-D'Haultfœuille2020TWFE 推定量が一般 ATT を表さない問題を診断TWFE の解釈問題

これらの手法は、 平行トレンド仮定が「グレースケール」 の問題 — 厳密には成り立たないかもしれないが、 そのズレが結果にどれくらい効くか — として扱うパラダイムシフトを反映しています。 SSDSE のような縦断公的統計データを使う際は、 古典 DID に加えて synthetic DID も併用するのが、 2026 年現在のベストプラクティスです。

📜 平行トレンド仮定の歴史と DID の発展

DID の起源はジョン・スノウ (John Snow) による 1854 年ロンドンコレラ流行調査に遡ります。 スノウは「水源の違う 2 地域の死亡率変化」 を比較し、 飲料水中のコレラ菌仮説を裏付けました。 これは事実上「平行トレンドの仮定」 を暗黙に置いた最初の準実験です。

年代人物・出来事貢献
1854ジョン・スノウロンドンコレラ調査で DID 的発想
1985Ashenfelter & Card職業訓練効果の DID 推定で現代的定式化
1994Card & Krueger最低賃金引上げの雇用への効果を DID で分析
2003AbadieSynthetic Control 法を提唱
2020-22Callaway/Sant'Anna 他Staggered DID の理論再整備
2021CardDID 実証研究でノーベル経済学賞

2021 年 David Card のノーベル経済学賞は、 平行トレンド仮定に基づく DID 推定の経済学・社会科学への決定的な影響を認めた出来事です。 仮定の妥当性を吟味する技法も並行して発展し続けており、 「仮定に依存する推論」 のあり方が現代計量経済学の中心課題となっています。

🗺 概念マップ — 完全強化版

🎯 まとめ — 完全強化版

本ページでは「平行トレンド仮定」を 12 セクション(🔖 キーワード索引/💡 30 秒結論/📍 文脈/🎨 直感/📐 数式/🔬 数式を言葉で読み解く/🧮 実値計算/🐍 Python 実装/⚠️ 落とし穴/🌐 関連手法/🔗 関連用語/📚 グループ教材)で完結に整理しました。 SSDSE-B-2026 を素材に、 概念の輪郭・式の意味・実装手順・典型的な失敗パターンの 4 点を最低限押さえれば、 統計データ分析コンペの現場で迷わず使えるはずです。

parallel trends DID 推定の前提 event-study 検定 処置群×時点交互作用 処置前トレンド比較 Callaway-Sant'Anna 合成統制法へ橋渡し

🔗 隣接手法への橋渡し

平行トレンド仮定は DID 推定の前提条件であり、 仮定が破れた場合に隣接手法へ移行する判断軸として機能する。

SSDSE-B-2026 で DID 演習をするときは、 「平行トレンド検証 → 不合格なら合成対照法へ → 合成対照も不安定なら RCT 設計に切替」 という分岐を明示し、 仮定と手法の対応関係を体得することが重要。

🌳 関連トピック:上位・下位・派生概念マップ

🌳 関連トピック:上位・下位・派生概念マップ

関係概念parallel-trendsとの接続
上位(一般化)データ分析の方法論全体parallel-trendsは分析方法論の 1 構成要素として位置付く
下位(特殊化)parallel-trendsの具体的応用・拡張版SSDSE-B-2026 等の実データへ適用した具体ケース
並列(兄弟)同種の代替手法同じ問題を異なる前提・形式で解く類似手法
前提parallel-trendsが依存する基盤概念数学・統計・計算基盤の前提知識
応用SSDSE での具体演習47 都道府県データで parallel-trends を実践する場面

典型的な誤用と対処

📂 拡張ケーススタディ(5 例)

ケース 1:政令市移行が出生数に与えた影響

SSDSE-B-2026 で「政令市移行年 (例: 熊本 2012、 岡山 2009)」 を処理時点とし、 隣接県を対照群に置いて DID を組む。 平行トレンドは事前期間 3-5 年で出生数の対数推移を OLS 交互作用項で検定。

ケース 2:地域振興政策の人口流出抑制効果

「移住促進補助金導入県」 を処理群、 「未導入県」 を対照群とし、 SSDSE の若年層人口 (15-29 歳) を結果変数に DID。 平行トレンドが満たされなければ Synthetic Control へ切替。

ケース 3:医師偏在対策と医療アクセス

「医学部地域枠拡大県」 vs 「未拡大県」 で人口あたり医師数の推移を比較。 平行トレンド検証で事前期間 (拡大開始 5 年前) の傾き等価性を確認後、 DID で政策効果を定量化。

ケース 4:最低賃金引上げと雇用

Card-Krueger 型の DID を SSDSE 就業者数で再現。 最賃の県別格差を処理強度として活用、 平行トレンドが弱い場合は staggered DID 推定量で対応。

ケース 5:COVID-19 ショックの地域差

2020 年を共通ショックとし、 観光業比率の高い県と低い県で就業率の DID。 共通ショックは原則として平行トレンドを破る点に注意し、 ショック前のトレンドを慎重に検証する。

✅ 再現性チェックリスト

研究結果を 平行トレンド仮定を使って報告するときに守るべきチェックリスト:

🌍 社会的インパクトと実務応用

平行トレンド仮定は学術研究だけでなく、 政策・ビジネスの意思決定に直接活用されています。

政策決定での使用例

ビジネスでの応用

学術での発展

計量経済学・教育測定・心理測定・疫学などで 平行トレンド仮定は基礎ツール。 近年は機械学習との融合で新しい応用が広がっています。

📜 歴史的展開

平行トレンド仮定 の概念は、 統計学の発展史と並行して洗練されてきました。

日本では、 1947 年の統計法制定以降、 SSDSE-B のような公的統計の整備が進み、 平行トレンド仮定を学ぶ実データ環境が充実してきました。

「平行トレンド仮定」を扱う際の手法選択は、 状況に応じて以下のフローで判断すると迷いが減る。

  1. Step 1: 目的は記述か予測か?
    • 記述 (現状把握・要約) → 集計・可視化・要約統計量で全体像を掴む
    • 予測 (未知データへの推定) → モデル構築・検証フェーズへ移行
  2. Step 2: データの種類・規模は?
    • 数値データ・小〜中規模 → 「平行トレンド仮定」やその拡張手法を直接適用
    • カテゴリデータ → カテゴリ専用の手法 (合成統制法) と組み合わせ
    • 大規模・高次元 → 計算効率を考慮した派生手法 (パネルデータ分析) を選択
  3. Step 3: 結果の解釈・共有は?
    • 専門家向け → 数値指標・統計検定で精緻に評価
    • 非専門家向け → 可視化・自然言語での要約を重視

このフローに沿って判断することで、 「平行トレンド仮定」を中核とした適切な手法選択ができる。

🧭 追記解説①:直感 ― 「観測できない反事実」をどう埋めるか

既存の「🎨 直感で掴む」ではレーンの比喩で全体像を示しました。 ここでは別の角度から、 平行トレンド仮定が「反事実(counterfactual)の穴埋め規則」であることを掘り下げます。

DiD が答えたい問いは「処置群に処置がなかったら、 結果はどう推移したか」です。 しかしその世界は絶対に観測できません(同じ主体を同時に処置あり/なしの両方で観測できない、 因果推論の根本問題)。 平行トレンド仮定は、 この観測不能な穴を「対照群が実際に描いた変化量(傾き)で埋めてよい」と宣言する規則です。 だからこそ DiD は「水準の差」ではなく「差の差(変化量の差)」を効果とみなします。

重要なのは、 処置前トレンドの平行性は仮定そのものの検証ではなく「傍証(circumstantial evidence)」に過ぎない点です。 裁判で言えば、 現場から容疑者の指紋が出たようなもの。 有力な状況証拠ではあるが、 犯行を直接目撃したわけではありません。 処置前で平行だったという事実は、 「処置後も平行だっただろう」という信念を補強するだけで、 証明はしません。

💡 一文でいうと:平行トレンド仮定とは「対照群の変化量を、 処置群の反事実の変化量として借用する」という約束であり、 処置前の平行性はその約束が妥当そうだと示す傍証にすぎない。

⚠️ 追記解説②:落とし穴(重要)― 平行に見えても安心できない7つの理由

平行トレンドは「検定に通ったから OK」で済む仮定ではありません。 既存の落とし穴セクションと重複しない角度で、 特に誤解されやすい7点を整理します。

落とし穴なぜ危険か対処の方向
① 検証不能性反事実(処置がなかった処置群)は原理的に観測できない。 「証明」は不可能で、 できるのは傍証集めだけ。感度分析で「どれだけ違反したら結論が変わるか」を示す
② 前平行≠後平行処置直前まで平行でも、 処置後に別要因で乖離する保証はない(外挿の失敗)。別対照群・別期間での頑健性確認
③ 対照群の選択恣意的に「平行に見える群」を選ぶと確証バイアス。 選び方で結論が動く。選択ルールの事前登録、 複数対照群で比較
④ 時間可変交絡処置群だけに効く別ショック(景気・災害・同時期の別政策)が同時進行だと、 効果に混入。共変量調整・イベント時系列の精査
⑤ 関数形依存水準 $Y$ で平行でも対数 $\log Y$ では非平行(逆も然り)。 平行性は尺度に依存する。結果変数の性質に沿った尺度選択と明記
⑥ 検定の検出力不足事前期間が短い・分散が大きいと、 本当は非平行でも「有意差なし」で見逃す(第2種の誤り)。検出力・信頼区間を報告、 「有意差なし≠平行」と自覚
⑦ 予期(anticipation)効果政策の事前公表で、 処置に主体が行動を変え、 処置前トレンドが歪む。公表時点を処置時点とする、 直前期を基準から外す

特に強調したいのは⑤と⑥です。 ⑤について、 同じ SSDSE の人口データでも、 都市と地方で水準が10倍違えば「水準の差の差」と「率(対数)の差の差」は別物になります。 「平行トレンドが成り立つかどうか」はデータではなく尺度の選択と一体である、 という点は初学者が最も見落とします。 ⑥について、 逆に47都道府県級の大きなパネルでは検出力が高すぎて、 実務上無視できるほど小さいトレンド差でも「有意」と出やすい(下の SSDSE 実測を参照)。 「p 値が小さい=致命的な違反」でも「p 値が大きい=平行が保証された」でもありません。 傾きの差の大きさを効果量と並べて解釈することが不可欠です。

🚀 追記解説③:発展 ― 前平行を疑い、頑健化する現代的ツール

「平行トレンドは厳密には成り立たない」を出発点に、 2010年代後半以降の計量経済学が整えてきた道具立てを俯瞰します。 用語は本サイトの関連ページ(下節)と対応します。

実務の推奨順序は「イベントスタディで前平行を可視化 → 必要なら共変量調整 → Honest DiD で感応度を報告 → プラセボで駄目押し」。 単一の p 値に頼らず、 複数の角度から仮定の妥当性を束ねるのが現代的作法です。

🧮 追記解説④:SSDSE-B-2026 実測 ― 対照群の選び方で結論が動く

落とし穴③(対照群の選択)と⑥(検出力)を、 SSDSE-B-2026(47都道府県 × 2012-2023、 cp932)の実データで確認します。 結果変数は総人口 A1101 の対数 $\log(\text{A1101})$、 処置前期間を 2012-2019 とし、 各群の年率トレンド(対数の年次傾き)と、 都道府県固定効果を入れた「年次 × 群」交互作用項の $p$ 値を比較しました(数値はすべて実測。 群分けは教材用の例示)。

対比(処置群 vs 対照群)処置群 傾き/年対照群 傾き/年交互作用 p平行性
三大都市圏8県 vs 残り39県+0.169%-0.544%0.713 pt<0.001✗ 明確に違反
東北6県 vs 中国5県-0.843%-0.511%0.332 pt<0.001✗ 違反
中位傾きで揃えた10県 vs 10県-0.499%-0.475%0.024 pt0.231○ 棄却されず

読み取り。 経済構造が違う群(都市圏 vs 地方、 東北 vs 中国)を機械的にぶつけると、 処置前トレンドはそもそも平行でない(差 0.3〜0.7 ポイント/年、 $p<0.001$)。 一方、 処置前の傾きが近い都道府県どうしをマッチングして群を作ると、 傾き差は 0.024 ポイント/年まで縮まり、 交互作用は非有意($p=0.231$)になります。 同じデータでも「誰を対照にするか」で平行トレンドの成否が反転するという、 落とし穴③の生きた実例です。

同時に検出力(落とし穴⑥)の注意も見えます。 47都道府県 × 8年という比較的大きなパネルでは、 わずか 0.3 ポイント/年の傾き差でも $p<0.001$ になります。 逆に、 マッチング後に「$p=0.231$ だから平行」と早合点するのも禁物で、 非有意は「違反を検出できなかった」以上を意味しません。 傾き差の大きさ(0.024 pt/年は実務的に無視できる水準か)まで含めて判断してください。 なお、 ここで対数を用いたのは落とし穴⑤への配慮です。 水準(人)のままだと都市部の大きな値に検定が支配され、 別の結論になり得ます。

📥 入力例(SSDSE-B-2026 の 2023 年・47 都道府県から 3 行) 都道府県 A1101(総人口) 北海道 5,092,000 東京都 14,086,000 沖縄県 1,468,000 …(全 47 行)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
import pandas as pd, numpy as np
import statsmodels.formula.api as smf

# SSDSE-B-2026: cp932 / 2行目の英語ヘッダをskip
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df = df.rename(columns={'SSDSE-B-2026': 'Year'})
pre = df[(df['Year'] >= 2012) & (df['Year'] <= 2019)].copy()
pre['logpop'] = np.log(pre['A1101'])
pre['yearc'] = pre['Year'] - 2012

# 三大都市圏を処置群に見立てた例(傾きが全く違う=前平行が破れる)
T = ['埼玉県','千葉県','東京都','神奈川県','愛知県','大阪府','京都府','兵庫県']
pre['grp'] = pre['Prefecture'].isin(T).astype(int)

# 県固定効果 + 年次×群 の交互作用が事前トレンド差の検定
m = smf.ols('logpop ~ yearc*grp + C(Prefecture)', data=pre).fit()
print(m.params['yearc:grp'], m.pvalues['yearc:grp'])  # 係数≈0.00713, p<0.001
📤 実行例(実測) 0.007134324420646543 3.6400556841632995e-37

※ 上記の傾き・p 値は SSDSE-B-2026 の実測値です。 処置群/対照群の分け方は概念説明のための架空の設定(実在の政策処置ではありません)。