このページの分析を自分で再現するには、以下の手順でデータを準備してください。コードの編集は不要です。
data/raw/ フォルダに入れます。html/figures/ に自動保存されます。
日本は世界で最も急速に高齢化が進む国のひとつであり、2023年時点での全国平均高齢化率(65歳以上人口比率)は 31.6% に達した。高齢化は社会保障費の膨張、現役世代の負担増大、労働力不足をもたらし、地域経済の活力低下を招くと懸念されてきた。
まず「高齢化と地域経済成長の関係:動態的パネル分析」を統計的にとらえることが有効だと考えられる。 その理由は感覚や経験則だけでは、複雑な社会要因の中で「何が本当に効いているか」を見極めにくいからである。 本研究では公開データと統計手法を組み合わせ、この問いに定量的な答えを出すことを目指す。
しかし一方で、高齢者の消費行動や医療・介護需要が地域内経済を下支えするという議論もある。本研究はこの「高齢化と経済成長のジレンマ」を47都道府県のパネルデータ(2012〜2023年)で実証的に検証する。
パネル分析 固定効果モデル 相関分析 時系列分析 非線形モデル
政府統計の総合窓口(e-Stat)が提供する教育用統計データセット SSDSE-B-2026(社会・人口統計体系、47都道府県版)を使用。2012〜2023年の12年間にわたる都道府県別年次データから、合計 564観測 のバランスト・パネルを構成した。
| 変数の種類 | 変数名 | 出所(SSDSE-B列) | 想定効果 |
|---|---|---|---|
| 目的変数 | 消費支出(二人以上世帯) | 消費支出(二人以上の世帯) | ─ |
| 主要説明変数 | 高齢化率(%) | 65歳以上人口 / 総人口 | 正(逆U字仮説) |
| 高齢化率の2乗項 | 高齢化率² | 負(逆U字の右下がり) | |
| コントロール変数 | 求人倍率 | 月間有効求人数 / 月間有効求職者数 | 正(雇用好調 → 所得増) |
| 保健医療費/人 | 保健医療費(二人以上の世帯) | 正(医療支出の大きい高齢者世帯) | |
| 人口規模(代理) | log(総人口) | 総人口の自然対数 | 正(都市の消費水準) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | import os import numpy as np import pandas as pd import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt import statsmodels.api as sm from scipy import stats plt.rcParams['font.family'] = 'Hiragino Sans' plt.rcParams['axes.unicode_minus'] = False plt.rcParams['figure.dpi'] = 150 FIG_DIR = 'html/figures' DATA_B = 'data/raw/SSDSE-B-2026.csv' os.makedirs(FIG_DIR, exist_ok=True) df_b = pd.read_csv(DATA_B, encoding='cp932', header=1) df_b = df_b[df_b['地域コード'].str.match(r'^R\d{5}', na=False)].copy() df_b['年度'] = df_b['年度'].astype(int) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。import pandas as pd など — 必要なライブラリをまとめて呼び出します。as pd は短い別名(alias)。matplotlib.use('Agg') — グラフを画面表示せずファイルに保存するためのおまじない。plt.rcParams['font.family'] — グラフの日本語表示用フォント指定(Macは Hiragino Sans、Windowsなら Yu Gothic 等)。os.makedirs('html/figures', exist_ok=True) — 図の保存先フォルダを作る(既にあってもOK)。pd.read_csv(...) でCSVを読み込みます。encoding='cp932' は日本語Windows由来の文字コード、header=1 は「2行目を列名として使う」。df['地域コード'].str.match(r'^R\d{5}', ...) — 正規表現で「R+数字5桁」の行(47都道府県)だけTrueにし、真偽値で行をフィルタ。.astype(int) — 列を整数に変換(年度などを数値比較するため)。f"...{x}..." はf-string。文字列の中に {変数} と書くだけで埋め込めて、{x:.2f} のように書式も指定できます。21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | # 地域マップ region_map = { '北海道': '北海道・東北', '青森県': '北海道・東北', '岩手県': '北海道・東北', '宮城県': '北海道・東北', '秋田県': '北海道・東北', '山形県': '北海道・東北', '福島県': '北海道・東北', '茨城県': '関東', '栃木県': '関東', '群馬県': '関東', '埼玉県': '関東', '千葉県': '関東', '東京都': '関東', '神奈川県': '関東', '新潟県': '中部', '富山県': '中部', '石川県': '中部', '福井県': '中部', '山梨県': '中部', '長野県': '中部', '岐阜県': '中部', '静岡県': '中部', '愛知県': '中部', '三重県': '近畿', '滋賀県': '近畿', '京都府': '近畿', '大阪府': '近畿', '兵庫県': '近畿', '奈良県': '近畿', '和歌山県': '近畿', '鳥取県': '中国・四国', '島根県': '中国・四国', '岡山県': '中国・四国', '広島県': '中国・四国', '山口県': '中国・四国', '徳島県': '中国・四国', '香川県': '中国・四国', '愛媛県': '中国・四国', '高知県': '中国・四国', '福岡県': '九州・沖縄', '佐賀県': '九州・沖縄', '長崎県': '九州・沖縄', '熊本県': '九州・沖縄', '大分県': '九州・沖縄', '宮崎県': '九州・沖縄', '鹿児島県': '九州・沖縄', '沖縄県': '九州・沖縄' } region_colors = { '北海道・東北': '#4e9af1', '関東': '#e05c5c', '中部': '#f0a500', '近畿': '#5cb85c', '中国・四国': '#9b59b6', '九州・沖縄': '#f39c12' } df_b['地域'] = df_b['都道府県'].map(region_map) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。df['A'] / df['B'] — pandasの列同士の四則演算は要素ごと(element-wise)。forループ不要なのが強み。44 45 46 47 48 49 50 | df_b['高齢化率'] = df_b['65歳以上人口'] / df_b['総人口'] * 100 df_b['消費支出'] = pd.to_numeric(df_b['消費支出(二人以上の世帯)'], errors='coerce') df_b['保健医療費_人'] = pd.to_numeric(df_b['保健医療費(二人以上の世帯)'], errors='coerce') df_b['求人数'] = pd.to_numeric(df_b['月間有効求人数(一般)'], errors='coerce') df_b['求職者数'] = pd.to_numeric(df_b['月間有効求職者数(一般)'], errors='coerce') # 求人倍率(有効求人数 / 有効求職者数) df_b['求人倍率'] = df_b['求人数'] / df_b['求職者数'] |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。df['A'] / df['B'] — pandasの列同士の四則演算は要素ごと(element-wise)。forループ不要なのが強み。51 52 53 54 55 56 | # 人口密度の代理変数: 高齢化率の高い地域は過疎地に多い(ここでは総人口/都道府県数で代替) # SSDSE-Bには面積データがないため、総人口を代理変数として使用 df_b['log_人口'] = np.log(df_b['総人口']) # 2次項 df_b['高齢化率2'] = df_b['高齢化率'] ** 2 |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。.map() は「1対1の置き換え」、.apply() は「関数を当てる」。辞書なら .map()、ロジックなら .apply()。57 58 59 60 61 62 63 64 65 66 67 68 | # 消費支出成長率(前年比) df_b_sorted = df_b.sort_values(['都道府県', '年度']).copy() df_b_sorted['消費支出成長率'] = df_b_sorted.groupby('都道府県')['消費支出'].pct_change() * 100 # 2012〜2023 絞り込み df_panel = df_b_sorted[(df_b_sorted['年度'] >= 2012) & (df_b_sorted['年度'] <= 2023)].copy() print("=== データ概要 ===") print(f"観測数: {len(df_panel)}") print(f"都道府県数: {df_panel['都道府県'].nunique()}") print(f"年度範囲: {df_panel['年度'].min()} - {df_panel['年度'].max()}") print() |
=== データ概要 === 観測数: 564 都道府県数: 47 年度範囲: 2012 - 2023
df.groupby('列').apply(関数) — グループごとに関数を適用。時系列や地域別の集計でよく使います。sort_values('列名', ascending=False) — 指定列で並べ替え(降順)。[式 for x in リスト] はリスト内包表記。forループでappendする代わりに1行でリストを作れます。69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | print() print("=== HTML用統計サマリー ===") print(f"分析期間: {df_panel['年度'].min()}〜{df_panel['年度'].max()}年") print(f"サンプル数(延べ): {len(df_panel.dropna(subset=['消費支出','高齢化率']))} 観測") print(f"2023年 全国平均高齢化率: {aging_2023['高齢化率'].mean():.1f}%") print(f"2023年 最高高齢化率: {aging_2023.iloc[0]['都道府県']} {aging_2023.iloc[0]['高齢化率']:.1f}%") print(f"2023年 最低高齢化率: {aging_2023.iloc[-1]['都道府県']} {aging_2023.iloc[-1]['高齢化率']:.1f}%") # 2012年との比較 aging_2012 = df_panel[df_panel['年度'] == 2012][['都道府県', '高齢化率']].set_index('都道府県') aging_2023_idx = aging_2023.set_index('都道府県') change = (aging_2023_idx['高齢化率'] - aging_2012['高齢化率']).sort_values(ascending=False) print(f"2012→2023 高齢化率増加幅最大: {change.index[0]} +{change.iloc[0]:.1f}pt") print(f"2012→2023 高齢化率増加幅最小: {change.index[-1]} +{change.iloc[-1]:.1f}pt") # 消費支出との相関 corr_data = df_2022[['高齢化率', '消費支出']].dropna() r2, p2 = stats.pearsonr(corr_data['高齢化率'], corr_data['消費支出']) print(f"2022年断面 高齢化率×消費支出 相関: r={r2:.3f} p={p2:.4f}") print() print("全図の生成が完了しました。") |
=== HTML用統計サマリー === 分析期間: 2012〜2023年 サンプル数(延べ): 564 観測 2023年 全国平均高齢化率: 31.6% 2023年 最高高齢化率: 秋田県 39.1% 2023年 最低高齢化率: 東京都 22.8% 2012→2023 高齢化率増加幅最大: 秋田県 +8.4pt 2012→2023 高齢化率増加幅最小: 東京都 +1.5pt 2022年断面 高齢化率×消費支出 相関: r=-0.361 p=0.0126 全図の生成が完了しました。
sort_values('列名', ascending=False) — 指定列で並べ替え(降順)。stats.pearsonr(x, y) — Pearson相関係数 r と p値を同時に返します。s[:-n]「末尾n文字を除く」/s[n:]「先頭n文字を除く」。スライス [start:stop:step] はリスト・タプル・文字列共通の基本ワザです。2012〜2023年における都道府県別高齢化率の推移を地域ブロックで色分けして示す。
2012〜2023年の増加幅では、秋田県が最大の +8.4 ポイントを記録した一方、東京都は +1.5 ポイントと相対的に緩やかな増加にとどまった。北海道・東北ブロックと中国・四国ブロックの高齢化率が特に高く、全国平均を5〜8ポイント程度上回って推移している。
47都道府県×12年のデータを個別に描くと情報過多になる。そこで地域ブロック別に集約したグループ平均の折れ線グラフが効果的。ブロック内の個体差(県差)は別途箱ひげ図等で補完する。
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | fig1, ax1 = plt.subplots(figsize=(10, 6)) regions_order = ['北海道・東北', '関東', '中部', '近畿', '中国・四国', '九州・沖縄'] df_region_aging = df_panel.groupby(['年度', '地域'])['高齢化率'].mean().reset_index() for region in regions_order: d = df_region_aging[df_region_aging['地域'] == region] d = d.sort_values('年度') ax1.plot(d['年度'], d['高齢化率'], marker='o', markersize=5, color=region_colors[region], linewidth=2, label=region) ax1.set_xlabel('年度', fontsize=12) ax1.set_ylabel('高齢化率(%)', fontsize=12) ax1.set_title('地域別 高齢化率の時系列推移(2012〜2023年)', fontsize=14, fontweight='bold') ax1.legend(loc='upper left', fontsize=10) ax1.set_xticks(range(2012, 2024)) ax1.grid(True, alpha=0.3) ax1.set_ylim(15, 40) plt.tight_layout() fig1.savefig(os.path.join(FIG_DIR, '2019_U2_fig1.png'), dpi=150, bbox_inches='tight') plt.close(fig1) print("図1 保存完了") |
図1 保存完了
df.groupby('列').apply(関数) — グループごとに関数を適用。時系列や地域別の集計でよく使います。fig, ax = plt.subplots(...) — 図全体(fig)と軸(ax)を作る定番。以降は ax.bar(...) 等で操作。sort_values('列名', ascending=False) — 指定列で並べ替え(降順)。[式 for x in リスト] はリスト内包表記。forループでappendする代わりに1行でリストを作れます。各都道府県に固有の不観測な効果(地域文化・気候・歴史的経緯等)をコントロールするため、固定効果(FE: Fixed Effects)モデルを推定した。誤差項の系列相関・不均一分散に対応するため、クラスター標準誤差(都道府県クラスター)を使用している。
ここで αi は都道府県固定効果(entity effects)、εit は誤差項。Within推定(グループ平均からのデミーニング)により αi を消去して推定する。
| 変数 | 推定係数 | 標準誤差 | t値 | p値 | 判定 |
|---|---|---|---|---|---|
| 高齢化率(%) | +6,270 | 5,296 | 1.18 | 0.237 | n.s. |
| 高齢化率² | -171 | 107 | -1.60 | 0.110 | n.s. (†) |
| 求人倍率 | +12,057 | 4,512 | 2.67 | 0.008 | *** p<0.01 |
| 保健医療費/人 | +3.56 | 0.44 | 8.18 | <0.001 | *** p<0.001 |
| log(人口) | -116,649 | 103,905 | -1.12 | 0.262 | n.s. |
クラスター標準誤差(都道府県クラスター)。Within R² = 0.126、F検定 p<0.0001。
パネルデータには「見えない個体差」が潜む。例えば秋田県は歴史的に倹約文化がある、東京は消費性向が高い、などの不観測効果。これを無視してOLS推定すると省略変数バイアスが生じる。FEモデルはデータを「グループ平均からの乖離」に変換(デミーニング)することで、この不観測効果を差し引いてしまう。
115 116 117 118 119 120 121 122 123 | df_2022 = df_panel[df_panel['年度'] == 2022].copy() df_2022 = df_2022.dropna(subset=['高齢化率', '消費支出']) fig2, ax2 = plt.subplots(figsize=(11, 8)) for region in regions_order: d = df_2022[df_2022['地域'] == region] ax2.scatter(d['高齢化率'], d['消費支出'] / 1000, color=region_colors[region], s=60, alpha=0.8, label=region, zorder=3) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。fig, ax = plt.subplots(...) — 図全体(fig)と軸(ax)を作る定番。以降は ax.bar(...) 等で操作。r, p = stats.pearsonr(...) — Pythonは複数戻り値を同時に受け取れる(タプルアンパック)。124 125 126 127 128 129 | # 都道府県ラベル for _, row in df_2022.iterrows(): ax2.annotate(row['都道府県'].replace('県', '').replace('都', '').replace('府', '').replace('道', ''), (row['高齢化率'], row['消費支出'] / 1000), fontsize=7, ha='center', va='bottom', color='#333333', xytext=(0, 4), textcoords='offset points') |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。for _, row in df.iterrows() — DataFrameを1行ずつ取り出すループ。1点ずつ描画したいときに使用。x if cond else y は三項演算子。リスト内包表記と組み合わせると、forとifを1行で書けます。130 131 132 133 134 135 136 | # 2次曲線フィット x_fit = df_2022['高齢化率'].values y_fit = df_2022['消費支出'].values / 1000 coeffs = np.polyfit(x_fit, y_fit, 2) x_range = np.linspace(x_fit.min(), x_fit.max(), 200) y_range = np.polyval(coeffs, x_range) ax2.plot(x_range, y_range, 'k--', linewidth=2, label=f'2次フィット\n({coeffs[0]:.1f}x²+{coeffs[1]:.1f}x+{coeffs[2]:.0f})') |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。df[col](1列)と df[[col1, col2]](複数列)でカッコの数が違います。リストを渡していると覚えるとミスを減らせます。137 138 139 140 141 142 143 144 145 146 147 148 149 150 | # 相関係数 r, p = stats.pearsonr(x_fit, y_fit) ax2.text(0.05, 0.95, f'r = {r:.3f} (p = {p:.3f})', transform=ax2.transAxes, fontsize=11, va='top', bbox=dict(boxstyle='round,pad=0.4', facecolor='white', alpha=0.8)) ax2.set_xlabel('高齢化率(%)', fontsize=12) ax2.set_ylabel('消費支出(千円)', fontsize=12) ax2.set_title('高齢化率と消費支出の関係(2022年断面、47都道府県)', fontsize=14, fontweight='bold') ax2.legend(loc='upper right', fontsize=9) ax2.grid(True, alpha=0.3) plt.tight_layout() fig2.savefig(os.path.join(FIG_DIR, '2019_U2_fig2.png'), dpi=150, bbox_inches='tight') plt.close(fig2) print("図2 保存完了") |
図2 保存完了
stats.pearsonr(x, y) — Pearson相関係数 r と p値を同時に返します。s[:-n]「末尾n文字を除く」/s[n:]「先頭n文字を除く」。スライス [start:stop:step] はリスト・タプル・文字列共通の基本ワザです。高齢化と消費支出の関係が逆U字型(ある水準まで増加し、それ以降は減少)かどうかを検証するため、2022年断面データを用いた散布図と2次曲線フィット、および高齢化率上位群・下位群の時系列比較を行った。
高齢化率の低い下位5県(東京・愛知等の大都市圏)の平均消費支出は一貫して上位5県を上回る。ただし、COVID-19禍の2020〜2021年には両群ともに消費支出が落ち込み、その回復パターンにも差異が見られる。
「逆U字関係」を検証するには説明変数に2乗項を加えて推定し、その係数の符号と有意性を確認する。回転点(ピーク)は β₁ / (2|β₂|) で求められる。
単純な断面OLSと固定効果モデルで結果が異なる場合は、地域固有の特性(都市規模・産業構造)が交絡している可能性を考慮する。
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 | fig3, ax3 = plt.subplots(figsize=(9, 5)) if fe_params is not None: # const以外の係数のみ plot_keys = [k for k in fe_params.index if k != 'const'] plot_labels = [param_names_en.get(k, k) for k in plot_keys] plot_vals = [fe_params[k] for k in plot_keys] # 標準化(係数の絶対値)で色分け colors_bar = ['#e05c5c' if v < 0 else '#4e9af1' for v in plot_vals] # 信頼区間 # conf_int の列名を動的に取得(linearmodels: 'lower'/'upper', statsmodels: 0/1) ci_cols = list(fe_conf_int.columns) lo_col, hi_col = ci_cols[0], ci_cols[1] lo = [fe_conf_int.loc[k, lo_col] for k in plot_keys] hi = [fe_conf_int.loc[k, hi_col] for k in plot_keys] xerr_lo = [abs(v - l) for v, l in zip(plot_vals, lo)] xerr_hi = [abs(h - v) for v, h in zip(plot_vals, hi)] bars = ax3.barh(plot_labels, plot_vals, color=colors_bar, alpha=0.8, height=0.6) ax3.errorbar(plot_vals, plot_labels, xerr=[xerr_lo, xerr_hi], fmt='none', color='black', capsize=5, linewidth=1.5) ax3.axvline(0, color='black', linewidth=0.8, linestyle='-') ax3.set_xlabel('推定係数', fontsize=12) ax3.set_title('固定効果モデル(FE)の推定係数と95%信頼区間', fontsize=13, fontweight='bold') ax3.grid(True, axis='x', alpha=0.3) plt.tight_layout() fig3.savefig(os.path.join(FIG_DIR, '2019_U2_fig3.png'), dpi=150, bbox_inches='tight') plt.close(fig3) print("図3 保存完了") |
図3 保存完了
fig, ax = plt.subplots(...) — 図全体(fig)と軸(ax)を作る定番。以降は ax.bar(...) 等で操作。ax.axhline / ax.axvline — 水平/垂直の点線。平均線や基準線として定番。x if cond else y は三項演算子。リスト内包表記と組み合わせると、forとifを1行で書けます。本分析の結果から、以下の政策的含意が導かれる。
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 | df_fe = df_panel.dropna(subset=['消費支出', '高齢化率', '求人倍率', '保健医療費_人', 'log_人口', '高齢化率2']).copy() fe_results = None fe_params = None fe_conf_int = None try: from linearmodels.panel import PanelOLS df_fe = df_fe.set_index(['都道府県', '年度']) y = df_fe['消費支出'] X = sm.add_constant(df_fe[['高齢化率', '高齢化率2', '求人倍率', '保健医療費_人', 'log_人口']]) model = PanelOLS(y, X, entity_effects=True) fe_results = model.fit(cov_type='clustered', cluster_entity=True) print("=== PanelOLS 固定効果モデル結果 ===") print(fe_results.summary) fe_params = fe_results.params fe_conf_int = fe_results.conf_int() print() print("係数:") print(fe_params) except Exception as e: print(f"PanelOLS 失敗 ({e})、OLS にフォールバック") df_fe_ols = df_panel.dropna(subset=['消費支出', '高齢化率', '求人倍率', '保健医療費_人', 'log_人口', '高齢化率2']).copy() X_ols = sm.add_constant(df_fe_ols[['高齢化率', '高齢化率2', '求人倍率', '保健医療費_人', 'log_人口']]) y_ols = df_fe_ols['消費支出'] ols_model = sm.OLS(y_ols, X_ols).fit() print("=== OLS フォールバック結果 ===") print(ols_model.summary()) fe_params = ols_model.params fe_conf_int = ols_model.conf_int() |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。import pandas as pd など — 必要なライブラリをまとめて呼び出します。as pd は短い別名(alias)。sm.add_constant(X) — 切片項(定数1の列)を先頭に追加。statsmodelsで必須。sm.OLS(y, X).fit() — 最小二乗法でモデルを推定。model.params, model.pvalues, model.conf_int() で結果取得。.map() は「1対1の置き換え」、.apply() は「関数を当てる」。辞書なら .map()、ロジックなら .apply()。214 215 216 217 218 | # 係数の情報を取得 if fe_params is not None: param_names_en = {'const': '定数項', '高齢化率': '高齢化率', '高齢化率2': '高齢化率²', '求人倍率': '求人倍率', '保健医療費_人': '保健医療費/人', 'log_人口': 'log(人口)'} param_display = {param_names_en.get(k, k): v for k, v in fe_params.items() if k != 'const'} |
=== PanelOLS 固定効果モデル結果 ===
PanelOLS Estimation Summary
================================================================================
Dep. Variable: 消費支出 R-squared: 0.1256
Estimator: PanelOLS R-squared (Between): -19.745
No. Observations: 564 R-squared (Within): 0.1256
Date: Mon, May 18 2026 R-squared (Overall): -13.532
Time: 11:23:30 Log-likelihood -6112.8
Cov. Estimator: Clustered
F-statistic: 14.708
Entities: 47 P-value 0.0000
Avg Obs: 12.000 Distribution: F(5,512)
Min Obs: 12.000
Max Obs: 12.000 F-statistic (robust): 14.772
P-value 0.0000
Time periods: 12 Distribution: F(5,512)
Avg Obs: 47.000
Min Obs: 47.000
Max Obs: 47.000
Parameter Estimates
==============================================================================
Parameter Std. Err. T-stat P-value Lower CI Upper CI
------------------------------------------------------------------------------
const 1.877e+06 1.455e+06 1.2902 0.1975 -9.813e+05 4.736e+06
高齢化率 6269.5 5296.3 1.1837 0.2371 -4135.7 1.667e+04
高齢化率2 -170.97 106.66 -1.6029 0.1096 -380.51 38.579
求人倍率 1.206e+04 4512.2 2.6721 0.0078 3192.6 2.092e+04
保健医療費_人 3.5638 0.4358 8.1782 0.0000 2.7077 4.4199
log_人口 -1.166e+05 1.039e+05 -1.1228 0.2621 -3.208e+05 8.747e+04
==============================================================================
F-test for Poolability: 16.838
P-value: 0.0000
Distribution: F(46,512)
Included effects: Entity
係数:
const 1.877462e+06
高齢化率 6.269452e+03
高齢化率2 -1.709654e+02
求人倍率 1.205733e+04
保健医療費_人 3.563793e+00
log_人口 -1.166493e+05
Name: parameter, dtype: float64[式 for x in リスト] はリスト内包表記。forループでappendする代わりに1行でリストを作れます。219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 | aging_2023 = df_panel[df_panel['年度'] == 2023][['都道府県', '高齢化率']].sort_values('高齢化率', ascending=False) top5_prefs = aging_2023.head(5)['都道府県'].tolist() bot5_prefs = aging_2023.tail(5)['都道府県'].tolist() print(f"高齢化率上位5: {top5_prefs}") print(f"高齢化率下位5: {bot5_prefs}") df_top = df_panel[df_panel['都道府県'].isin(top5_prefs)].groupby('年度')['消費支出'].mean() / 1000 df_bot = df_panel[df_panel['都道府県'].isin(bot5_prefs)].groupby('年度')['消費支出'].mean() / 1000 fig4, ax4 = plt.subplots(figsize=(10, 6)) ax4.plot(df_top.index, df_top.values, marker='o', markersize=6, color='#e05c5c', linewidth=2.5, label=f'高齢化率上位5県\n({", ".join([p.replace("県","").replace("都","").replace("府","").replace("道","") for p in top5_prefs])})') ax4.plot(df_bot.index, df_bot.values, marker='s', markersize=6, color='#4e9af1', linewidth=2.5, label=f'高齢化率下位5県\n({", ".join([p.replace("県","").replace("都","").replace("府","").replace("道","") for p in bot5_prefs])})') ax4.fill_between(df_top.index, df_top.values, df_bot.values, alpha=0.08, color='gray') ax4.set_xlabel('年度', fontsize=12) ax4.set_ylabel('平均消費支出(千円)', fontsize=12) ax4.set_title('高齢化率 上位群 vs 下位群 の消費支出比較(2012〜2023年)', fontsize=13, fontweight='bold') ax4.legend(loc='upper left', fontsize=9) ax4.set_xticks(range(2012, 2024)) ax4.grid(True, alpha=0.3) plt.tight_layout() fig4.savefig(os.path.join(FIG_DIR, '2019_U2_fig4.png'), dpi=150, bbox_inches='tight') plt.close(fig4) print("図4 保存完了") |
高齢化率上位5: ['秋田県', '高知県', '徳島県', '山口県', '青森県'] 高齢化率下位5: ['滋賀県', '神奈川県', '愛知県', '沖縄県', '東京都'] 図4 保存完了
df.groupby('列').apply(関数) — グループごとに関数を適用。時系列や地域別の集計でよく使います。fig, ax = plt.subplots(...) — 図全体(fig)と軸(ax)を作る定番。以降は ax.bar(...) 等で操作。sort_values('列名', ascending=False) — 指定列で並べ替え(降順)。ax.fill_between(...) — 2つの曲線で囲まれた領域を塗りつぶし。Lorenz曲線の格差面積などを可視化。df[col](1列)と df[[col1, col2]](複数列)でカッコの数が違います。リストを渡していると覚えるとミスを減らせます。本研究では、47都道府県の2012〜2023年パネルデータ(SSDSE-B)を用い、高齢化と地域消費支出の関係を動態的に検証した。主要な結果をまとめる。
| 分析 | 結果 | 解釈 |
|---|---|---|
| 時系列推移(図1) | 全地域で高齢化率が上昇。北海道・東北が最高、関東が最低 | 地域格差は拡大傾向 |
| 断面相関(図2) | r = -0.361(p = 0.013) | 高齢化率高い県ほど消費低め |
| FEモデル 求人倍率 | +12,057(p = 0.008) | 雇用が消費を強く押し上げ |
| FEモデル 保健医療費 | +3.56(p < 0.001) | 医療消費が総消費を下支え |
| 逆U字仮説(高齢化率²) | -171(p = 0.110) | 符号は整合的だが有意性なし |
| 上位 vs 下位群比較(図4) | 下位群(大都市)が一貫して高消費 | 都市圏・地方圏の構造的差異 |
(1) 固定効果か変量効果か:Hausman検定(または理論的根拠)で選択する。地域固有の特性が説明変数と相関していると考えられるなら固定効果。
(2) クラスター標準誤差:同一都道府県内の年次誤差は相関しやすい(系列相関)。同一個体内の相関を認めるクラスター標準誤差を使用することで、t検定の信頼性が向上する。
(3) Poolability検定:F(46,512)=16.84, p<0.001 が固定効果の存在を強く支持。単純なプールドOLSは不適切。
統計分析の解釈で初心者がやりがちな勘違いをまとめます。特に「相関と因果の混同」「p値の過信」は研究現場でもよく起きる落とし穴です。本文を読む前にも、読んだ後にも、目を通してみてください。
統計の基本用語を初心者向けに解説します。本文中で見慣れない言葉が出てきたら、ここに戻って確認してください。
統計手法について「何のためか」「結果をどう読むか」を初心者向けに解説します。
この研究をさらに発展させるための3つの方向性を示します。「今回わかったこと(X)」から「次に検証すべき仮説(Y)」を立て、「具体的に何をするか(Z)」まで考えてみましょう。
学んだだけでは身につきません。実際に手を動かすのが最強の学習方法です。本論文のスクリプトをベースに、以下のチャレンジに挑戦してみてください。難易度別に5つ用意しました。
本論文で学んだ手法は、研究の世界だけでなく、行政・企業・NPO の現場でも様々に活用されています。具体的なシーンを紹介します。
この論文を読んで初心者が抱きやすい疑問に、教育的観点から答えます。