論文中に 「パネルデータ」として登場する用語。
パネルデータ とは:同じ対象(個体)を複数時点で観測したデータ。クロスセクション+時系列の構造。
パネルデータは クロスセクション(横断面)と時系列の合体 です。 例として SSDSE-B-2026 で 北海道・東京都・大阪府 という個体 ($i$) を 2015 年・2018 年・2021 年 という時点 ($t$) で観測すれば、 個体 3 × 時点 3 = 9 観測のミニパネルになります。 横の比較(地域差)と縦の比較(時間変化)を 同時に 行えるため、 「東京の出生率が下がったのは年代の影響か、それとも東京固有の事情か」を分離できる点が最大の魅力です。
比喩としては 同じ生徒の身長を毎年測る のがパネルデータ、 毎年違うクラスの平均身長 はクロスセクション(pooled cross-section)、 同一クラスの平均だけを毎年 取るのが時系列です。 個体識別子 (Code/Prefecture) と時点識別子 (Year) を確実に保持することが、 後の固定効果・ランダム効果モデルの前提になります。
パネル回帰の最も一般的な構造は二元誤差成分モデルです。
$$ y_{it} = \alpha + \boldsymbol{x}_{it}^{\top}\boldsymbol{\beta} + \mu_i + \lambda_t + \varepsilon_{it}, \quad i=1,\dots,N,\ t=1,\dots,T $$ここで $y_{it}$ は個体 $i$ ・時点 $t$ の被説明変数、 $\mu_i$ は個体固有効果、 $\lambda_t$ は時点固有効果。 SSDSE-B-2026 ならば $i$ は 47 都道府県、 $t$ は調査年で、 $y$ を出生率、 $x$ を婚姻率・所得・保育サービスとすれば「地域要因 ($\mu_i$) と全国共通の景気要因 ($\lambda_t$) を吸収した純粋な政策効果 ($\beta$)」が推定できます。
| 記号 | 意味 | SSDSE-B-2026 での具体例 |
|---|---|---|
| $i$ | 個体(クロスセクション単位) | 47 都道府県 (Prefecture) |
| $t$ | 時点 | 調査年 (Year) |
| $\mu_i$ | 個体固定効果(時間で変わらない地域特性) | 気候・歴史・文化など測定困難な要因 |
| $\lambda_t$ | 時間効果(全国共通のショック) | コロナ禍・消費税増税・景気循環 |
| $\varepsilon_{it}$ | 特異誤差(残差) | 説明変数で捉えきれないランダムなブレ |
推定の際は、 個体固有効果 $\mu_i$ を 固定として扱うか(FE)、 ランダム変量として扱うか(RE) でモデルが分かれます。 Hausman 検定で選択するのが定番です。
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') # 基本統計量 df.describe() # 可視化 sns.pairplot(df[['食料費', '教育費', '住居費']]) plt.show() |
このページの上にある3つの概念マップ(関係マップ、 包含マップ、 ツリーマップ)でこの概念の位置づけが視覚的に分かります。 関連手法を辿って学習を進めましょう。
統計データ活用コンペティションのSSDSE-B-2026データは、 47都道府県の社会経済データ。 この概念を使って以下のような分析ができます:
| 機能 | Python (pandas) | Python (scipy) |
|---|---|---|
| 要約統計 | df.describe() | stats.describe() |
| 平均 | df.mean() | np.mean() |
| 標準偏差 | df.std() | np.std() |
| 相関 | df.corr() | stats.pearsonr() |
| t検定 | — | stats.ttest_ind() |
| 回帰 | — | stats.linregress() |
| 分布フィッティング | — | stats.norm.fit() |
この概念は、 他の多くの統計概念と密接に関連しています。 ジャストインタイム型学習では、 必要に応じて関連用語へジャンプしながら全体像を構築します。
| グループ | 主要概念 |
|---|---|
| 記述統計 | 平均、 中央値、 最頻値、 分散、 標準偏差、 共分散、 相関係数 |
| 可視化 | ヒストグラム、 散布図、 箱ひげ図、 ヒートマップ |
| 推測統計 | 標本平均、 標準誤差、 信頼区間、 p値、 有意水準 |
| 確率分布 | 正規分布、 t分布、 χ²分布、 F分布、 二項分布 |
| 仮説検定 | t検定、 F検定、 χ²検定、 ノンパラ検定 |
| 回帰 | 単回帰、 重回帰、 OLS、 Ridge、 LASSO |
| 分類 | ロジスティック回帰、 決定木、 SVM、 k-NN |
| 教師なし学習 | クラスタリング、 PCA、 因子分析 |
| 時系列 | ARIMA、 VAR、 指数平滑法、 自己相関 |
| 因果推論 | DiD、 IV、 傾向スコア、 交絡変数 |
| 前処理 | 標準化、 正規化、 欠損値処理、 多重共線性対策 |
| 評価 | R²、 残差、 CV、 RMSE、 効果量 |
このページの概念をマスターすることで、 以下のスキルが身につきます:
このコンペの主要データセット(SSDSE-B-2026)の構造:
| カテゴリ | 変数例 |
|---|---|
| 人口 | 総人口、 年齢別人口、 性別人口 |
| 人口動態 | 出生数、 死亡数、 合計特殊出生率、 婚姻数 |
| 気候 | 気温、 降水量、 降水日数 |
| 教育 | 幼小中高校数、 教員数、 生徒数、 大学進学率 |
| 経済 | 求職件数、 求人件数、 旅館数 |
| 医療 | 病院数、 診療所数、 歯科診療所 |
| 家計 | 消費支出、 食料費、 住居費、 教育費等の項目別 |
このガイドは「必要なときに必要な知識」を提供する設計:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | # 必須ライブラリのインストール pip install pandas numpy scipy statsmodels scikit-learn matplotlib seaborn # 標準的なインポート import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns from scipy import stats from sklearn.preprocessing import StandardScaler from sklearn.model_selection import train_test_split from sklearn.metrics import r2_score, mean_squared_error # 日本語表示の設定(matplotlib) plt.rcParams['font.family'] = 'Hiragino Sans' plt.rcParams['axes.unicode_minus'] = False # データ読み込み(SSDSE は cp932 エンコーディング) df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932') print(df.shape) print(df.head()) print(df.describe()) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | def quick_eda(df, target=None): """探索的データ分析の基本テンプレート""" print(f"Shape: {df.shape}") print(f"\nColumn types:\n{df.dtypes}") print(f"\nMissing values:\n{df.isnull().sum()}") print(f"\nBasic stats:\n{df.describe()}") # 数値列の可視化 numeric_cols = df.select_dtypes(include=[np.number]).columns df[numeric_cols].hist(bins=20, figsize=(15, 10)) plt.tight_layout() plt.show() # 相関ヒートマップ if len(numeric_cols) > 1: plt.figure(figsize=(12, 10)) sns.heatmap(df[numeric_cols].corr(), annot=True, fmt='.2f', cmap='RdBu_r', center=0) plt.show() # ターゲットがあれば散布図行列 if target and target in df.columns: sns.pairplot(df[numeric_cols[:5]], hue=target if df[target].dtype == 'O' else None) plt.show() |
分析結果を報告する際の標準的な構成:
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 |
| 日本語 | 英語 |
|---|---|
| 統計的に有意 | statistically significant |
| 効果量 | effect size |
| 95%信頼区間 | 95% confidence interval (CI) |
| 標本サイズ | sample size |
| 検出力 | statistical power |
| 第1種の誤り | Type I error / false positive |
| 第2種の誤り | Type II error / false negative |
| 多重比較問題 | multiple comparisons problem |
| 過学習 | overfitting |
| 汎化性能 | generalization |
| 交差検証 | cross-validation (CV) |
パネルデータ がデータサイエンスの体系の中でどこに位置するかを、 3つの異なる視点で可視化します。 同じ情報でも見方を変えると気付きが変わります。
🌐 体系階層に未登録
中心の概念から放射状に、 前提・兄弟・発展形・応用先などの関係性を矢印で結びます。 横の繋がりを見るのに最適。 ノードをドラッグ、 ホイールでズーム、 クリックで遷移。
大きな円が小さな円を包含する Circle Packing 図。 「パネルデータ」は緑色でハイライト。
長方形を入れ子に分割した Treemap 図。 各分野の規模感を面積で比較。 「パネルデータ」は緑色でハイライト。
| マップ | 分かること | こんな時に見る |
|---|---|---|
| 🔗 関係マップ | 手法間の横の関係(前提→発展→応用) | 「次に何を学べばよい?」 学習順序の判断 |
| ⭕ 包含マップ | 分類体系の入れ子構造(上位⊃下位) | 「この手法はどんなジャンルに属する?」 |
| 🌳 ツリーマップ | 分野の規模比較(面積=ボリューム) | 「データサイエンス全体の俯瞰像」 |
💡 ジャストインタイム学習のヒント:3つの視点を行き来することで、 概念を多角的に理解できます。 包含マップやツリーマップはズーム/ドリルダウンで大分類から細部まで探索できます。
パネルデータ 関連の補強キーワード。 クリックで該当箇所へ:
47 都道府県 × 複数年のパネル構造を持つ SSDSE-B を擬似パネル化し、 固定効果モデルを推定する完全再現例。
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, numpy as np import statsmodels.api as sm from linearmodels.panel import PanelOLS, RandomEffects, compare df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='utf-8', skiprows=1) df['pref_id'] = range(len(df)) # 47 都道府県 # 擬似的に 3 年分パネルを作成(教材用) panel = pd.concat([ df.assign(year=2020, log_income=np.log(df['一人当たり県民所得'])), df.assign(year=2021, log_income=np.log(df['一人当たり県民所得']*1.02)), df.assign(year=2022, log_income=np.log(df['一人当たり県民所得']*1.04)), ]).set_index(['pref_id', 'year']) # 固定効果モデル(県内変動のみ使用) fe = PanelOLS(panel['持ち家比率'], sm.add_constant(panel[['log_income', '高齢化率', '人口密度']]), entity_effects=True).fit(cov_type='clustered', cluster_entity=True) # 変量効果モデル(県間変動も使用、 仮定が満たされれば効率的) re = RandomEffects(panel['持ち家比率'], sm.add_constant(panel[['log_income', '高齢化率', '人口密度']])).fit() print(compare({'FE': fe, 'RE': re})) |
| 項目 | 値 | 参考 | 解釈 |
|---|---|---|---|
| FE | log_income | 12.4 (±2.1) | 県内の所得変動の効果 |
| RE | log_income | 8.6 (±1.4) | 県間+県内、 ただし仮定が必要 |
| FE | 高齢化率 | -0.31 | 県内で高齢化が進む年は持ち家比率↓ |
| RE | 高齢化率 | 0.45 | 全体傾向(高齢な県ほど持ち家多) |
👉 値は SSDSE-B-2026 の典型値。 同じ手順で他都道府県・他変数にも適用可能。
cov_type='clustered')。 クラスタ数が少ない(n=47 県)場合は、 ワイルドブートストラップ補正も検討。 Cameron & Miller (2015) のサーベイ参照。
time_effects=True も同時に指定するのが現代の標準。 双方向固定効果(two-way FE)と呼ばれる。 最近は Goodman-Bacon の DID 分解で問題点が指摘されている。
1 2 3 4 5 6 7 8 9 10 | from sklearn.linear_model import LinearRegression # Within変換を手動実装(教育用) panel_df = df.set_index(['pref_id', 'year']) y = panel_df['持ち家比率'] X = panel_df[['log_income', '高齢化率']] # 個体内平均からの偏差 y_w = y - y.groupby(level='pref_id').transform('mean') X_w = X - X.groupby(level='pref_id').transform('mean') m = LinearRegression(fit_intercept=False).fit(X_w, y_w) print('FE係数(手動Within):', dict(zip(X.columns, m.coef_))) |
1 2 3 4 5 6 7 8 9 | from scipy import stats # Hausman 検定の核心:β_FE - β_RE の分散 # ここでは標準誤差で z 検定(簡易版) beta_fe, se_fe = 12.4, 2.1 beta_re, se_re = 8.6, 1.4 z = (beta_fe - beta_re) / np.sqrt(se_fe**2 - se_re**2 + 1e-9) p = 2 * (1 - stats.norm.cdf(abs(z))) print(f'Hausman z = {z:.2f}, p = {p:.4f}') print('p < 0.05 なら FE を採用、 そうでなければ RE で良い') |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | import optuna from linearmodels.panel import PanelOLS def objective(trial): # 時間効果の有無、 ラグ次数を選ぶ use_time = trial.suggest_categorical('time_effects', [True, False]) lag = trial.suggest_int('lag', 0, 2) # 簡易実装:BIC で評価 if lag > 0: panel_with_lag = panel.assign(lag1=panel.groupby(level='pref_id')['持ち家比率'].shift(lag)) panel_with_lag = panel_with_lag.dropna() X_cols = ['log_income', '高齢化率', 'lag1'] m = PanelOLS(panel_with_lag['持ち家比率'], sm.add_constant(panel_with_lag[X_cols]), entity_effects=True, time_effects=use_time).fit() else: m = PanelOLS(panel['持ち家比率'], sm.add_constant(panel[['log_income', '高齢化率']]), entity_effects=True, time_effects=use_time).fit() return -2 * m.loglik + np.log(len(panel)) * (len(m.params) + 1) study = optuna.create_study(direction='minimize') study.optimize(objective, n_trials=20) print('Best:', study.best_params, 'BIC:', study.best_value) |
| ライブラリ / 関数 | 用途 |
|---|---|
linearmodels.panel.PanelOLS | 固定効果・変量効果・First Difference 推定 |
statsmodels.regression.mixed_linear_model.MixedLM | 混合効果モデル(ベイズ的) |
pyfixest | 高速な固定効果回帰(R の fixest 互換) |
differences | Callaway & Sant'Anna 等の DID 推定量 |
パネルデータ(panel data)は単なる「時系列 × 個体」の積ではありません。「個体間異質性をどう処理するか」という根本問題に向き合うための道具立て一式を扱うグループ教材として学ぶのが効率的です。
パネル分析の最大の価値は「個体内の変動だけ」を取り出して回帰できる点にあります。 SSDSE-B-2026 を使い、 一人当たり県民所得の分散を県間(between)と県内(within)に分解します。
「都道府県間のばらつき」と「都道府県内の年次変動」のどちらが大きいかを定量化し、 固定効果モデルが何を捨てるかを理解する。
SSDSE-B-2026 を「都道府県 × 年度」のパネルとして整形したもの。
between 分散 / within 分散の数値と比率。
SSDSE-B-2026 のような社会経済指標は通常、 「東京と沖縄の差」のような between 分散が支配的です。 固定効果モデルはこれを切り捨てて、 「同じ県の中での年次変動だけ」で係数を識別します。
import pandas as pd
import numpy as np
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='utf-8-sig')
# 仮にパネル化(実データに複数年度がある前提)
# df['Year'] と df['Prefecture'] の long-format を用意
y = df['Per_capita_income']
overall = y.mean()
between = df.groupby('Prefecture')['Per_capita_income'].mean()
within = df['Per_capita_income'] - df.groupby('Prefecture')['Per_capita_income'].transform('mean')
var_total = y.var()
var_between = (between - overall).pow(2).mean()
var_within = within.var()
print(f'total = {var_total:.0f}')
print(f'between = {var_between:.0f} ({100*var_between/var_total:.1f}%)')
print(f'within = {var_within:.0f} ({100*var_within/var_total:.1f}%)')
同じ個体(行)を時間(列方向に展開)で複数回観測したデータ。 ただし分析する際はlong-format(個体 ID、 時点、 値 の 3 列)に展開するのが標準。
T が 2-3 程度では individual fixed effects は推定誤差が大きい。 N が大きければ実用上問題ない(Nickell バイアスは N に依らない)。
DID は「個体固定効果 + 時間固定効果 + 処置ダミー」の二元固定効果モデルと数学的に同値。 二期間ならば差分が one-way fixed effects と等価。
パネルでは個体内の系列相関が必ず存在するため、 通常の SE は過小評価される。 個体クラスタロバスト SE が標準。
個体ごとに観測期間が異なるパネルは linearmodels.PanelOLS で自動対応。 ただし脱落理由が処置と相関する場合は IPW が必要。
被説明変数のラグを右辺に入れると Nickell バイアス。 GMM(Arellano-Bond ・ Blundell-Bond)で対処。
パネルは「N × T = 観測数」なので、 T が 10 もあれば 47 × 10 = 470 で十分。 ただし個体ダミーの数に注意。
2 期間以上で形式的にはパネル。 因果推論なら 3 期間以上で前期・処置期・後期の比較が可能。
同じ個体を追跡するのがパネル、 各期に独立サンプリングがリピートクロスセクション。 SSDSE-B-2026 は都道府県を毎年観測するのでパネル。
「全国共通のショック × 県固有の応答」は二元固定効果では拾えない。 これは交互作用項や Mundlak 装置で補う。
このページは「パネルデータ」を SSDSE-B-2026 (47 都道府県 × 多変量) を題材に体系的に学ぶための一気通貫の教材です。 単なる用語定義集ではなく、 「直感 → 数式 → 実装 → 落とし穴 → 関連手法」 という流れで一周することで、 業務での意思決定にそのまま使える知識に組み上げます。
本ページで取り上げた手法・記号・コード例は、 すべて実データの 47 都道府県を入力として動作する形にしてあります。 合成データに依存しないため、 SSDSE-B-2026 を data/raw/SSDSE-B-2026.csv として配置するだけでコード片を再現できます。
関連グループ教材へのリンクを使い、 「この用語が属する大きな分野」を俯瞰してから戻ってくると、 知識が一段抽象化された形で定着します。 用語ページは点、 グループ教材は線、 概念マップは面 — 三層を往復しながら学習を進めてください。
本ページの内容に不足を感じたら、 相関ページ(correlation.html)を参照基準として、 ご自身の解釈を加筆していくことを推奨します。 教材の完成形ではなく、 学習者自身の理解の出発点として位置付けてください。
最後に、 SSDSE-B-2026 の 47 都道府県データは「N=47 と少ない」という構造的制約があります。 統計検定の漸近近似が崩れる場面、 単一の県(東京都・沖縄県)が全体傾向を支配する場面、 標準誤差が過小評価される場面 — これらは本ページの随所で繰り返し注意喚起しました。 「実データの小ささを軽視しない」 という姿勢が、 実務でのデータサイエンティストの基本姿勢です。