このページの分析を自分で再現するには、以下の手順でデータを準備してください。コードの編集は不要です。
data/raw/ フォルダに入れます。html/figures/ に自動保存されます。
「格差社会」という言葉が日本で広く使われるようになって久しい。2021年時点でも、日本の都道府県間には消費支出・家計所得において無視できない差異が存在する。一方、政府は社会保障・福祉支出を通じて、こうした格差の是正を図ってきた。
まず「都道府県別家計所得格差と社会保障支出の効果分析」を統計的にとらえることが有効だと考えられる。 その理由は感覚や経験則だけでは、複雑な社会要因の中で「何が本当に効いているか」を見極めにくいからである。 本研究では公開データと統計手法を組み合わせ、この問いに定量的な答えを出すことを目指す。
本研究では、都道府県別の家計消費支出を所得水準の代理変数として用い、(1) 格差の実態を変動係数・ローレンツ曲線・ジニ係数で定量化し、(2) 大学進学率・有効求人倍率・高齢化率・人口流動性など複数の社会経済変数が所得水準にどう影響するかを重回帰分析で分析する。
格差分析 SSDSE-B 相関分析 重回帰分析 ローレンツ曲線
統計数理研究所が提供する SSDSE-B(社会・人口統計体系データセット B)の2022年度断面データを使用した。47都道府県すべてを対象とする。
| データ | 変数 | 役割 |
|---|---|---|
| 消費支出(二人以上の世帯) | 所得水準の代理変数(目的変数) | 家計の実質購買力を反映 |
| 大学進学率 | 高校卒業者のうち進学者数 / 高校卒業者数 | 人的資本の蓄積 |
| 高齢化率 | 65歳以上人口 / 総人口 | 高齢化の負担・医療需要 |
| 有効求人倍率 | 月間有効求人数 / 月間有効求職者数 | 労働市場の活況度(第三次産業の代理) |
| 転入超過率 | (転入数-転出数)/ 総人口 | 人口移動・経済的魅力度 |
| 指標 | 計算式 | 解釈 |
|---|---|---|
| 変動係数 (CV) | 標準偏差 ÷ 平均 | 値が大きいほど格差が大きい。0に近いほど均等。 |
| 90/10分位数比 | 第90百分位値 ÷ 第10百分位値 | 上位層と下位層の格差倍率。1に近いほど均等。 |
| ジニ係数 | ローレンツ曲線と均等線の囲む面積×2 | 0(完全均等)〜1(完全不均等)。 |
格差を1つの数値で表すのは難しい。変動係数は平均に対する相対的なばらつきを、分位数比は分布の両端を、ジニ係数は全体の分布形状を捉える。それぞれが異なる格差の側面を反映するため、複数の指標を組み合わせて解釈することが重要。
2022年の都道府県別消費支出(二人以上の世帯)のデータから、以下の格差指標が得られた。
| 地域 | 特徴 | 消費支出水準 |
|---|---|---|
| 関東 | 東京・埼玉・神奈川等の大都市圏 | 高い傾向 |
| 中部 | 製造業が盛んな愛知・静岡 | 中〜高 |
| 近畿 | 大阪・京都・兵庫のサービス業 | 中 |
| 北海道・東北 | 農林業・人口減少地域 | 低い傾向 |
| 九州・沖縄 | 観光業・農業・社会保障依存 | 低い傾向 |
| 中国・四国 | 過疎化・高齢化が進む地域 | 低い傾向 |
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 | # ── データ読み込み ────────────────────────────────────────────────── 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) # 2022年断面データ df = df_b[df_b['年度'] == 2022].copy().reset_index(drop=True) |
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ループ不要なのが強み。24 25 26 27 28 29 | # ── 変数の定義と派生変数計算 ────────────────────────────────────────── # 所得代理変数: 消費支出(二人以上の世帯) df['消費支出'] = df['消費支出(二人以上の世帯)'] # 大学進学率 = 高等学校卒業者のうち進学者数 / 高等学校卒業者数 df['大学進学率'] = df['高等学校卒業者のうち進学者数'] / df['高等学校卒業者数'] |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。.map() は「1対1の置き換え」、.apply() は「関数を当てる」。辞書なら .map()、ロジックなら .apply()。30 31 32 33 34 35 36 37 | # 高齢化率 = 65歳以上人口 / 総人口 df['高齢化率'] = df['65歳以上人口'] / df['総人口'] # 有効求人倍率(労働市場の活況 = 第三次産業・経済の代理) df['有効求人倍率'] = df['月間有効求人数(一般)'] / df['月間有効求職者数(一般)'] # 転入超過率(人口移動の活発さ) df['転入超過率'] = (df['転入者数(日本人移動者)'] - df['転出者数(日本人移動者)']) / df['総人口'] |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。[式 for x in リスト] はリスト内包表記。forループでappendする代わりに1行でリストを作れます。38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | # 地域マップ region_map = { '北海道': '北海道・東北', '青森県': '北海道・東北', '岩手県': '北海道・東北', '宮城県': '北海道・東北', '秋田県': '北海道・東北', '山形県': '北海道・東北', '福島県': '北海道・東北', '茨城県': '関東', '栃木県': '関東', '群馬県': '関東', '埼玉県': '関東', '千葉県': '関東', '東京都': '関東', '神奈川県': '関東', '新潟県': '中部', '富山県': '中部', '石川県': '中部', '福井県': '中部', '山梨県': '中部', '長野県': '中部', '岐阜県': '中部', '静岡県': '中部', '愛知県': '中部', '三重県': '近畿', '滋賀県': '近畿', '京都府': '近畿', '大阪府': '近畿', '兵庫県': '近畿', '奈良県': '近畿', '和歌山県': '近畿', '鳥取県': '中国・四国', '島根県': '中国・四国', '岡山県': '中国・四国', '広島県': '中国・四国', '山口県': '中国・四国', '徳島県': '中国・四国', '香川県': '中国・四国', '愛媛県': '中国・四国', '高知県': '中国・四国', '福岡県': '九州・沖縄', '佐賀県': '九州・沖縄', '長崎県': '九州・沖縄', '熊本県': '九州・沖縄', '大分県': '九州・沖縄', '宮崎県': '九州・沖縄', '鹿児島県': '九州・沖縄', '沖縄県': '九州・沖縄' } region_colors = { '北海道・東北': '#4e9af1', '関東': '#e05c5c', '中部': '#f0a500', '近畿': '#5cb85c', '中国・四国': '#9b59b6', '九州・沖縄': '#f39c12' } df['地域'] = df['都道府県'].map(region_map) df['color'] = df['地域'].map(region_colors) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。r, p = stats.pearsonr(...) — Pythonは複数戻り値を同時に受け取れる(タプルアンパック)。62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | # ── 格差指標の計算 ───────────────────────────────────────────────── income = df['消費支出'].values cv = income.std() / income.mean() # 変動係数 p90p10 = np.percentile(income, 90) / np.percentile(income, 10) # 90/10分位数比 # ジニ係数 def gini(x): x = np.sort(x) n = len(x) cumx = np.cumsum(x) return (n + 1 - 2 * np.sum(cumx) / cumx[-1]) / n gini_coef = gini(income) print("=== 格差指標(2022年断面) ===") print(f"平均消費支出: {income.mean():,.0f} 円/月") print(f"変動係数 (CV): {cv:.4f}") print(f"90/10分位数比: {p90p10:.4f}") print(f"ジニ係数: {gini_coef:.4f}") print(f"最大 - {df.loc[df['消費支出'].idxmax(), '都道府県']}: {income.max():,.0f} 円") print(f"最小 - {df.loc[df['消費支出'].idxmin(), '都道府県']}: {income.min():,.0f} 円") |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。gini(arr) — Gini係数(0=完全平等、1=完全不平等)を計算。ソート → 累積和 → 公式という単純実装。x if cond else y は三項演算子。リスト内包表記と組み合わせると、forとifを1行で書けます。83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | # ── 重回帰分析 ───────────────────────────────────────────────────── X_cols = ['大学進学率', '高齢化率', '有効求人倍率', '転入超過率'] X_raw = df[X_cols].copy() X_std = (X_raw - X_raw.mean()) / X_raw.std() Y_raw = df['消費支出'] Y_std = (Y_raw - Y_raw.mean()) / Y_raw.std() X_sm = sm.add_constant(X_std) model = sm.OLS(Y_std, X_sm).fit() print("\n=== 重回帰分析結果(標準化変数) ===") print(model.summary()) coefs = model.params[1:] pvalues = model.pvalues[1:] conf_int = model.conf_int().iloc[1:] print("\n標準化偏回帰係数:") for col, b, p in zip(X_cols, coefs, pvalues): sig = "***" if p < 0.001 else "**" if p < 0.01 else "*" if p < 0.05 else "n.s." print(f" {col}: β={b:.4f}, p={p:.4f} {sig}") print(f"\nR²={model.rsquared:.3f}, 調整済みR²={model.rsquared_adj:.3f}") |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。sm.add_constant(X) — 切片項(定数1の列)を先頭に追加。statsmodelsで必須。sm.OLS(y, X).fit() — 最小二乗法でモデルを推定。model.params, model.pvalues, model.conf_int() で結果取得。df[col](1列)と df[[col1, col2]](複数列)でカッコの数が違います。リストを渡していると覚えるとミスを減らせます。105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | # 相関分析 print("\n=== 相関分析 ===") for col in X_cols: r, p = stats.pearsonr(df[col].dropna(), df.loc[df[col].notna(), '消費支出']) print(f" {col} vs 消費支出: r={r:.4f}, p={p:.4f}") # ── 図1: 都道府県別消費支出ランキング(棒グラフ) ────────────────── df_sorted = df.sort_values('消費支出', ascending=True).reset_index(drop=True) fig, ax = plt.subplots(figsize=(14, 10)) bars = ax.barh( df_sorted['都道府県'], df_sorted['消費支出'] / 1000, color=[region_colors[r] for r in df_sorted['地域']], edgecolor='white', linewidth=0.3 ) ax.axvline(income.mean() / 1000, color='#333', linestyle='--', linewidth=1.5, label=f'全国平均 {income.mean()/1000:.1f}千円') ax.set_xlabel('消費支出(千円/月, 二人以上の世帯)', fontsize=12) ax.set_title('都道府県別 消費支出ランキング(2022年)\n─ 家計所得格差の可視化 ─', fontsize=14, fontweight='bold') ax.legend(fontsize=11, loc='lower right') |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。fig, ax = plt.subplots(...) — 図全体(fig)と軸(ax)を作る定番。以降は ax.bar(...) 等で操作。sort_values('列名', ascending=False) — 指定列で並べ替え(降順)。ax.axhline / ax.axvline — 水平/垂直の点線。平均線や基準線として定番。stats.pearsonr(x, y) — Pearson相関係数 r と p値を同時に返します。s[:-n]「末尾n文字を除く」/s[n:]「先頭n文字を除く」。スライス [start:stop:step] はリスト・タプル・文字列共通の基本ワザです。125 126 127 128 129 130 131 132 133 134 135 136 137 | # 凡例パッチ from matplotlib.patches import Patch legend_elements = [Patch(facecolor=c, label=r) for r, c in region_colors.items()] ax.legend(handles=legend_elements + [ plt.Line2D([0], [0], color='#333', linestyle='--', linewidth=1.5, label=f'全国平均 {income.mean()/1000:.1f}千円') ], fontsize=10, loc='lower right', ncol=2) ax.tick_params(axis='y', labelsize=9) ax.tick_params(axis='x', labelsize=10) ax.set_xlim(200, 350) plt.tight_layout() fig.savefig(os.path.join(FIG_DIR, '2021_H5_5_fig1.png'), bbox_inches='tight') plt.close(fig) |
=== 格差指標(2022年断面) ===
平均消費支出: 289,630 円/月
変動係数 (CV): 0.0655
90/10分位数比: 1.1753
ジニ係数: 0.0371
最大 - 埼玉県: 324,793 円
最小 - 愛媛県: 245,054 円
=== 重回帰分析結果(標準化変数) ===
OLS Regression Results
==============================================================================
Dep. Variable: 消費支出 R-squared: 0.311
Model: OLS Adj. R-squared: 0.245
Method: Least Squares F-statistic: 4.729
Date: Mon, 18 May 2026 Prob (F-statistic): 0.00305
Time: 11:23:52 Log-Likelihood: -57.446
No. Observations: 47 AIC: 124.9
Df Residuals: 42 BIC: 134.1
Df Model: 4
Covariance Type: nonrobust
==============================================================================
coef std err t P>|t| [0.025 0.975]
------------------------------------------------------------------------------
const -6.8e-16 0.127 -5.36e-15 1.000 -0.256 0.256
大学進学率 0.3330 0.161 2.069 0.045 0.008 0.658
高齢化率 0.0240 0.200 0.120 0.905 -0.379 0.427
有効求人倍率 0.2599 0.145 1.788 0.081 -0.033 0.553
転入超過率 0.4020 0.196 2.055 0.046 0.007 0.797
==============================================================================
Omnibus: 1.972 Durbin-Watson: 1.945
Prob(Omnibus): 0.373 Jarque-Bera (JB): 1.256
Skew: -0.385 Prob(JB): 0.534
Kurtosis: 3.220 Cond. No. 3.10
==============================================================================
Notes:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
標準化偏回帰係数:
大学進学率: β=0.3330, p=0.0447 *
高齢化率: β=0.0240, p=0.9048 n.s.
有効求人倍率: β=0.2599, p=0.0810 n.s.
転入超過率: β=0.4020, p=0.0462 *
R²=0.311, 調整済みR²=0.245
=== 相関分析 ===
大学進学率 vs 消費支出: r=0.4464, p=0.0017
高齢化率 vs 消費支出: r=-0.3614, p=0.0126
有効求人倍率 vs 消費支出: r=-0.0198, p=0.8948
転入超過率 vs 消費支出: r=0.4371, p=0.0021import pandas as pd など — 必要なライブラリをまとめて呼び出します。as pd は短い別名(alias)。fig.savefig(..., bbox_inches='tight') — 余白を自動で詰めて保存。plt.close() でメモリ解放。np.cumsum(arr) は累積和、np.linspace(a, b, n) は「aからbを等間隔でn個」。NumPyの定石です。138 139 140 141 142 143 144 145 146 147 148 149 | print("\n図1 保存完了: 2021_H5_5_fig1.png") # ── 図2: ローレンツ曲線 ────────────────────────────────────────── income_sorted = np.sort(income) n = len(income_sorted) lorenz_x = np.concatenate([[0], np.arange(1, n + 1) / n]) lorenz_y = np.concatenate([[0], np.cumsum(income_sorted) / income_sorted.sum()]) fig, ax = plt.subplots(figsize=(8, 7)) ax.plot([0, 1], [0, 1], 'k--', linewidth=1.5, label='完全均等分布線') ax.plot(lorenz_x, lorenz_y, color='#e05c5c', linewidth=2.5, label=f'ローレンツ曲線(ジニ係数={gini_coef:.4f})') ax.fill_between(lorenz_x, lorenz_x, lorenz_y, alpha=0.15, color='#e05c5c', label='格差面積') |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。fig, ax = plt.subplots(...) — 図全体(fig)と軸(ax)を作る定番。以降は ax.bar(...) 等で操作。ax.fill_between(...) — 2つの曲線で囲まれた領域を塗りつぶし。Lorenz曲線の格差面積などを可視化。df['A'] / df['B'] — pandasの列同士の四則演算は要素ごと(element-wise)。forループ不要なのが強み。150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 | # 注目点を追加 idx10 = int(0.1 * n) idx90 = int(0.9 * n) ax.annotate( f'下位10%が得る所得シェア\n= {lorenz_y[idx10]:.1%}', xy=(lorenz_x[idx10], lorenz_y[idx10]), xytext=(0.2, 0.05), arrowprops=dict(arrowstyle='->', color='#333', lw=1.2), fontsize=10, color='#333' ) ax.set_xlabel('都道府県の累積比率(所得の低い順)', fontsize=12) ax.set_ylabel('消費支出の累積シェア', fontsize=12) ax.set_title('ローレンツ曲線:都道府県間消費支出格差(2022年)', fontsize=13, fontweight='bold') ax.legend(fontsize=11, loc='upper left') ax.set_xlim(0, 1); ax.set_ylim(0, 1) ax.grid(True, alpha=0.3) plt.tight_layout() fig.savefig(os.path.join(FIG_DIR, '2021_H5_5_fig2.png'), bbox_inches='tight') plt.close(fig) |
図1 保存完了: 2021_H5_5_fig1.png
fig.savefig(..., bbox_inches='tight') — 余白を自動で詰めて保存。plt.close() でメモリ解放。.map() は「1対1の置き換え」、.apply() は「関数を当てる」。辞書なら .map()、ロジックなら .apply()。消費支出(所得代理)を目的変数とし、大学進学率・高齢化率・有効求人倍率・転入超過率を説明変数とした重回帰分析を実施した。すべての変数を標準化(Z変換)したうえでOLS推定を行い、標準化偏回帰係数(β)として比較する。
| 説明変数 | 相関係数 r | p値 | 有意性 |
|---|---|---|---|
| 大学進学率 | 0.446 | 0.0017 | ** (p<0.01) |
| 転入超過率 | 0.437 | 0.0021 | ** (p<0.01) |
| 高齢化率 | -0.361 | 0.0126 | * (p<0.05) |
| 有効求人倍率 | -0.020 | 0.8948 | n.s. |
| 変数 | 標準化偏回帰係数 β | p値 | 有意性 | 解釈 |
|---|---|---|---|---|
| 大学進学率 | 0.333 | 0.045 | * (p<0.05) | 進学率が高い都道府県ほど所得が高い |
| 転入超過率 | 0.402 | 0.046 | * (p<0.05) | 人が流入する地域は所得水準が高い |
| 高齢化率 | 0.024 | 0.905 | n.s. | 高齢化率の独立効果は限定的 |
| 有効求人倍率 | 0.260 | 0.081 | n.s. (傾向) | 求人倍率の効果は10%水準で有意傾向 |
通常の回帰係数は単位の影響を受けるため、異なる変数の「影響力」を直接比較できない。すべての変数をZ変換(標準化)してから回帰すると、得られる係数β は「その変数が1標準偏差増えたとき、目的変数が何標準偏差変化するか」を示す。これにより単位の異なる変数間の影響力を公平に比較できる。
高齢化率は消費支出と単変量相関では r=−0.361(有意 p<0.05)と負の関連を示すが、重回帰に投入すると β=0.024(n.s.)になる。これは「高齢化率が高い地域は、他の変数(転入超過率・大学進学率)も低い傾向があり、見かけの相関が生じていた」ことを示す。重回帰分析は、他の変数の影響を統制した上での純粋な効果(偏回帰係数)を推定できる。
171 172 173 174 175 176 177 178 179 180 181 182 | print("図2 保存完了: 2021_H5_5_fig2.png") # ── 図3: 有効求人倍率 vs 消費支出(散布図・地域色分け) ────────────── fig, ax = plt.subplots(figsize=(11, 8)) for region, color in region_colors.items(): mask = df['地域'] == region ax.scatter( df.loc[mask, '有効求人倍率'], df.loc[mask, '消費支出'] / 1000, c=color, s=80, alpha=0.85, edgecolors='white', linewidth=0.5, label=region ) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。fig, ax = plt.subplots(...) — 図全体(fig)と軸(ax)を作る定番。以降は ax.bar(...) 等で操作。.map() は「1対1の置き換え」、.apply() は「関数を当てる」。辞書なら .map()、ロジックなら .apply()。183 184 185 186 187 188 189 190 | # 都道府県ラベル for _, row in df.iterrows(): ax.annotate( row['都道府県'].replace('都', '').replace('道', '').replace('府', '').replace('県', ''), (row['有効求人倍率'], row['消費支出'] / 1000), fontsize=7, ha='center', va='bottom', xytext=(0, 4), textcoords='offset points', color='#333' ) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。for _, row in df.iterrows() — DataFrameを1行ずつ取り出すループ。1点ずつ描画したいときに使用。[式 for x in リスト] はリスト内包表記。forループでappendする代わりに1行でリストを作れます。191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 | # 回帰直線 x_reg = df['有効求人倍率'].values y_reg = df['消費支出'].values / 1000 slope, intercept, r_val, p_val, _ = stats.linregress(x_reg, y_reg) x_line = np.linspace(x_reg.min(), x_reg.max(), 100) ax.plot(x_line, slope * x_line + intercept, color='#333', linewidth=1.8, linestyle='--', label=f'回帰直線 (r={r_val:.3f}, p={p_val:.3f})') ax.set_xlabel('有効求人倍率(労働市場の活況度)', fontsize=12) ax.set_ylabel('消費支出(千円/月)', fontsize=12) ax.set_title('有効求人倍率 vs 消費支出(2022年,47都道府県)\n─ 労働市場の強さと家計所得の関係 ─', fontsize=13, fontweight='bold') ax.legend(fontsize=10, loc='upper left', ncol=2) ax.grid(True, alpha=0.25) plt.tight_layout() fig.savefig(os.path.join(FIG_DIR, '2021_H5_5_fig3.png'), bbox_inches='tight') plt.close(fig) |
図2 保存完了: 2021_H5_5_fig2.png
stats.linregress(x, y) — 単回帰の傾き・切片・r値・p値・標準誤差を返します。使わない値は _ で受け取り。fig.savefig(..., bbox_inches='tight') — 余白を自動で詰めて保存。plt.close() でメモリ解放。r, p = stats.pearsonr(...) — Pythonは複数戻り値を同時に受け取れる(タプルアンパック)。格差の大きさを視覚的に示す最も有名なツールが「ローレンツ曲線」とそれから計算される「ジニ係数」である。消費支出の低い都道府県から順に並べ、累積人口比率と累積所得比率の関係を描く。
ローレンツ曲線は、所得の低い順に並べたとき「人口の下位x%が所得全体のy%を得ている」ことを示す。均等分布(すべて同じ所得)なら対角線と一致する。ジニ係数は均等線とローレンツ曲線の間の面積の2倍として定義される。
209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 | print("図3 保存完了: 2021_H5_5_fig3.png") # ── 図4: 標準化偏回帰係数プロット ──────────────────────────────── var_labels = ['大学進学率', '高齢化率', '有効求人倍率', '転入超過率'] betas = coefs.values ci_lo = (betas - conf_int.iloc[:, 0].values) ci_hi = (conf_int.iloc[:, 1].values - betas) colors_bar = ['#e05c5c' if p < 0.05 else '#aaaaaa' for p in pvalues] fig, ax = plt.subplots(figsize=(9, 5)) y_pos = range(len(var_labels)) bars2 = ax.barh(y_pos, betas, xerr=[ci_lo, ci_hi], color=colors_bar, align='center', edgecolor='white', linewidth=0.5, error_kw=dict(ecolor='#555', elinewidth=1.5, capsize=5)) ax.axvline(0, color='#333', linewidth=1.0) ax.set_yticks(y_pos) ax.set_yticklabels(var_labels, fontsize=12) ax.set_xlabel('標準化偏回帰係数 (β) ± 95%CI', fontsize=12) ax.set_title('消費支出(所得)格差の規定要因\n─ 重回帰分析・標準化偏回帰係数(2022年, N=47)─', fontsize=13, fontweight='bold') ax.set_xlim(-0.4, 0.9) ax.grid(True, axis='x', alpha=0.3) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。fig, ax = plt.subplots(...) — 図全体(fig)と軸(ax)を作る定番。以降は ax.bar(...) 等で操作。ax.axhline / ax.axvline — 水平/垂直の点線。平均線や基準線として定番。[式 for x in リスト] はリスト内包表記。forループでappendする代わりに1行でリストを作れます。232 233 234 235 236 237 | # β値をバー上に表示 for i, (b, p) in enumerate(zip(betas, pvalues)): sig_str = '*' if p < 0.05 else '' ax.text(b + (0.04 if b >= 0 else -0.04), i, f'β={b:.3f}{sig_str}', va='center', ha='left' if b >= 0 else 'right', fontsize=10, fontweight='bold') |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。r, p = stats.pearsonr(...) — Pythonは複数戻り値を同時に受け取れる(タプルアンパック)。238 239 240 241 242 243 244 245 246 247 | # 凡例 from matplotlib.patches import Patch as MPatch legend_handles = [ MPatch(facecolor='#e05c5c', label='有意 (p<0.05)'), MPatch(facecolor='#aaaaaa', label='非有意') ] ax.legend(handles=legend_handles, fontsize=10, loc='lower right') plt.tight_layout() fig.savefig(os.path.join(FIG_DIR, '2021_H5_5_fig4.png'), bbox_inches='tight') plt.close(fig) |
図3 保存完了: 2021_H5_5_fig3.png
import pandas as pd など — 必要なライブラリをまとめて呼び出します。as pd は短い別名(alias)。fig.savefig(..., bbox_inches='tight') — 余白を自動で詰めて保存。plt.close() でメモリ解放。x if cond else y は三項演算子。リスト内包表記と組み合わせると、forとifを1行で書けます。本分析の重回帰結果は、都道府県間の所得格差の主な規定要因として「大学進学率」と「転入超過率」を特定した。これらの知見から、以下の政策的含意が導かれる。
| 政策領域 | 具体策 | 期待効果 |
|---|---|---|
| 教育 | 地方奨学金の拡充、地方大学強化 | 大学進学率↑ → 所得↑ |
| 産業・雇用 | 地方への企業誘致、テレワーク推進 | 転入超過率↑ → 所得↑ |
| 社会保障 | 生活保護・医療・介護の充実 | 最下位層の底上げ |
| インフラ | 交通・通信インフラ整備 | 地方の経済アクセス改善 |
249 250 251 252 253 254 255 256 257 258 259 260 261 | print("図4 保存完了: 2021_H5_5_fig4.png") print("\n=== 全図の生成完了 ===") print(f" 図1: 都道府県別消費支出ランキング") print(f" 図2: ローレンツ曲線(ジニ係数={gini_coef:.4f})") print(f" 図3: 有効求人倍率 vs 消費支出(散布図)") print(f" 図4: 標準化偏回帰係数プロット(R²={model.rsquared:.3f})") print(f"\n格差サマリー:") print(f" 変動係数: {cv:.4f}") print(f" 90/10分位数比: {p90p10:.4f}") print(f" ジニ係数: {gini_coef:.4f}") print(f" 最大: {df.loc[df['消費支出'].idxmax(), '都道府県']} ({income.max():,.0f}円)") print(f" 最小: {df.loc[df['消費支出'].idxmin(), '都道府県']} ({income.min():,.0f}円)") |
図4 保存完了: 2021_H5_5_fig4.png === 全図の生成完了 === 図1: 都道府県別消費支出ランキング 図2: ローレンツ曲線(ジニ係数=0.0371) 図3: 有効求人倍率 vs 消費支出(散布図) 図4: 標準化偏回帰係数プロット(R²=0.311) 格差サマリー: 変動係数: 0.0655 90/10分位数比: 1.1753 ジニ係数: 0.0371 最大: 埼玉県 (324,793円) 最小: 愛媛県 (245,054円)
r, p = stats.pearsonr(...) — Pythonは複数戻り値を同時に受け取れる(タプルアンパック)。SSDSE-B の47都道府県・2022年断面データを用いた分析の結果:
| データ | 出典 |
|---|---|
| SSDSE-B-2026 都道府県別統計 | 統計数理研究所 SSDSE(社会・人口統計体系データセット) |
本スクリプトは SSDSE-B-2026.csv の実データのみを使用(合成データ・np.random.seed等は一切使用していない)。
統計分析の解釈で初心者がやりがちな勘違いをまとめます。特に「相関と因果の混同」「p値の過信」は研究現場でもよく起きる落とし穴です。本文を読む前にも、読んだ後にも、目を通してみてください。
統計の基本用語を初心者向けに解説します。本文中で見慣れない言葉が出てきたら、ここに戻って確認してください。
統計手法について「何のためか」「結果をどう読むか」を初心者向けに解説します。
この研究をさらに発展させるための3つの方向性を示します。「今回わかったこと(X)」から「次に検証すべき仮説(Y)」を立て、「具体的に何をするか(Z)」まで考えてみましょう。
学んだだけでは身につきません。実際に手を動かすのが最強の学習方法です。本論文のスクリプトをベースに、以下のチャレンジに挑戦してみてください。難易度別に5つ用意しました。
本論文で学んだ手法は、研究の世界だけでなく、行政・企業・NPO の現場でも様々に活用されています。具体的なシーンを紹介します。
この論文を読んで初心者が抱きやすい疑問に、教育的観点から答えます。