「fixed effects」は統計データ分析の文脈で扱う重要概念のひとつ。 本ページでは「fixed effects」を取り巻く中核キーワードを以下にチップで一覧化する。 各キーワードは関連する概念・手法・道具立てを含み、 文献検索や学習計画の起点になる。
これらのキーワードは「fixed effects の理解 → 適用 → 検証」のプロセスを構成する。 各章で詳しく解説する。
🍰 まずはやさしく
個人のクセを無視する仕組みです。
正しく原因と結果を知るために使います。
部活で人による能力の差をなくす例です。
この手法で何ができるかを紹介します。
fixed effects を 30 秒で把握する重要ポイント:
🍰 まずはやさしく
分析でよく使われる重要な道具です。
データの偏りをなくすために使います。
都道府県のデータ分析で役立ちます。
定義から使い方まで順番に解説します。
論文中に 「固定効果モデル」として登場する用語。
固定効果モデル とは:個体ごとの「観察できない固有の差」を吸収する変数を入れたパネルモデル。時間不変の交絡を完全に除去。
本ページでは「fixed effects」を扱う。 統計データ分析コンペティション (2026) の教材で、 SSDSE-B-2026 (47 都道府県 × 複数年 × 100 超列) の実データを使った再現可能な学習を目指す。
「fixed effects」は統計・データサイエンスの体系における重要概念のひとつ。 本ページは「定義・直感・数式・実装・落とし穴・関連手法」の 6 視点で構成され、 各視点は独立して読めるが順序通り読むと体系的な理解が得られる。
🍰 まずはやさしく
個人のもともとの差を消すイメージです。
純粋な変化だけを見るために使います。
身長の絶対値ではなく伸び方を見る例です。
図を使って直感的に仕組みを説明します。
固定効果 (Fixed Effects, FE) モデルは、 SSDSE-B-2026 の 都道府県ごとに自前のダミー変数 を 1 本ずつ追加するイメージです(最大 46 本)。 これにより「東京の出生率がもとから低い理由」のような 時間を通じて変わらない地域特性 を完全に吸収できます。 残った変動は 各都道府県内の年次変化 のみ — つまり「同じ都道府県内で年が進むと $x$ が変化したとき、 $y$ も変化したか」を見ています。
比喩で言うなら、 各人の身長を年齢の関数で表現するときに「身長の絶対値の差(個人差)」を一旦消して、 各人の身長の伸びだけで議論する のと同じ発想。 個体差という最大の交絡をエレガントに退治できるので、 観察研究で因果に最も近づける推定量の一つとして広く使われます。
固定効果モデルは「個体ごとに異なる切片(観測されない時間不変の特性)」を吸収することで、 時間内変動だけから因果効果を推定する。 ここでは「プール OLS との違い」「within 変換」「県固有切片の意味」を概念図で視覚化する。
4 つの個体(グループ)からなるパネルデータを散布図に色分け表示しています。 各個体の中では傾き +0.80 の同じ正の関係がありますが、 個体ごとに切片(=観測されない時間不変の個体固有効果 αi)が異なります。 スライダーで個体効果の強さ kを上げると、 個体間の切片差が説明変数 x と相関して交絡を生み、 全体をプールした OLS(黒破線)の傾きが真値からずれ、 やがて符号まで反転します。 「表示切替」ボタンで within 変換(各個体の平均を引く)後の図に切り替えると、 個体固有効果が消去され真の個体内効果 +0.80 が復元される様子が体感できます。
図を左右にドラッグ(スマホはタッチ)しても k を変えられます。 左端=交絡なし、右端=交絡最大。
固定効果は「観測されない時間不変の個体差」をまるごと吸収する仕組みです。 各個体の平均を引く within 変換を行うと、 個体ごとに固定された切片 αi はその個体の平均に完全に含まれるため差し引きゼロになります。 残るのは「同じ個体の中で x が動いたとき y がどう動いたか」という個体内の変動だけ。 上の図で k をいくら上げても within の傾きが +0.80 のまま揺らがないのは、 個体固有効果がどれほど強い交絡を生んでも、 平均差分によって機械的に除去されるからです。
🍰 まずはやさしく
数式で表した分析のルールです。
計算で個人のクセを取り除くために使います。
ある県の中で年ごとにどう変わったかを見ます。
具体的な計算方法と数式を学びます。
推定は within 変換(個体平均を引く)で行います:
$$ y_{it} - \bar{y}_i = (\boldsymbol{x}_{it} - \bar{\boldsymbol{x}}_i)^{\top}\boldsymbol{\beta} + (\varepsilon_{it} - \bar{\varepsilon}_i) $$これで $\alpha_i$ は綺麗に消える($\bar{\alpha}_i = \alpha_i$ なので差し引きゼロ)。 SSDSE-B-2026 で「東京の婚姻率が高い年と低い年で、 出生率がどう動いたか」だけを使って $\beta$ を推定するのが FE の本質です。
| 記号 | 意味 | SSDSE-B-2026 解釈 |
|---|---|---|
| $\alpha_i$ | 個体固定効果(定数として扱う) | 「東京は東京、 沖縄は沖縄」という時間不変の地域特性 |
| $\bar{y}_i$ | 個体 $i$ の被説明変数の時間平均 | 東京の出生率の年平均 |
| $y_{it} - \bar{y}_i$ | 個体内偏差(within 変動) | 東京の今年の出生率と東京の平均との差 |
| $\boldsymbol{\beta}$ | 時間内(within)係数 | 「同じ都道府県内で $x$ が動くと $y$ がいくら動くか」 |
FE は時間不変な変数(地域固定の制度、 緯度、 海岸線など)の係数は推定できない(withinゼロになる)点に注意。 そういうときは RE か Mundlak 型を検討します。
固定効果(Fixed Effects, FE)は、 パネルデータで「個体(県・企業・人)ごとに観測されない時間不変の特性」をダミー変数として吸収する手法です。 同一個体内の時間方向の変動だけを使って係数を推定するため、 個体固有の交絡因子(県の地形・気候、 企業の経営方針、 個人の性格など)に強い識別が可能になります。 観測値 y_it = α_i + βX_it + u_it の α_i を消去(within 変換または LSDV)するのが核です。
SSDSE-B-2026 (47 都道府県 × 12 年、 2012-2023) のように同じ個体を複数時点で観測するパネルでは、 OLS は県間の異質性で交絡を起こします。 固定効果はそれを構造的に除去します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | # ── この抜粋で使うデータを用意します(SSDSE-B の 47 都道府県・最新年度)── import pandas as pd df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', header=1) df = df[df['地域コード'].astype(str).str.match(r'^R\d{5}$', na=False)].copy() df['年度'] = pd.to_numeric(df['年度'], errors='coerce') df = df[df['年度'] == df['年度'].max()] for _c in df.columns[3:]: df[_c] = pd.to_numeric(df[_c], errors='coerce') df['高齢化率'] = df['65歳以上人口'] / df['総人口'] * 100 # 見本でよく使われる仮の列名を、実データから作っておく df['income'] = df['消費支出(二人以上の世帯)'] df['population'] = df['総人口'] _region = {'北海道': '北海道', '青森県': '東北', '岩手県': '東北', '宮城県': '東北', '秋田県': '東北', '山形県': '東北', '福島県': '東北', '茨城県': '関東', '栃木県': '関東', '群馬県': '関東', '埼玉県': '関東', '千葉県': '関東', '東京都': '関東', '神奈川県': '関東'} df['region'] = df['都道府県'].map(_region).fillna('その他') df['地域'] = df['region'] import pandas as pd import numpy as np from scipy import stats import matplotlib.pyplot as plt # SSDSE データの読み込み # 基本統計 df.describe() df.info() # 可視化 df.hist(bins=30, figsize=(15, 10)) plt.show() |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | # 基本パターン import pandas as pd import numpy as np from scipy import stats import matplotlib.pyplot as plt import seaborn as sns # データ読み込み df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', header=1) # 基本統計量 df.describe() # 可視化 sns.pairplot(df[['食料費(二人以上の世帯)', '教育費(二人以上の世帯)', '住居費(二人以上の世帯)']]) plt.show() |
このページの上にある3つの概念マップ(関係マップ、 包含マップ、 ツリーマップ)でこの概念の位置づけが視覚的に分かります。 固定効果モデルは within 推定量・LSDV・差分の差分(DID)・操作変数法(IV)・Hausman 検定・クラスタ標準誤差・Mundlak 装置といった関連概念と直接結びつき、 時間不変な交絡をコントロールしたい場面の起点となる手法です。
| 機能 | Python (linearmodels/statsmodels) | 補足 |
|---|---|---|
| FE 推定 | PanelOLS(y, X, entity_effects=True).fit() | within 推定量、 個体内変動のみ利用 |
| 2-way FE | PanelOLS(y, X, entity_effects=True, time_effects=True).fit() | 県+年の両方で吸収 |
| クラスタ SE | .fit(cov_type='clustered', cluster_entity=True) | パネルでは原則必須 (Cameron & Miller 2015) |
| Hausman 検定 | compare(re_result, fe_result) | χ² で FE vs RE 選択 |
| LSDV (ダミー回帰) | smf.ols('y ~ x + C(entity)', data=df).fit() | FE と数値一致、 county FE 多数で重い |
| RE 推定 | RandomEffects(y, X).fit() | GLS、 E[α_i|X]=0 が前提 |
| DID | smf.ols('y ~ treated*post + C(entity) + C(time)', data=df).fit() | 2-way FE と等価 |
| 動学パネル | linearmodels.IVGMM / Arellano-Bond | y_{t-1} を入れる場合 Nickell バイアスを GMM で修正 |
固定効果モデルは 3 つの軸で位置づけられます: (1) パネルデータ手法として RE/Mixed Effects と並列、 (2) 因果推論手法として DID/IV と並列 (実は 2-way FE = DID)、 (3) 時間不変な交絡をコントロールする道具として propensity score / matching と相補的。
| グループ | 主要概念 |
|---|---|
| パネル推定量 | FE (within), RE, Pooled OLS, Between, First-Difference |
| FE vs RE 判定 | Hausman 検定, Mundlak 装置, Hausman-Taylor |
| DID 関連 | 2-way FE, parallel trends, event study, TWFE bias (Goodman-Bacon) |
| 動学パネル | Arellano-Bond, System GMM, Nickell bias, IV |
| 標準誤差 | クラスタ SE, 2-way clustering, Driscoll-Kraay, ブロックブートストラップ |
| 階層モデル | Mixed Effects, Random Slope, ICC, BLUP |
| 時間 FE | 年ダミー, 半期ダミー, week-of-year, trend |
| 不均衡パネル | attrition, missing-at-random, Heckman 補正 |
| 識別戦略 | DID, RDD, IV, synthetic control, matching |
| パッケージ | linearmodels.PanelOLS, statsmodels, plm (R), reghdfe (Stata) |
| 診断 | Wooldridge AR(1) test, Pesaran CD test, BP-LM test |
| 頑健性 | drop1, leave-one-out, placebo test, alternative cluster |
SSDSE-B-2026 は 47都道府県 × 複数年度(2012-2023)のパネルデータ。 これは固定効果モデルの典型的なテストケースです。 「人口あたり医療費」を「人口あたり病院数」で予測する例で実演します。
1 2 3 4 5 6 7 | import pandas as pd import numpy as np df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) # パネル化:都道府県 × 年度 panel = df[['SSDSE-B-2026', 'Prefecture', 'A1101', 'I510120']].copy() panel.columns = ['year', 'pref', 'pop', 'hospitals'] print(panel.shape, panel['year'].unique()) # (564, 4) [2012..2023] |
| 手法 | 推定式 | 病院数の係数(仮想例) | 解釈 |
|---|---|---|---|
| プールド OLS | $y_{it}=\alpha+\beta x_{it}+\epsilon$ | +0.85 *** | 県固有性無視(過大評価のおそれ) |
| 県FE(Within) | $y_{it}=\alpha_i+\beta x_{it}+\epsilon$ | +0.22 * | 「同じ県の中で病院が増えると医療費がどう変わるか」 |
| 県+年FE(Two-way) | $y_{it}=\alpha_i+\gamma_t+\beta x_{it}+\epsilon$ | +0.18 * | 時間共通ショック(コロナ等)も除去 |
💡 得られる洞察:プールド OLS では「病院が多い県は医療費が高い」という県間の差に引きずられて係数が大きく出ますが、 FE で県固有要因を除くと、 「同じ県の中で病院が増えても医療費は思ったほど増えない」という別の現実が見えます。
パネル分析では「同じ県の年度間で誤差が相関」しているため、 通常の標準誤差は過小評価。 必ず cluster='pref' でクラスタ頑健標準誤差を使うこと。
都道府県 × 年度のパネルで出生率(人口千対、 A4101÷A1101×1000)を被説明変数とし、 高齢化率と消費支出(L3221)を説明変数として固定効果モデルを推定します(SSDSE-B-2026 には「県民所得」「完全失業率」の列が無いため、 実在列から導出できる変数を使います)。 OLS(プールド)・ LSDV・ within 変換の 3 通りで係数が一致することを実データで確かめましょう。
LSDV(最小二乗ダミー変数法)と within 変換が同じ係数を返すことを SSDSE-B-2026 で確認する。
SSDSE-B-2026 の都道府県 × 年度パネル。 説明変数は Aging_rate(高齢化率、 A1303÷A1101×100) ・ L3221(消費支出)。
OLS / LSDV / within の係数表、 標準誤差、 R^2。
プールド OLS は県固有事情を見逃すため係数が歪む。 LSDV は県ダミーを 46 個入れる愚直法、 within は各列から県平均を引く高速法。 結果は同じになる(Frisch-Waugh-Lovell の定理)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | import pandas as pd import numpy as np import statsmodels.api as sm 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': 'Year'}) df['Aging_rate'] = df['A1303'] / df['A1101'] * 100 # 高齢化率(%) df['Birth_rate'] = df['A4101'] / df['A1101'] * 1000 # 出生率(人口千対) df = df.set_index(['Prefecture', 'Year']) y = df['Birth_rate'] X = df[['Aging_rate', 'L3221']] # 高齢化率と消費支出 # 1. プールド OLS(固定効果を入れない) pooled = sm.OLS(y, sm.add_constant(X)).fit() print('pooled :', pooled.params.values) # 2. LSDV D = pd.get_dummies(df.index.get_level_values(0), drop_first=True, dtype=float) D.index = df.index Xd = pd.concat([X, D], axis=1) lsdv = sm.OLS(y, sm.add_constant(Xd)).fit() print('LSDV :', lsdv.params[['Aging_rate', 'L3221']].values) # 3. within 変換 Xw = X - X.groupby(level=0).transform('mean') yw = y - y.groupby(level=0).transform('mean') within = sm.OLS(yw, Xw).fit() print('within :', within.params.values) # 4. linearmodels の PanelOLS(クラスタロバスト SE) res = PanelOLS(y, X, entity_effects=True).fit(cov_type='clustered', cluster_entity=True) print(res.params) |
Aging_rate 係数が(小数点誤差を除いて)同じ値になることを確認。Hausman 検定が原則だが、 ドメイン知識で「個体効果と説明変数に相関がある」と判断できれば固定効果一択。 SSDSE-B-2026 の都道府県分析では通常、 固定効果が安全。
全国共通のショック(景気変動など)があるなら時間固定効果も必要。 二元固定効果(two-way FE)が標準。
個体固定効果と完全多重共線になるので推定不可。 これは固定効果モデルの最大の欠点。
「within R^2」「between R^2」「overall R^2」を分けて報告する。 固定効果モデルでは within R^2 が主役。
経験則で 30 クラスタ以上。 SSDSE-B-2026 の N=47 はギリギリ安全圏。 不安なら wild cluster bootstrap を併用。
2 期間 ・ 2 群 DID は one-way FE と等価。 多期間 DID は二元固定効果と等価(ただし staggered adoption で問題が出る)。
使えるが、 標準誤差が爆発する。 within 分散が小さい変数で因果推論しようとするのは無理がある。
パネルではクラスタロバストが原則。 通常のロバスト SE は系列相関を無視する。
LSDV はダミーが増えると行列計算が重い。 within 変換(demean)の方が効率的で、 結果は同じ。
被説明変数のラグを右辺に入れると Nickell バイアス。 Arellano-Bond GMM で対処。
linearmodels.PanelOLS や statsmodels の plm が自動対応。 ただし脱落理由が処置と相関するなら IPW が必要。
新しい個体への予測には使えない(固定効果は推定済み個体の値)。 一般化したい場合は変量効果か階層モデルへ。
農業就業者比率を被説明変数として、 「政策効果」を見たいときに、 県固有の気候や地理は時不変なので固定効果で完全に吸収される。 これにより気候を別途モデル化する必要がなくなる。
リーマンショックやコロナのような全国共通の年次ショックは、 年固定効果で吸収。 これにより「景気のせい」と「政策のせい」を分離できる。
「平成の大合併」のような大規模合併があった年は個体ダミーの定義が壊れる。 SSDSE-B-2026 は都道府県単位なので合併の影響は限定的だが、 市区町村単位の分析では深刻。
「同じ政策を導入しても、 大都市県と地方県で効果が逆」というケース。 固定効果+ HTE モデル(処置 × 都市規模ダミー)で異質性を可視化する。
合成データで個体内変動 (within) を計算する。
| i | t | y | y - ȳ_i |
|---|---|---|---|
| 1 | 1 | 10 | -2 |
| 1 | 2 | 12 | 0 |
| 1 | 3 | 14 | +2 |
| 2 | 1 | 20 | -2 |
| 2 | 2 | 22 | 0 |
| 2 | 3 | 24 | +2 |
ȳ_1 = 12, ȳ_2 = 22
1 2 3 4 5 6 7 8 | import numpy as np y = np.array([10,12,14,20,22,24]) ids = np.array([1,1,1,2,2,2]) within = sum((y[ids==i] - y[ids==i].mean())**2 for i in [1,2]).sum() total = ((y - y.mean())**2).sum() print(f"within: {within}") print(f"total: {total}") print(f"within/total: {within/total:.3f}") |
💬 手計算 (Step 2) 16 / 166 と Python 出力が完全一致。
1 2 3 4 5 6 7 8 9 | from linearmodels.panel import PanelOLS # panel の列は year / pref / pop / hospitals。被説明変数は hospitals(病院数)、 # 説明変数は pop(総人口)。'y' や 'x' という列は存在しない panel = panel.set_index(['pref', 'year']) mod = PanelOLS.from_formula('hospitals ~ 1 + pop + EntityEffects + TimeEffects', data=panel) res = mod.fit(cov_type='clustered', cluster_entity=True) print(res.params.round(6)) print('within R2 =', round(res.rsquared_within, 4)) |
少ない個体数なら、 ダミー変数を直接作って OLS で推定する古典的アプローチも有効。
1 2 3 4 5 6 7 8 9 10 11 12 13 | import pandas as pd import statsmodels.formula.api as smf # ── この抜粋だけで動くように、都道府県 × 年度のパネルを作り直す ── panel = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) panel = panel.rename(columns={'SSDSE-B-2026': 'year', 'Prefecture': 'pref'}) panel['y'] = panel['A4101'] / panel['A1101'] * 1000 # 出生率(人口千対) panel['x'] = panel['A1303'] / panel['A1101'] * 100 # 高齢化率(%) # C(pref) で都道府県ダミー、 C(year) で年ダミーを作成 model = smf.ols('y ~ x + C(pref) + C(year)', data=panel).fit( cov_type='cluster', cov_kwds={'groups': panel['pref']}) print(model.summary()) |
scikit-learn には公式の固定効果クラスはありません。 代わりにダミー変数を OneHotEncoder で作り、 LinearRegression に通す方法があります。 ただし正規方程式に直結する形なので、 大規模パネルでは linearmodels が圧倒的に速い。
1 2 3 4 5 6 7 8 9 10 11 12 13 | import pandas as pd import statsmodels.api as sm # この抜粋だけで動くように、都道府県 × 年度のパネルを作り直す df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) df = df.rename(columns={'SSDSE-B-2026': 'year', 'Prefecture': 'pref'}) df['y'] = df['A4101'] / df['A1101'] * 1000 # 出生率(人口千対) df['x'] = df['A1303'] / df['A1101'] * 100 # 高齢化率(%) # 各県の年度平均を引いて Within 変換 df['y_within'] = df['y'] - df.groupby('pref')['y'].transform('mean') df['x_within'] = df['x'] - df.groupby('pref')['x'].transform('mean') print(sm.OLS(df['y_within'], df['x_within']).fit().summary()) |
これは linearmodels が内部で行っている処理と同じ。 自由度補正は手動で必要。
同じデータに対して (1) プールド OLS、 (2) 個体固定効果、 (3) 二元固定効果 (TWFE) の 3 モデルを推定し、 係数の符号や大きさがどう変わるかを観察する。
SSDSE-B-2026 をパネル化(Prefecture × Year)したデータ。
3 モデルの係数表とクラスタロバスト標準誤差。
プールド OLS で正の係数が、 TWFE で負になる、 という現象(Simpson's paradox 的な逆転)は実データで頻繁に起こる。 これがパネル分析の真価。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | import pandas as pd from linearmodels.panel import PanelOLS, PooledOLS df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) df = df.rename(columns={'SSDSE-B-2026': 'Year'}) df['Aging_rate'] = df['A1303'] / df['A1101'] * 100 # 高齢化率(%) df['Birth_rate'] = df['A4101'] / df['A1101'] * 1000 # 出生率(人口千対) df = df.set_index(['Prefecture', 'Year']) y = df['Birth_rate'] X = df[['Aging_rate', 'L3221']] # 高齢化率と消費支出 # 1. プールド OLS pool = PooledOLS(y, X).fit(cov_type='clustered', cluster_entity=True) print('Pooled:') print(pool.params) # 2. 個体固定効果 fe = PanelOLS(y, X, entity_effects=True).fit(cov_type='clustered', cluster_entity=True) print('FE (entity):') print(fe.params) # 3. 二元固定効果 (TWFE) twfe = PanelOLS(y, X, entity_effects=True, time_effects=True).fit(cov_type='clustered', cluster_entity=True) print('TWFE:') print(twfe.params) |
unbalanced panel として扱う。 linearmodels.PanelOLS は自動対応。 ただし脱落が処置と相関するなら IPW で補正。
「処置 × 時間」は DID と同義。 「処置 × 共変量」は HTE 分析。 どちらも固定効果モデルに組み込み可能。
無視すると標準誤差が過小評価される。 クラスタロバスト SE で対処するのが標準。
新規個体の予測区間は通常出せない。 既存個体の将来予測は固定効果が利用可能。
「個体内の変動」だけを説明するのが within R^2 なので、 値が小さくなりやすい。 比較は同じ FE モデル間で行う。
固定効果は個体効果を「自由パラメータ」、 階層モデルは「確率変数」として扱う。 後者は予測に強い。
N が小さいとクラスタロバスト SE の漸近近似が崩れる。 wild cluster bootstrap が代替。
Athey-Wager の Double ML で、 機械学習を「残差化」のステップに使う。 固定効果はそのまま残せる。
「高齢化率(A1303÷A1101)」を Prefecture × Year のパネルで眺め、 between 分散 / within 分散 / overall 分散の比率を求めよ。 80% 以上が between なら固定効果モデルは多くの情報を捨てることになる。
「高齢化率 → 出生率(人口千対)」の回帰を 2 通り(個体固定効果のみ / TWFE)で推定し、 係数と SE を比較せよ。 全国共通の景気変動が混在する場合、 TWFE で係数が変わるはず。
同じ回帰で通常 SE とクラスタロバスト SE を比較し、 後者が大きくなることを確認せよ。 数十倍違うことも珍しくない。
変量効果モデルと固定効果モデルを推定し、 Hausman 検定で適切なモデルを判定せよ。 都道府県データではほぼ常に固定効果に軍配が上がる。
| 項目 | 固定効果モデル (FE) | 変量効果モデル (RE) | プールド OLS |
|---|---|---|---|
| 個体効果の扱い | 自由パラメータ | 確率変数 | 無視 |
| 個体効果と説明変数の相関 | 許す | 仮定: 無相関 | 無関係 |
| 時間不変変数の推定 | 不可 | 可 | 可 |
| 必要な漸近性 | N → ∞ (or T → ∞) | N → ∞ | N → ∞ |
| 効率性 | 低(自由度を多く消費) | 高(仮定が成り立てば) | 最高(仮定が成り立てば) |
| 不偏性(固定効果と相関ある場合) | 不偏 | 偏 | 偏 |
| 適切な検定 | F 検定 ・ Hausman | Breusch-Pagan | — |
パネルデータ分析と固定効果モデルは、 ミクロ計量経済学の発展と密接に関わってきました。 ここでは主要な発展を時系列で振り返り、 「なぜ二元固定効果が DID の標準になったのか」「なぜクラスタロバスト SE が必須になったのか」を歴史的視点から理解します。
計量経済学の初期、 ヘテロジニアスな個体を「個体ダミー変数」で扱うアイデアが登場。 ただし当時の計算機では大量のダミー変数を含む回帰は重く、 within 変換による計算量削減が重要視されました。
Mundlak (1978) が「個体効果と説明変数の相関」が固定効果と変量効果の選択を決めることを示しました。 Hausman (1978) は両者を統計的に判定する検定を提示。
Nickell (1981) は動学パネルでの固定効果バイアスを指摘。 Arellano-Bond (1991) ・ Blundell-Bond (1998) が GMM 推定量を提案し、 動学パネル分析の標準ツールになりました。
Bertrand-Duflo-Mullainathan (2004) は DID 分析でクラスタロバスト SE が必須であることを示しました。 これ以降、 パネル因果推論ではクラスタ SE が標準になりました。
Goodman-Bacon (2021) は staggered な処置タイミングで二元固定効果が偏ることを示し、 Callaway-Sant'Anna (2021) ・ de Chaisemartin-D'Haultfœuille (2020) などの新推定量が登場しました。
FE は個体内変動だけを使うため、 個体内で値が変わらない変数(性別、 出生年、 県のコード自体など)の係数は原理的に推定不能。 推定しようとすると多重共線性で落ちます。 もし時間不変要因の効果を見たいなら、 Random Effects(変量効果)モデルや Hausman-Taylor 推定、 Mundlak の近似が必要。 FE はあくまで「時間内変動」専用の道具と心得る。
パネルデータでは同じ個体(都道府県等)の年度間誤差が相関しています。 これを無視すると、 標準誤差が真の値の半分以下に推定され、 有意でないものを有意と誤判定する確率が高まる。 必ず クラスタ頑健標準誤差(cluster_entity=True)を使う。 Stata では cluster(pref)、 R では plm の vcovHC、 Python は linearmodels の自動オプションを利用。
個体FEだけだと、 「景気・コロナ・政策変更」など全国共通のショックが説明変数の影響と交絡することがある。 例えば 2020-2021年のコロナ期は全国一斉に医療費が変動した。 これを「病院数増加の効果」と誤認しないためには two-way FE(個体+年)を入れる。 ただし two-way FE は heterogeneous treatment effect の下で偏りを生むことが Goodman-Bacon (2021) で示されており、 因果推論では DiD の最新手法(Callaway-Sant'Anna 等)を検討する場面も。
FE は各個体の平均からの差で回帰するため、 自由度は単純にサンプル数ではなく NT − N − K(個体数 N、 期間 T、 説明変数 K)になります。 47県×6年=282 観測でも、 自由度は 282-47-K と大きく目減り。 ガジット派が「サンプル多いから安全」と過信するのは危険。 観測数と自由度を区別して計画する。
FE は「個体固有の時間不変交絡」を除去しますが、 「時間変動する交絡」は依然として残る。 たとえば「病院数増加 → 医療費増加」の推定で、 実は「県の景気変動が両方を動かしている」場合、 FE では救えない。 IV(操作変数)や DiD・PSM・合成統制法を併用する必要があります。 Hausman 検定で FE vs RE を比較するのも基本動作。
FE は個体間の系統的な違い(例:東京vs鳥取の構造的違い)を全部 α_i に押し込む。 つまり「東京と鳥取で平均的に何が違うか」については一切答えない。 もしそれが研究目的なら、 FE は不適切。 Random Effects か HLM(階層線形モデル)が必要。 研究目的が「県内変動の効果」なのか「県間差の説明」なのかを最初に明確にする。
47県のダミー変数を直接入れた OLS は、 サンプル数が増えると行列演算が非常に重くなる。 linearmodels の PanelOLS や R の fixest::feols は Within 変換を内部で使い、 ダミー行列を作らないので桁違いに速い。 大規模パネル(数万個体×数十年)では必須テクニック。
クラスタロバスト SE の漸近近似が崩れる。 wild cluster bootstrap で再評価。
個体固定効果を入れると切片を落とさないと完全多重共線。 drop_first=True。
「県境界の改編」など個体固有の時間不変ダミーは推定不可。 主分析から除外。
脱落が処置と相関するなら IPW で補正。
被説明変数のラグを入れると Nickell バイアス。 GMM で対処。
TWFE は処置効果に「負の重み」を割り当てる可能性。 Callaway-Sant'Anna に切り替え。
N >> T では within 推定量、 N << T では時系列分析。 同等なら両方検討。
処置効果が個体で異なるなら、 平均処置効果は誤解を招く。 HTE 分析へ。
パネルデータで「高齢化率 → 県民所得」の関係を推定。 プールド OLS では負の係数が出るが、 これは「もともと所得が低く高齢化が進んでいる地方県」と「所得が高く高齢化が遅い都市県」のクロスセクション差を捉えているだけ。 固定効果モデルに切り替えると「同じ県の中で高齢化が進んだとき所得がどう変わったか」が見え、 因果に近い解釈が可能になる。
「大学進学率 → 失業率」の関係。 県固定効果を入れると「県固有の大学設置数や産業構造」を吸収。 さらに時間固定効果を入れると「全国共通の景気変動」も吸収。 両者を入れると、 「同じ県の中で進学率が上がった年に失業率がどう変わったか」が分離される。
仮に「ある県だけが新政策を導入した」場合、 個体固定効果 + 時間固定効果 + 政策ダミー が DID と等価。 政策効果を推定する標準形であり、 平行トレンド仮定の検証が肝要。
既存の「直感」章とは別角度から固定効果を捉え直します。 ここでのキーワードは「各個体を自分自身の対照群にする」という発想と、 「全変動を between(個体間)と within(個体内)に分解する」という会計です。 固定効果推定量が使うのは within の変動だけ。 したがって「within にどれだけ情報が残っているか」を先に確認するのが、 落とし穴を避ける最短ルートになります。 以下の数値はすべて SSDSE-B-2026(47 都道府県 × 2012–2023 年 = 564 観測、 cp932 / skiprows=[1])を実測したものです(高齢化率 = A1303÷A1101×100、 出生率 = A4101÷A1101×1000)。
within 変換 $x_{it}-\bar{x}_i$ は、 各県を他県ではなく過去の自分と比べる操作です。 プール OLS や between 推定量が「高齢化率が高い県は出生率が低い」という県と県の横比較を見るのに対し、 固定効果は「同じ県の中で高齢化が進んだ年に、 出生率がどう動いたか」という県内の縦比較だけを見ます。 時間不変の県特性(気候・地理・県民性)は「自分の平均」に丸ごと含まれるので、 差を取った瞬間に消えます。 これが「self-control(自己対照)」という言い換えの核心です。
各変数の総分散を between(各県平均のばらつき)と within(各県内で年ごとにばらつく分)に分解した実測値です。
高齢化率は変動の約 7 割が between(=県ごとの水準差)で、 within に残るのは 3 割だけ。 固定効果はこの 3 割の情報「だけ」で係数を推定します。 「情報を捨てている」のではなく「交絡した情報を意図的に外している」のですが、 within が薄い変数ほど推定は不安定・測定誤差に脆弱になります(後述)。
被説明変数 = 出生率、 説明変数 = 高齢化率で、 pooled / between / 個体 FE(within)/ 変量効果(RE)/ 二元 FE(TWFE)を推定しました。 within R² ≈ 0.800。
| 推定量 | 使う変動 | 高齢化率の係数(実測) | 読み方 |
|---|---|---|---|
| プール OLS | between + within | -0.232 | 県間差に引っ張られた混合 |
| between | between のみ | -0.180 | 横断面「高齢な県ほど出生率低い」 |
| 個体 FE(within) | within のみ | -0.354 | 同じ県で高齢化が進むと出生率はより急に下がる |
| 変量効果(RE) | GLS 加重 | -0.344 | FE に近いが無相関を仮定 |
| 二元 FE(TWFE) | within − 年共通 | -0.016 | 年ダミー追加で効果がほぼ消滅 |
プール OLS(-0.232)は between(-0.180)と within(-0.354)の加重平均のような中間値になっているのが読み取れます。 これが「なぜ FE で係数が動くのか」の会計的な答えです。
上表で最も教育的なのは、 個体 FE の -0.354 が二元 FE で-0.016 までほぼ消えることです。 これは「高齢化が進んだ県で出生率が下がった」ように見えた within 相関の大半が、 実は全国一斉に進行した時間トレンド(少子高齢化という全国共通ショック)だったことを意味します。 県固定効果は時間不変の交絡しか吸収できないため、 この時間可変の交絡は年固定効果(TimeEffects)を足して初めて除去できます。 「個体 FE を入れたから因果」と早合点するのは危険で、 年 FE を足したときに効果が生き残るかを必ず確認すべき、 という実データの警告です(平行トレンド / DiD の発想に接続)。
分散分解で見た通り、 高齢化率は within が総分散の 30.1% しか残りません。 古典的測定誤差 $x^{*}=x+u$ の下で回帰係数は真値の $\dfrac{\mathrm{Var}(x^{*})}{\mathrm{Var}(x^{*})+\mathrm{Var}(u)}$ 倍に希薄化(attenuation)します。 within 変換は分母の信号分散 $\mathrm{Var}(x^{*})$ を減らす一方、 誤差分散 $\mathrm{Var}(u)$ は多くの場合そのまま残るため、 希薄化率が悪化します。 「FE にしたら係数がゼロに近づいた」現象は、 交絡除去だけでなく信号対雑音比の低下が原因のこともある、 という二面性に注意してください(測定誤差)。 (希薄化の一般式は教科書結果であり、 上の 30.1% は SSDSE-B-2026 の実測、 誤差分散そのものは本データからは同定できません。)
同じ県の年度間で誤差は相関するため、 i.i.d. を仮定した標準誤差は過小評価になります。 上の個体 FE(高齢化率係数)で実測すると:
この例では 1.46 倍ですが、 系列相関が強い変数ではもっと開きます。 t 値・信頼区間・有意性判定がすべて楽観的にずれるため、 パネルではクラスタ頑健 SE を既定にするのが作法です(標準誤差)。 なお N=47 はクラスタ数として下限に近く、 不安なら wild cluster bootstrap を併用します。
※ 本節の係数・分散・SE・χ² はすべて SSDSE-B-2026 実測(出生率〜高齢化率、 単回帰、 564 観測)。 測定誤差の希薄化式のみ一般的な教科書結果で、 誤差分散は本データからは同定していません。
p値だけでなく効果量も併記するのが現代統計の標準。 主要な指標と Cohen の解釈基準:
| 統計量 | 効果量 | 小 | 中 | 大 |
|---|---|---|---|---|
| 2群平均差 | Cohen's d | 0.2 | 0.5 | 0.8 |
| 相関 | r | 0.1 | 0.3 | 0.5 |
| 線形回帰 | R² | 0.02 | 0.13 | 0.26 |
| ANOVA | η² (eta²) | 0.01 | 0.06 | 0.14 |
| χ² | Cramér's V | 0.1 | 0.3 | 0.5 |
| ロジスティック | Odds Ratio | 1.5 | 2.5 | 4.0 |
固定効果モデル がデータサイエンスの体系の中でどこに位置するかを、 3つの異なる視点で可視化します。 同じ情報でも見方を変えると気付きが変わります。
🌐 統計・データサイエンス › 因果推論 › パネル分析 › 固定効果モデル(個体固有の効果を除く推定)
中心に 固定効果モデル を置き、 そこから パネルデータ・ランダム効果・時系列分析 計 3 個の用語へ、 前提・兄弟・発展形といった関係を矢印で結んでいます。 線がどちら向きかを見れば、 先に読むべき用語とあとから読む用語が分かります。 ノードはドラッグで動かせ、 ホイールでズーム、 クリックでその用語のページへ遷移します。
大きな円が小さな円を包含する Circle Packing 図。 「固定効果モデル」は緑色でハイライト。
長方形を入れ子に分割した Treemap 図。 各分野の規模感を面積で比較。 「固定効果モデル」は緑色でハイライト。
| マップ | 分かること | こんな時に見る |
|---|---|---|
| 🔗 関係マップ | 手法間の横の関係(前提→発展→応用) | 「次に何を学べばよい?」 学習順序の判断 |
| ⭕ 包含マップ | 分類体系の入れ子構造(上位⊃下位) | 「この手法はどんなジャンルに属する?」 |
| 🌳 ツリーマップ | 分野の規模比較(面積=ボリューム) | 「データサイエンス全体の俯瞰像」 |
💡 3 つの図は同じ位置関係を別の角度から描いています。 関係マップは 固定効果モデル の隣に何が並ぶかを、 包含マップとツリーマップは 統計・データサイエンス → パネル分析 → 固定効果モデル という入れ子の位置を示します。 「パネル分析には他に何があったか」を思い出したいときは包含マップを、 「次に何を読むか」を決めたいときは関係マップを開いてください。
「固定効果モデル」は単独で完結せず、 隣接する手法と接続することで分析パイプラインの一部として機能する。 以下に具体的な接続関係を示す。
「固定効果モデル」は (1) パネルデータ整備 (個体 i × 時期 t) → (2) within 変換または LSDV → (3) クラスタロバスト標準誤差 → (4) F 検定で個別効果有意性 → (5) Hausman 検定で RE vs FE 選択、 の 5 段パネル分析パイプラインで運用する。
論文・記事に登場する用語のリンクで該当箇所へジャンプ: