このページの分析を自分で再現するには、以下の手順でデータを準備してください。コードの編集は不要です。
data/raw/ フォルダに入れます。html/figures/ に自動保存されます。
日本の総人口は2008年の約1億2,808万人をピークに減少局面に入り、地方圏では2000年代前半から人口流出・少子化が深刻化している。2021年時点で47都道府県のうち41道府県が前年比で人口を減らしており、国・自治体が移住促進や子育て支援に多額の予算を投じているが、その効果は地域によって大きく異なる。
まず「人口減少対策の効果検証移住促進・子育て支援政策の地域分析」を統計的にとらえることが有効だと考えられる。 その理由は感覚や経験則だけでは、複雑な社会要因の中で「何が本当に効いているか」を見極めにくいからである。 本研究では公開データと統計手法を組み合わせ、この問いに定量的な答えを出すことを目指す。
本研究は、SSDSE-B(都道府県統計データ)を用いて2012年から2022年の断面データを分析し、移住促進(転入率・転出率)と子育て支援(保育所密度・合計特殊出生率)のいずれが人口増減率に強く影響するかを重回帰分析によって検証する。
重回帰分析 相関分析 地域比較 SSDSE-B 2026
SSDSE-B-2026(社会・人口統計体系データセット)の2022年断面データを主に使用。47都道府県全てを分析対象とする。2012→2022年の10年間の人口変化率を目的変数として算出する。
| 区分 | 変数名 | 元データ(SSDSE-B) | 加工方法 |
|---|---|---|---|
| 目的変数 | 人口増加率(%) | 総人口(2012年・2022年) | (P2022-P2012)/P2012×100 |
| 移住促進 | 転入率(%) | 転入者数(日本人移動者) | 転入数/総人口×100 |
| 転出率(%) | 転出者数(日本人移動者) | 転出数/総人口×100 | |
| 子育て支援 | 保育所密度(施設/千人) | 保育所等数 | 保育所等数/総人口×1000 |
| 合計特殊出生率 | 合計特殊出生率 | そのまま使用 | |
| 住宅コスト | 住居費割合(%) | 住居費・消費支出(二人以上の世帯) | 住居費/消費支出×100 |
転入率・転出率はある1年間の「フロー」(流れ量)であるのに対し、人口増加率は10年間の「ストック」変化量である。回帰分析で両者を組み合わせる際には、1年断面のフロー変数が10年間のストック変化を代理することに注意が必要。2022年の転入率は当年の社会移動を反映しており、10年分の累積移動の「代表値」として解釈する。
まず、子育て支援の重要指標である「保育所密度」と「合計特殊出生率」の関係を都道府県別に可視化する。地域ブロックごとに色分けし、各都道府県の位置を確認する。
次に、2012年を基準(=100)とした地域別の人口指数の推移を確認する。
都道府県の人口規模は北海道の約500万人から東京都の約1,400万人まで大きく異なる。絶対値で比較すると規模の大きい都市の変化が目立ちすぎる。基準年=100の指数化を行うことで、規模を揃えた変化率比較が可能になる。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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) |
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)。f"...{x}..." はf-string。文字列の中に {変数} と書くだけで埋め込めて、{x:.2f} のように書式も指定できます。17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | # ── データ読み込み ────────────────────────────────────────────────────────── 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) # ── 地域マップ ────────────────────────────────────────────────────────────── region_map = { '北海道': '北海道・東北', '青森県': '北海道・東北', '岩手県': '北海道・東北', '宮城県': '北海道・東北', '秋田県': '北海道・東北', '山形県': '北海道・東北', '福島県': '北海道・東北', '茨城県': '関東', '栃木県': '関東', '群馬県': '関東', '埼玉県': '関東', '千葉県': '関東', '東京都': '関東', '神奈川県': '関東', '新潟県': '中部', '富山県': '中部', '石川県': '中部', '福井県': '中部', '山梨県': '中部', '長野県': '中部', '岐阜県': '中部', '静岡県': '中部', '愛知県': '中部', '三重県': '近畿', '滋賀県': '近畿', '京都府': '近畿', '大阪府': '近畿', '兵庫県': '近畿', '奈良県': '近畿', '和歌山県': '近畿', '鳥取県': '中国・四国', '島根県': '中国・四国', '岡山県': '中国・四国', '広島県': '中国・四国', '山口県': '中国・四国', '徳島県': '中国・四国', '香川県': '中国・四国', '愛媛県': '中国・四国', '高知県': '中国・四国', '福岡県': '九州・沖縄', '佐賀県': '九州・沖縄', '長崎県': '九州・沖縄', '熊本県': '九州・沖縄', '大分県': '九州・沖縄', '宮崎県': '九州・沖縄', '鹿児島県': '九州・沖縄', '沖縄県': '九州・沖縄' } region_colors = { '北海道・東北': '#4e9af1', '関東': '#e05c5c', '中部': '#f0a500', '近畿': '#5cb85c', '中国・四国': '#9b59b6', '九州・沖縄': '#f39c12' } |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。pd.read_csv(...) でCSVを読み込みます。encoding='cp932' は日本語Windows由来の文字コード、header=1 は「2行目を列名として使う」。df['地域コード'].str.match(r'^R\d{5}', ...) — 正規表現で「R+数字5桁」の行(47都道府県)だけTrueにし、真偽値で行をフィルタ。.astype(int) — 列を整数に変換(年度などを数値比較するため)。df['A'] / df['B'] — pandasの列同士の四則演算は要素ごと(element-wise)。forループ不要なのが強み。43 44 45 46 47 48 49 50 51 | # ── 変数の準備 ────────────────────────────────────────────────────────────── # 2012年・2022年断面 df12 = df_b[df_b['年度'] == 2012].set_index('都道府県').copy() df22 = df_b[df_b['年度'] == 2022].set_index('都道府県').copy() # 共通47都道府県 pref_47 = df22.index.intersection(df12.index) df22 = df22.loc[pref_47].copy() df12 = df12.loc[pref_47].copy() |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。.map() は「1対1の置き換え」、.apply() は「関数を当てる」。辞書なら .map()、ロジックなら .apply()。52 53 54 55 56 57 58 59 60 | # 人口増加率(2012→2022) df22['人口増加率'] = (df22['総人口'] - df12['総人口']) / df12['総人口'] * 100 # 人口千人あたり指標 df22['保育所密度'] = df22['保育所等数'] / df22['総人口'] * 1000 df22['転入率'] = df22['転入者数(日本人移動者)'] / df22['総人口'] * 100 df22['転出率'] = df22['転出者数(日本人移動者)'] / df22['総人口'] * 100 df22['純移動率'] = df22['転入率'] - df22['転出率'] df22['住居費割合'] = df22['住居費(二人以上の世帯)'] / df22['消費支出(二人以上の世帯)'] * 100 |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。[式 for x in リスト] はリスト内包表記。forループでappendする代わりに1行でリストを作れます。61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | # 地域ラベル付与 df22['地域'] = df22.index.map(region_map) df22 = df22.reset_index() # ── 都道府県略称 ────────────────────────────────────────────────────────────── abbr = { '北海道':'北海道', '青森県':'青森', '岩手県':'岩手', '宮城県':'宮城', '秋田県':'秋田', '山形県':'山形', '福島県':'福島', '茨城県':'茨城', '栃木県':'栃木', '群馬県':'群馬', '埼玉県':'埼玉', '千葉県':'千葉', '東京都':'東京', '神奈川県':'神奈川', '新潟県':'新潟', '富山県':'富山', '石川県':'石川', '福井県':'福井', '山梨県':'山梨', '長野県':'長野', '岐阜県':'岐阜', '静岡県':'静岡', '愛知県':'愛知', '三重県':'三重', '滋賀県':'滋賀', '京都府':'京都', '大阪府':'大阪', '兵庫県':'兵庫', '奈良県':'奈良', '和歌山県':'和歌山', '鳥取県':'鳥取', '島根県':'島根', '岡山県':'岡山', '広島県':'広島', '山口県':'山口', '徳島県':'徳島', '香川県':'香川', '愛媛県':'愛媛', '高知県':'高知', '福岡県':'福岡', '佐賀県':'佐賀', '長崎県':'長崎', '熊本県':'熊本', '大分県':'大分', '宮崎県':'宮崎', '鹿児島県':'鹿児島', '沖縄県':'沖縄' } fig1, ax1 = plt.subplots(figsize=(10, 7)) x_col = '保育所密度' y_col = '合計特殊出生率' df_plot = df22[['都道府県', x_col, y_col, '地域']].dropna() for region, grp in df_plot.groupby('地域'): col = region_colors.get(region, '#888') ax1.scatter(grp[x_col], grp[y_col], c=col, s=60, alpha=0.85, label=region, edgecolors='white', linewidths=0.5, zorder=3) for _, row in grp.iterrows(): ax1.annotate(abbr.get(row['都道府県'], row['都道府県']), (row[x_col], row[y_col]), fontsize=7.5, ha='center', va='bottom', xytext=(0, 3), textcoords='offset points', color='#333', zorder=4) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。df.groupby('列').apply(関数) — グループごとに関数を適用。時系列や地域別の集計でよく使います。fig, ax = plt.subplots(...) — 図全体(fig)と軸(ax)を作る定番。以降は ax.bar(...) 等で操作。for _, row in df.iterrows() — DataFrameを1行ずつ取り出すループ。1点ずつ描画したいときに使用。r, p = stats.pearsonr(...) — Pythonは複数戻り値を同時に受け取れる(タプルアンパック)。95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | # 回帰線 x_arr = df_plot[x_col].values y_arr = df_plot[y_col].values slope, intercept, r_val, p_val, _ = stats.linregress(x_arr, y_arr) x_line = np.linspace(x_arr.min(), x_arr.max(), 100) ax1.plot(x_line, intercept + slope * x_line, 'k--', linewidth=1.5, alpha=0.7, zorder=2) ax1.text(0.98, 0.04, f'r = {r_val:.3f} (p = {p_val:.3f})', transform=ax1.transAxes, ha='right', fontsize=10, bbox=dict(boxstyle='round,pad=0.4', fc='white', ec='#ccc', alpha=0.9)) ax1.set_xlabel('保育所密度(施設数/千人)', fontsize=12) ax1.set_ylabel('合計特殊出生率', fontsize=12) ax1.set_title('図1 保育所密度と合計特殊出生率の関係(2022年・47都道府県)', fontsize=13, fontweight='bold') ax1.legend(loc='upper left', fontsize=9, framealpha=0.9) ax1.grid(True, alpha=0.3, zorder=1) fig1.tight_layout() fig1.savefig(os.path.join(FIG_DIR, '2021_H5_1_fig1.png'), dpi=150, bbox_inches='tight') plt.close(fig1) print('fig1 saved') |
fig1 saved
stats.linregress(x, y) — 単回帰の傾き・切片・r値・p値・標準誤差を返します。使わない値は _ で受け取り。x if cond else y は三項演算子。リスト内包表記と組み合わせると、forとifを1行で書けます。5つの説明変数(保育所密度・合計特殊出生率・転入率・転出率・住居費割合)を目的変数「人口増加率(2012→2022年)」に回帰させる。全変数を標準化(平均0、標準偏差1)した上でOLS推定を行い、標準化偏回帰係数(β)によって各要因の相対的な影響力を比較する。
| 変数 | 標準化係数 (β) | t値 | p値 | 有意性 | 解釈 |
|---|---|---|---|---|---|
| 転入率 | +1.553 | 7.09 | <0.001 | *** | 転入が多い都道府県ほど人口増加(最大効果) |
| 転出率 | -0.883 | -4.27 | <0.001 | *** | 転出が多い都道府県は人口減少(強い負効果) |
| 合計特殊出生率 | +0.172 | 1.63 | 0.110 | n.s. | 出生率の正効果は見られるが非有意 |
| 保育所密度 | -0.127 | -1.17 | 0.249 | n.s. | 保育所密度の単独効果は非有意 |
| 住居費割合 | +0.055 | 0.61 | 0.544 | n.s. | 住宅コストの効果は非有意 |
| モデル適合度 | R² = 0.735 | Adj-R² = 0.702(N=47) | |||
異なる単位を持つ変数(転入率[%]と保育所密度[施設/千人]など)を比較するため、全変数を標準化してからOLSを実施する。標準化係数βの絶対値が大きいほど、その変数の相対的影響力が大きいことを示す。ただし、転入率と転出率は互いに相関している可能性があるため(都市部は両方高い)、VIF(分散膨張因子)で多重共線性を確認することが重要。
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | years_avail = sorted(df_b['年度'].unique()) region_pop = {} for yr in years_avail: dfyr = df_b[df_b['年度'] == yr].copy() dfyr['地域'] = dfyr['都道府県'].map(region_map) grp = dfyr.groupby('地域')['総人口'].sum() region_pop[yr] = grp pop_df = pd.DataFrame(region_pop).T # 2012年を100として指数化 base = pop_df.loc[2012] pop_idx = pop_df.div(base) * 100 fig2, ax2 = plt.subplots(figsize=(10, 6)) for region in region_colors: if region in pop_idx.columns: col = region_colors[region] ax2.plot(pop_idx.index, pop_idx[region], color=col, linewidth=2.2, marker='o', markersize=4, label=region, zorder=3) ax2.axhline(100, color='#aaa', linestyle='--', linewidth=1, alpha=0.7) ax2.set_xlabel('年度', fontsize=12) ax2.set_ylabel('人口指数(2012年=100)', fontsize=12) ax2.set_title('図2 地域別人口推移(2012〜2023年、2012年=100)', fontsize=13, fontweight='bold') ax2.set_xticks(years_avail) ax2.set_xticklabels([str(y) for y in years_avail], rotation=45, fontsize=9) ax2.legend(loc='lower left', fontsize=9, framealpha=0.9) ax2.grid(True, alpha=0.3, zorder=1) fig2.tight_layout() fig2.savefig(os.path.join(FIG_DIR, '2021_H5_1_fig2.png'), dpi=150, bbox_inches='tight') plt.close(fig2) print('fig2 saved') |
fig2 saved
df.groupby('列').apply(関数) — グループごとに関数を適用。時系列や地域別の集計でよく使います。fig, ax = plt.subplots(...) — 図全体(fig)と軸(ax)を作る定番。以降は ax.bar(...) 等で操作。ax.axhline / ax.axvline — 水平/垂直の点線。平均線や基準線として定番。df['A'] / df['B'] — pandasの列同士の四則演算は要素ごと(element-wise)。forループ不要なのが強み。重回帰分析の結果から、都道府県レベルでは移住促進(社会的人口移動)が子育て支援(自然増加)より人口変動に大きく寄与することが示された。以下に各対策の効果と解釈上の留意点を整理する。
β = +1.553(p<0.001)。転入率が1標準偏差高い都道府県は、人口増加率が平均的な都道府県より1.553標準偏差高い。移住者の受け入れ拡大が最も即効性のある対策。
β = -0.883(p<0.001)。転出率の低減も統計的に有意。若年層の地方からの流出を食い止める施策(雇用創出・生活利便性向上)が重要。
β = -0.127(n.s.)。保育所密度は出生率と正相関(r=0.628)するが、人口増加率との直接効果は非有意。子育て環境の充実は長期的な出生行動に影響するが、10年スパンの人口変動への影響は限定的。
β = +0.172(n.s.)。出生率の増加は自然増加に寄与するが、47都道府県の10年スパン分析では社会移動の効果が上回り、有意な効果は検出されなかった。
「保育所密度の効果が非有意」という結果は、「保育所が重要でない」という意味ではない。N=47の小サンプルでは、中程度の効果量(β≒0.2程度)は検出力不足で非有意となりうる。重要なのは①p値(有意性)②β・効果量(実質的大きさ)③信頼区間(不確かさの範囲)の3点をセットで報告すること。
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 | fig3, ax3 = plt.subplots(figsize=(9, 5)) var_labels = { '保育所密度': '保育所密度\n(施設数/千人)', '合計特殊出生率': '合計特殊出生率', '転入率': '転入率\n(転入数/人口 %)', '転出率': '転出率\n(転出数/人口 %)', '住居費割合': '住居費割合\n(住居費/消費支出 %)', } labels = [var_labels.get(v, v) for v in coef_df['変数']] colors_bar = ['#e05c5c' if sig else '#aaaaaa' for sig in coef_df['有意']] values = coef_df['標準化係数'].values bars = ax3.barh(labels, values, color=colors_bar, edgecolor='white', height=0.6) ax3.axvline(0, color='#333', linewidth=1.2) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。fig, ax = plt.subplots(...) — 図全体(fig)と軸(ax)を作る定番。以降は ax.bar(...) 等で操作。ax.axhline / ax.axvline — 水平/垂直の点線。平均線や基準線として定番。[式 for x in リスト] はリスト内包表記。forループでappendする代わりに1行でリストを作れます。165 166 167 168 169 170 171 172 | # p値ラベル for i, (bar, row) in enumerate(zip(bars, coef_df.itertuples())): sig_str = '***' if row.p値 < 0.001 else '**' if row.p値 < 0.01 else '*' if row.p値 < 0.05 else 'n.s.' x_pos = row.標準化係数 ha = 'left' if x_pos >= 0 else 'right' offset = 0.01 if x_pos >= 0 else -0.01 ax3.text(x_pos + offset, i, f' {sig_str} (p={row.p値:.3f})', va='center', ha=ha, fontsize=9) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。r, p = stats.pearsonr(...) — Pythonは複数戻り値を同時に受け取れる(タプルアンパック)。173 174 175 176 177 178 179 180 181 182 183 184 185 186 | # 凡例パッチ import matplotlib.patches as mpatches sig_patch = mpatches.Patch(color='#e05c5c', label='有意(p<0.05)') ns_patch = mpatches.Patch(color='#aaaaaa', label='非有意(n.s.)') ax3.legend(handles=[sig_patch, ns_patch], loc='lower right', fontsize=9) ax3.set_xlabel('標準化偏回帰係数 (β)', fontsize=12) ax3.set_title(f'図3 重回帰分析:標準化偏回帰係数(目的変数:人口増加率, N={len(df_ols)}, Adj-R²={r2_adj:.3f})', fontsize=11, fontweight='bold') ax3.grid(True, axis='x', alpha=0.3) fig3.tight_layout() fig3.savefig(os.path.join(FIG_DIR, '2021_H5_1_fig3.png'), dpi=150, bbox_inches='tight') plt.close(fig3) print('fig3 saved') |
fig3 saved
import pandas as pd など — 必要なライブラリをまとめて呼び出します。as pd は短い別名(alias)。x if cond else y は三項演算子。リスト内包表記と組み合わせると、forとifを1行で書けます。重回帰分析の結果と地域動態の考察をふまえ、都道府県レベルの人口維持政策として以下を提言する。
| 地域 | 現状(人口動態) | 重点施策 |
|---|---|---|
| 北海道・東北 | 最大減少(-7〜12%) | 転出抑制が最急務。地元就業機会の創出・生活インフラ維持 |
| 中部・近畿(非都市部) | 中程度減少(-3〜7%) | 製造業雇用維持・保育環境充実で現役世代の定着促進 |
| 中国・四国 | 中程度減少(-5〜8%) | 都市部(広島・岡山)への集約と移住受け入れ体制強化 |
| 九州・沖縄 | やや減少(沖縄は増加) | 沖縄の子育て政策(高出生率)を九州本土へ展開 |
| 関東 | 増加継続 | 一極集中の緩和:地方への移住インセンティブ充実 |
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 | reg_cols = ['保育所密度', '合計特殊出生率', '転入率', '転出率', '住居費割合'] y_col_ols = '人口増加率' df_ols = df22[[y_col_ols] + reg_cols].dropna().copy() # 標準化 df_std = (df_ols - df_ols.mean()) / df_ols.std() Y = df_std[y_col_ols] X = sm.add_constant(df_std[reg_cols]) model = sm.OLS(Y, X).fit() print('\n=== OLS 重回帰結果(標準化) ===') print(model.summary()) coef_df = pd.DataFrame({ '変数': reg_cols, '標準化係数': model.params[reg_cols].values, 'p値': model.pvalues[reg_cols].values, '有意': model.pvalues[reg_cols].values < 0.05 }) coef_df = coef_df.sort_values('標準化係数') print('\n係数表:') print(coef_df.to_string(index=False)) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。sort_values('列名', ascending=False) — 指定列で並べ替え(降順)。sm.add_constant(X) — 切片項(定数1の列)を先頭に追加。statsmodelsで必須。sm.OLS(y, X).fit() — 最小二乗法でモデルを推定。model.params, model.pvalues, model.conf_int() で結果取得。.map() は「1対1の置き換え」、.apply() は「関数を当てる」。辞書なら .map()、ロジックなら .apply()。211 212 213 214 | # R²・調整済みR² r2 = model.rsquared r2_adj = model.rsquared_adj print(f'\nR² = {r2:.4f}, Adj-R² = {r2_adj:.4f}, N = {len(df_ols)}') |
=== OLS 重回帰結果(標準化) ===
OLS Regression Results
==============================================================================
Dep. Variable: 人口増加率 R-squared: 0.735
Model: OLS Adj. R-squared: 0.702
Method: Least Squares F-statistic: 22.72
Date: Mon, 18 May 2026 Prob (F-statistic): 7.53e-11
Time: 11:23:50 Log-Likelihood: -34.996
No. Observations: 47 AIC: 81.99
Df Residuals: 41 BIC: 93.09
Df Model: 5
Covariance Type: nonrobust
==============================================================================
coef std err t P>|t| [0.025 0.975]
------------------------------------------------------------------------------
const 5.378e-17 0.080 6.76e-16 1.000 -0.161 0.161
保育所密度 -0.1266 0.108 -1.168 0.249 -0.345 0.092
合計特殊出生率 0.1719 0.105 1.632 0.110 -0.041 0.385
転入率 1.5530 0.219 7.087 0.000 1.110 1.995
転出率 -0.8834 0.207 -4.270 0.000 -1.301 -0.466
住居費割合 0.0547 0.089 0.612 0.544 -0.126 0.235
==============================================================================
Omnibus: 12.638 Durbin-Watson: 1.621
Prob(Omnibus): 0.002 Jarque-Bera (JB): 13.674
Skew: 1.026 Prob(JB): 0.00107
Kurtosis: 4.666 Cond. No. 5.64
==============================================================================
Notes:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
係数表:
変数 標準化係数 p値 有意
転出率 -0.883430 1.131002e-04 True
保育所密度 -0.126552 2.493811e-01 False
住居費割合 0.054677 5.441751e-01 False
合計特殊出生率 0.171877 1.103493e-01 False
転入率 1.552972 1.241517e-08 True
R² = 0.7348, Adj-R² = 0.7024, N = 47[式 for x in リスト] はリスト内包表記。forループでappendする代わりに1行でリストを作れます。215 216 217 218 219 220 221 222 223 224 225 226 | rank_df = df22[['都道府県', '人口増加率', '地域']].dropna().copy() rank_df = rank_df.sort_values('人口増加率', ascending=True).reset_index(drop=True) rank_df['略称'] = rank_df['都道府県'].map(abbr) rank_df['色'] = rank_df.apply( lambda row: ('#e05c5c' if row['人口増加率'] >= 0 else region_colors.get(row['地域'], '#888')), axis=1 ) fig4, ax4 = plt.subplots(figsize=(11, 10)) bars4 = ax4.barh(rank_df['略称'], rank_df['人口増加率'], color=rank_df['色'], edgecolor='white', height=0.7) ax4.axvline(0, color='#333', linewidth=1.2) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。fig, ax = plt.subplots(...) — 図全体(fig)と軸(ax)を作る定番。以降は ax.bar(...) 等で操作。sort_values('列名', ascending=False) — 指定列で並べ替え(降順)。ax.axhline / ax.axvline — 水平/垂直の点線。平均線や基準線として定番。r, p = stats.pearsonr(...) — Pythonは複数戻り値を同時に受け取れる(タプルアンパック)。227 228 229 230 231 232 | # 数値ラベル for bar, val in zip(bars4, rank_df['人口増加率']): ha = 'left' if val >= 0 else 'right' offset = 0.1 if val >= 0 else -0.1 ax4.text(val + offset, bar.get_y() + bar.get_height()/2, f'{val:+.1f}%', va='center', ha=ha, fontsize=8) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。x if cond else y は三項演算子。リスト内包表記と組み合わせると、forとifを1行で書けます。233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 | # 地域カラー凡例 legend_elements = [ mpatches.Patch(facecolor='#e05c5c', label='人口増加(正)'), ] + [ mpatches.Patch(facecolor=region_colors[r], label=r) for r in region_colors ] ax4.legend(handles=legend_elements, loc='lower right', fontsize=8, framealpha=0.9) ax4.set_xlabel('人口増加率(2012→2022年、%)', fontsize=12) ax4.set_title('図4 都道府県別 人口増加率ランキング(2012→2022年)', fontsize=13, fontweight='bold') ax4.grid(True, axis='x', alpha=0.3) fig4.tight_layout() fig4.savefig(os.path.join(FIG_DIR, '2021_H5_1_fig4.png'), dpi=150, bbox_inches='tight') plt.close(fig4) print('fig4 saved') |
fig4 saved
df[col](1列)と df[[col1, col2]](複数列)でカッコの数が違います。リストを渡していると覚えるとミスを減らせます。249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 | print('\n===== HTML埋め込み用統計サマリー =====') print(f'分析対象: 47都道府県 (2022年断面)') print(f'人口増加率 (2012→2022) 平均: {df22["人口増加率"].mean():.2f}%') print(f'人口増加率 最大: {df22["人口増加率"].max():.2f}% ({df22.loc[df22["人口増加率"].idxmax(), "都道府県"]})') print(f'人口増加率 最小: {df22["人口増加率"].min():.2f}% ({df22.loc[df22["人口増加率"].idxmin(), "都道府県"]})') print(f'保育所密度 平均: {df22["保育所密度"].mean():.4f} 施設/千人') print(f'合計特殊出生率 全国平均 (2022): {df22["合計特殊出生率"].mean():.2f}') print(f'純移動率 平均: {df22["純移動率"].mean():.4f}%') pos_pref = (df22['人口増加率'] > 0).sum() print(f'人口増加都道府県数: {pos_pref}都道府県') print(f'\nOLS結果 R²={r2:.4f}, Adj-R²={r2_adj:.4f}') print(f'有意な変数: {coef_df[coef_df["有意"]]["変数"].tolist()}') # 散布図の相関 r_nursery, p_nursery = stats.pearsonr( df_plot['保育所密度'].values, df_plot['合計特殊出生率'].values) print(f'\n保育所密度×合計特殊出生率: r={r_nursery:.3f}, p={p_nursery:.3f}') print('\n===== 完了 =====') |
===== HTML埋め込み用統計サマリー ===== 分析対象: 47都道府県 (2022年断面) 人口増加率 (2012→2022) 平均: -4.87% 人口増加率 最大: 6.08% (東京都) 人口増加率 最小: -12.51% (秋田県) 保育所密度 平均: 0.2758 施設/千人 合計特殊出生率 全国平均 (2022): 1.36 純移動率 平均: -0.1305% 人口増加都道府県数: 7都道府県 OLS結果 R²=0.7348, Adj-R²=0.7024 有意な変数: ['転出率', '転入率'] 保育所密度×合計特殊出生率: r=0.628, p=0.000 ===== 完了 =====
stats.pearsonr(x, y) — Pearson相関係数 r と p値を同時に返します。x if cond else y は三項演算子。リスト内包表記と組み合わせると、forとifを1行で書けます。本研究では、SSDSE-B(47都道府県・2012〜2023年)を用いて、人口減少対策として実施されている移住促進と子育て支援政策の効果を重回帰分析で検証した。
統計分析から得られた示唆は「まず移住促進、次いで子育て支援」という二段階戦略である。転入者を増やし・転出者を減らした上で、保育環境を充実させることで転入者が地域に定着・出産するという好循環を設計することが、人口減少対策として最も効果的と考えられる。
統計分析の解釈で初心者がやりがちな勘違いをまとめます。特に「相関と因果の混同」「p値の過信」は研究現場でもよく起きる落とし穴です。本文を読む前にも、読んだ後にも、目を通してみてください。
統計の基本用語を初心者向けに解説します。本文中で見慣れない言葉が出てきたら、ここに戻って確認してください。
統計手法について「何のためか」「結果をどう読むか」を初心者向けに解説します。
この研究をさらに発展させるための3つの方向性を示します。「今回わかったこと(X)」から「次に検証すべき仮説(Y)」を立て、「具体的に何をするか(Z)」まで考えてみましょう。
学んだだけでは身につきません。実際に手を動かすのが最強の学習方法です。本論文のスクリプトをベースに、以下のチャレンジに挑戦してみてください。難易度別に5つ用意しました。
本論文で学んだ手法は、研究の世界だけでなく、行政・企業・NPO の現場でも様々に活用されています。具体的なシーンを紹介します。
この論文を読んで初心者が抱きやすい疑問に、教育的観点から答えます。