このページの主要な見どころ。 気になる項目から読み始めてください。
同時性 (simultaneity) は、 説明変数 X と応答変数 Y が互いに同時に決まる状況。 通常の回帰では係数が偏る。
論文・実務レポート・公的統計の解説で、 こんな場面に出会ったはずです。
同時性とは「X が Y を決め、 Y も X を決める」双方向の連立的因果のこと。 普通の回帰式 $y = \beta x + \varepsilon$ では、 $x$ が $\varepsilon$ と相関してしまい 係数 β の OLS 推定量は偏る。 これを「内生性 (endogeneity)」と呼びます。
古典的な例は 需要と供給。 ある商品の月別データを集めて「価格 → 需要量」の回帰をやっても、 そこに現れる「価格の係数」は需要曲線の傾きではありません。 なぜか?
市場では、 価格と需要量は同じ瞬間に同時に決まっています。 需要が増えれば価格が上がり、 価格が上がれば需要が減る。 だからデータの (価格, 需要) 点は「需要曲線」でも「供給曲線」でもなく、両者の交点の動きです。 単純に回帰すれば、 需要曲線と供給曲線の混ざりものを推定してしまいます。
SSDSE-B 都道府県データでも、 たとえば「賃金水準 ↔ 県外への転出率」「教育費 ↔ 学力」など、 互いに引っ張り合う変数組はたくさんあります。 「相関を見たから因果」と短絡してはいけない、 という警告灯がこの概念です。
同時性が疑われる場合、 まずは 「どちら向きにも因果が走り得ないか」 を理論的に吟味し、 OLS を補正する道具(IV・2SLS)に進むのが定石です。 「とりあえず回帰」では足りないのが、 因果推論の難しさです。
需要・供給の最小モデル:
均衡条件から $P$ と $Q$ を解くと、 どちらも $u_1, u_2$ の関数。 つまり $\mathrm{Cov}(P, u_1) \ne 0$ で OLS は偏る。
操作変数 $Z$(供給側だけに作用、 例: 原材料費)を使うと、 2 段階最小二乗法 (2SLS) で:
$Z$ が $u_1$ と無相関で $P$ と十分相関していれば、 $\hat{\alpha}_1^{\text{2SLS}}$ は需要曲線の傾きを一致推定します。
2 段階の流れ:
1) 第一段階:$P_i = \pi_0 + \pi_1 Z_i + v_i$ で $\hat{P}_i$ を作る
2) 第二段階:$Q_i = \alpha_0 + \alpha_1 \hat{P}_i + e_i$ を OLS で推定
| 記号 | 意味 | 需要・供給の例 |
|---|---|---|
| $Q^d$ | 需要量 | その月に売れた商品個数 |
| $Q^s$ | 供給量 | その月に出荷された個数 |
| $P$ | 価格(内生変数) | 市場価格 |
| $u_1, u_2$ | 誤差項(需要ショック・供給ショック) | 気候・流行・原材料の変動 |
| $\alpha_1$ | 需要の価格弾力性(推定したい) | 普通は負 |
| $\beta_1$ | 供給の価格弾力性 | 普通は正 |
| $Z$ | 操作変数 | 原材料費・天候など供給側だけに効く外生変数 |
同時性の正体は「説明変数が誤差項と相関する」こと。 操作変数 $Z$ はその相関を「外生的に揺らせる部分」だけ取り出す装置です。
SSDSE-B 文脈で言えば、 たとえば「気候」は宿泊者数・観光業に効くが、 高齢化率に直接効くわけではないので、 観光振興 → 経済 → 移住の連鎖を見るときの IV 候補になり得ます。
SSDSE-B 2023 で、 同時性が疑われる例として「人口流入 ↔ 出生率」を考えます。 「若い人が流入する県は出生率が上がる」と同時に「出生率が高い県は子育て世代を引き寄せる」両方向の因果が想定できます。
| 変数 | 定義 | 2023 年 平均 | 標準偏差 |
|---|---|---|---|
| 転入超過率 | (転入 − 転出) / 総人口 × 1000 | −1.85 | 3.04 |
| 高齢化率 | 65 歳以上 / 総人口 × 100 | 31.59 % | 3.34 |
| 出生率 | 出生数 / 総人口 × 1000 | 6.15 | 0.88 |
| 合計特殊出生率 | 女性 1 人あたり出生児数 | 1.29 | 0.13 |
転入超過率と出生率の相関は r = +0.61。 しかしこれは「転入が多いから出生が増える」のか「出生が多いから移住先として選ばれる」のか、 単純な回帰では切り分けられません。 操作変数(地理的距離・気候など外生要因)の導入が検討すべき方向です。
| モデル | 転入超過率の係数 β̂ | 解釈 |
|---|---|---|
| OLS(単純回帰) | 0.18 | 同時性バイアスを含む可能性大 |
| 2SLS(高齢化率を IV と仮置き) | 異なる値になる | 外生性が満たされる前提でのみ意味 |
「OLS と IV で係数が大きく違う」=「同時性・内生性がありそう」のシグナル(Hausman 検定の定性的解釈)。 実務では理論で IV を慎重に選ぶ必要があります。
SSDSE-B 2023 を読み込み、 同時性が疑われる変数組を確認:
import pandas as pd
# SSDSE-B-2026 を読み込み(年度別 47 都道府県、 最新は 2023 年)
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='shift_jis', skiprows=1)
df.columns = [c.strip() for c in df.columns]
df = df[df['年度'] == 2023].reset_index(drop=True)
print(df.shape) # (47, 112)
print(df['都道府県'].nunique()) # 47
print(df.iloc[:3, :5])
変数構築と相関行列:
df['転入超過率'] = (df['転入者数(日本人移動者)'] - df['転出者数(日本人移動者)']) / df['総人口'] * 1000 df['出生率'] = df['出生数'] / df['総人口'] * 1000 df['高齢化率'] = df['65歳以上人口'] / df['総人口'] * 100 print(df[['転入超過率', '出生率', '合計特殊出生率', '高齢化率']].corr().round(3))
素朴な OLS — このとき係数は同時性バイアスを含む:
import statsmodels.api as sm y = df['出生率'] X = sm.add_constant(df['転入超過率']) ols = sm.OLS(y, X).fit() print(ols.summary()) # 係数は「両方向の効果が混ざった」値になりやすい
操作変数法による推定(linearmodels が必要):
# pip install linearmodels
from linearmodels.iv import IV2SLS
# 仮の操作変数:高齢化率を「転入超過率に効くが、出生率に直接は効きにくい」と仮定
# 実務では除外制約を理論で正当化する必要がある
data = df[['出生率', '転入超過率', '高齢化率', '合計特殊出生率']].dropna()
mod = IV2SLS.from_formula(
'出生率 ~ 1 + [転入超過率 ~ 高齢化率] + 合計特殊出生率',
data=data
)
res = mod.fit()
print(res.summary)
# OLS と IV で係数がどれだけ違うかを見るHausman 検定で「同時性が実際にあるか」を確認:
print('Hausman test (内生性検定):')
print(res.wu_hausman())
# p < 0.05 なら OLS は不一致 → IV を使うべき
# p >= 0.05 なら OLS のままで良いが、 統計的決定だけに頼らず理論も併用