このページの分析を自分で再現するには、以下の手順でデータを準備してください。コードの編集は不要です。
data/raw/ フォルダに入れます。html/figures/ に自動保存されます。
「生まれた地域によって進学機会が異なる」――これは日本社会が長年抱えてきた課題である。 大学進学率は都市部で高く、地方で低い傾向が指摘されてきたが、その背景には所得格差・教育環境・人口構造など 複合的な要因が絡み合っている。本研究では、SSDSE(社会・人口統計体系データセット)の都道府県データを用いて、 大学進学率の地域差を規定する要因を統計的に解明することを目的とする。
まず「地域の所得格差・教育環境と学力・進学率の関係」を統計的にとらえることが有効だと考えられる。 その理由は感覚や経験則だけでは、複雑な社会要因の中で「何が本当に効いているか」を見極めにくいからである。 本研究では公開データと統計手法を組み合わせ、この問いに定量的な答えを出すことを目指す。
SSDSE-B-2026 重回帰分析 標準化偏回帰係数 相関分析 地域ブロック比較
SSDSE-B-2026(社会・人口統計体系データセット B:都道府県別データ)の2022年度断面データを使用。 地域コードが R\d{5} の47都道府県(全国)を分析対象とした。
| データ | 内容 | 対象 | 年度 |
|---|---|---|---|
| SSDSE-B-2026 | 都道府県別 社会・人口統計(112変数) | 47都道府県 | 2022年度(断面) |
| 変数 | 種別 | 元データ列 | 想定方向 |
|---|---|---|---|
| 大学進学率(%) | 目的変数 | 高等学校卒業者のうち進学者数 / 高等学校卒業者数 × 100 | — |
| 教育費(円/月) | 説明変数 | 教育費(二人以上の世帯) | 正(+) |
| 学校数/万人(校) | 説明変数 | (小学校数+中学校数+高等学校数)/ 総人口 × 10000 | ? |
| 消費支出総額(円/月) | 説明変数 | 消費支出(二人以上の世帯) | 正(+) |
| 人口(対数) | 説明変数 | log(総人口) | 正(+) |
| 高齢化率(%) | 説明変数 | 65歳以上人口 / 総人口 × 100 | 負(−) |
| 合計特殊出生率 | 説明変数 | 合計特殊出生率 | 負(−) |
「所得水準」や「都市化度」は直接観測できない概念だが、 消費支出・人口(対数)などの観測可能な変数で近似することができる。 こうした変数を代理変数という。代理変数が元の概念をどれだけ 正確に表現できているかを常に意識することが、統計分析の質を左右する。
1 2 3 | 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 はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。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ループ不要なのが強み。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 | region_map = { '北海道': '北海道・東北', '青森県': '北海道・東北', '岩手県': '北海道・東北', '宮城県': '北海道・東北', '秋田県': '北海道・東北', '山形県': '北海道・東北', '福島県': '北海道・東北', '茨城県': '関東', '栃木県': '関東', '群馬県': '関東', '埼玉県': '関東', '千葉県': '関東', '東京都': '関東', '神奈川県': '関東', '新潟県': '中部', '富山県': '中部', '石川県': '中部', '福井県': '中部', '山梨県': '中部', '長野県': '中部', '岐阜県': '中部', '静岡県': '中部', '愛知県': '中部', '三重県': '近畿', '滋賀県': '近畿', '京都府': '近畿', '大阪府': '近畿', '兵庫県': '近畿', '奈良県': '近畿', '和歌山県': '近畿', '鳥取県': '中国・四国', '島根県': '中国・四国', '岡山県': '中国・四国', '広島県': '中国・四国', '山口県': '中国・四国', '徳島県': '中国・四国', '香川県': '中国・四国', '愛媛県': '中国・四国', '高知県': '中国・四国', '福岡県': '九州・沖縄', '佐賀県': '九州・沖縄', '長崎県': '九州・沖縄', '熊本県': '九州・沖縄', '大分県': '九州・沖縄', '宮崎県': '九州・沖縄', '鹿児島県': '九州・沖縄', '沖縄県': '九州・沖縄' } region_colors = { '北海道・東北': '#4e9af1', '関東': '#e05c5c', '中部': '#f0a500', '近畿': '#5cb85c', '中国・四国': '#9b59b6', '九州・沖縄': '#f39c12' } region_order = ['北海道・東北', '関東', '中部', '近畿', '中国・四国', '九州・沖縄'] |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。.map() は「1対1の置き換え」、.apply() は「関数を当てる」。辞書なら .map()、ロジックなら .apply()。29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | df = df_b[df_b['年度'] == 2022].copy() # 目的変数 df['大学進学率'] = df['高等学校卒業者のうち進学者数'] / df['高等学校卒業者数'] * 100 # 説明変数 df['教育費'] = df['教育費(二人以上の世帯)'] # 円/月 df['消費支出総額'] = df['消費支出(二人以上の世帯)'] # 円/月 df['高齢化率'] = df['65歳以上人口'] / df['総人口'] * 100 # % df['合計特殊出生率'] = df['合計特殊出生率'] df['学校数合計'] = df['小学校数'] + df['中学校数'] + df['高等学校数'] df['学校数_万人'] = df['学校数合計'] / df['総人口'] * 10000 # 校/万人 df['人口対数'] = np.log(df['総人口']) # 都市化の代理 # 地域ブロック付与 df['地域'] = df['都道府県'].map(region_map) # 分析用列の選択(欠損なし確認) analysis_cols = ['都道府県', '地域', '大学進学率', '教育費', '学校数_万人', '消費支出総額', '人口対数', '高齢化率', '合計特殊出生率'] df_ana = df[analysis_cols].dropna().reset_index(drop=True) print(f"分析サンプル数: {len(df_ana)} 都道府県 (2022年度)") |
分析サンプル数: 47 都道府県 (2022年度)
[式 for x in リスト] はリスト内包表記。forループでappendする代わりに1行でリストを作れます。全国平均56.6%に対して、都道府県間の標準偏差は7.0ポイントと、 大学進学率には統計的に無視できない地域差が存在する。 最高(京都府 73.0%)と最低(沖縄県 46.2%)の差は26.8ポイントに達する。
上位10都道府県は関東・近畿に集中しており、下位10県は九州・沖縄・北海道東北に多い。 地域的な偏りが明確に視覚化される。
DS LEARNING POINT 2散布図は2変数間の関係を直感的に把握する最も基本的なツール。 相関係数 r は線形関係の強さと方向を −1〜+1 の数値で示す。 ただし相関関係は因果関係ではない点に注意が必要。
52 53 54 55 56 57 58 59 60 61 62 63 64 | fig1, ax1 = plt.subplots(figsize=(10, 7)) for region in region_order: sub = df_ana[df_ana['地域'] == region] ax1.scatter(sub['教育費'], sub['大学進学率'], color=region_colors[region], label=region, s=70, alpha=0.85, zorder=3) for _, row in sub.iterrows(): pref_short = row['都道府県'].replace('県', '').replace('府', '').replace('都', '').replace('道', '') ax1.annotate(pref_short, xy=(row['教育費'], row['大学進学率']), xytext=(3, 3), textcoords='offset points', fontsize=7.5, color='#333333', alpha=0.9) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。fig, ax = plt.subplots(...) — 図全体(fig)と軸(ax)を作る定番。以降は ax.bar(...) 等で操作。for _, row in df.iterrows() — DataFrameを1行ずつ取り出すループ。1点ずつ描画したいときに使用。df[col](1列)と df[[col1, col2]](複数列)でカッコの数が違います。リストを渡していると覚えるとミスを減らせます。65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | # 回帰直線 slope, intercept, r_val, p_val, se = stats.linregress(df_ana['教育費'], df_ana['大学進学率']) x_line = np.linspace(df_ana['教育費'].min(), df_ana['教育費'].max(), 200) ax1.plot(x_line, intercept + slope * x_line, color='#333333', linewidth=1.8, linestyle='--', alpha=0.8, label=f'回帰直線 (r={r_val:.2f}, p={p_val:.3f})') ax1.set_xlabel('教育費(消費支出内, 円/月)', fontsize=13) ax1.set_ylabel('大学進学率(%)', fontsize=13) ax1.set_title('図1 教育費 vs 大学進学率(47都道府県, 2022年度)', fontsize=14, fontweight='bold') ax1.legend(loc='lower right', fontsize=9, framealpha=0.8) ax1.grid(True, alpha=0.3) ax1.tick_params(labelsize=10) fig1.tight_layout() fig1.savefig(os.path.join(FIG_DIR, '2020_H3_fig1.png'), bbox_inches='tight') plt.close(fig1) print("fig1 saved.") |
fig1 saved.
stats.linregress(x, y) — 単回帰の傾き・切片・r値・p値・標準誤差を返します。使わない値は _ で受け取り。s[:-n]「末尾n文字を除く」/s[n:]「先頭n文字を除く」。スライス [start:stop:step] はリスト・タプル・文字列共通の基本ワザです。重回帰分析の前に、各変数間のPearson相関係数を確認する。 多重共線性(説明変数どうしの強い相関)がある場合、個々の係数推定が不安定になる。
| 変数 | 標準化係数 (β) | t値 | p値 | 有意性 |
|---|---|---|---|---|
| 教育費 | +0.114 | 0.72 | 0.477 | n.s. |
| 学校数/万人 | −0.298 | −1.42 | 0.163 | n.s. |
| 消費支出総額 | +0.081 | 0.55 | 0.588 | n.s. |
| 人口(対数) | −0.201 | −0.94 | 0.353 | n.s. |
| 高齢化率 | −0.339 | −1.69 | 0.100 | n.s. |
| 合計特殊出生率 | −0.326 | −2.12 | 0.040 | * |
|
R² = 0.535, 自由度調整済み R² = 0.465, F(6,40) = 7.67, p < 0.001 * p<.05 n.s. 有意でない(p≥.05) |
||||
偏回帰係数の大きさは変数の単位に依存するため、「教育費(円/月)」と「高齢化率(%)」を そのまま比較することはできない。 標準化偏回帰係数 β は全変数を平均0・標準偏差1に変換してから推定することで、 単位によらない「相対的な影響力」の比較を可能にする。
人口対数と学校数/万人の相関係数は r = −0.77 と強く、これが多重共線性を引き起こしている。 多重共線性があると個々の係数の推定が不安定になり、t値が低くなる(有意でなくなる)。 相関ヒートマップで事前に確認するか、VIF(Variance Inflation Factor)を計算して診断する。
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | df_rank = df_ana.sort_values('大学進学率', ascending=False).reset_index(drop=True) top10 = df_rank.head(10) bottom10 = df_rank.tail(10).sort_values('大学進学率', ascending=True) fig2, axes = plt.subplots(1, 2, figsize=(13, 5.5)) for ax, sub_df, title_str in [ (axes[0], top10, '上位10都道府県'), (axes[1], bottom10, '下位10都道府県') ]: colors = [region_colors[r] for r in sub_df['地域']] bars = ax.barh(sub_df['都道府県'], sub_df['大学進学率'], color=colors, edgecolor='white', height=0.65) for bar, val in zip(bars, sub_df['大学進学率']): ax.text(bar.get_width() + 0.3, bar.get_y() + bar.get_height()/2, f'{val:.1f}%', va='center', fontsize=9) ax.set_xlabel('大学進学率(%)', fontsize=11) ax.set_title(title_str, fontsize=13, fontweight='bold') ax.set_xlim(0, df_ana['大学進学率'].max() * 1.12) ax.grid(axis='x', alpha=0.3) ax.tick_params(labelsize=10) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。fig, ax = plt.subplots(...) — 図全体(fig)と軸(ax)を作る定番。以降は ax.bar(...) 等で操作。sort_values('列名', ascending=False) — 指定列で並べ替え(降順)。s[:-n]「末尾n文字を除く」/s[n:]「先頭n文字を除く」。スライス [start:stop:step] はリスト・タプル・文字列共通の基本ワザです。103 104 105 106 107 108 109 110 111 112 | # 凡例 patches = [mpatches.Patch(color=region_colors[r], label=r) for r in region_order] fig2.legend(handles=patches, loc='lower center', ncol=3, fontsize=9, bbox_to_anchor=(0.5, -0.04), framealpha=0.85) fig2.suptitle('図2 都道府県別大学進学率ランキング(2022年度)', fontsize=14, fontweight='bold', y=1.01) fig2.tight_layout() fig2.savefig(os.path.join(FIG_DIR, '2020_H3_fig2.png'), bbox_inches='tight') plt.close(fig2) print("fig2 saved.") |
fig2 saved.
np.cumsum(arr) は累積和、np.linspace(a, b, n) は「aからbを等間隔でn個」。NumPyの定石です。47都道府県を6地域ブロックに分類し、大学進学率の地域差を比較する。
| 地域ブロック | 平均進学率 | 標準偏差 | 都道府県数 | 全国比較 |
|---|---|---|---|---|
| 近畿 | 63.5% | 6.4% | 7 | +6.9% |
| 関東 | 62.5% | 6.4% | 7 | +5.9% |
| 中部 | 58.7% | 3.6% | 9 | +2.1% |
| 中国・四国 | 55.6% | 5.3% | 9 | −1.0% |
| 北海道・東北 | 50.6% | 2.9% | 7 | −6.0% |
| 九州・沖縄 | 49.6% | 4.0% | 8 | −7.0% |
| 全国平均 | 56.6% | 7.0% | 47 | — |
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 | fig3, ax3 = plt.subplots(figsize=(8.5, 7)) n_vars = len(corr_cols) im = ax3.imshow(corr_mat.values, cmap='RdBu_r', vmin=-1, vmax=1, aspect='auto') ax3.set_xticks(range(n_vars)) ax3.set_yticks(range(n_vars)) ax3.set_xticklabels(corr_labels, fontsize=10) ax3.set_yticklabels(corr_labels, fontsize=10) for i in range(n_vars): for j in range(n_vars): val = corr_mat.values[i, j] text_color = 'white' if abs(val) > 0.6 else 'black' ax3.text(j, i, f'{val:.2f}', ha='center', va='center', fontsize=9.5, color=text_color, fontweight='bold' if abs(val) >= 0.5 else 'normal') cbar = fig3.colorbar(im, ax=ax3, fraction=0.046, pad=0.04) cbar.set_label('Pearson相関係数', fontsize=10) ax3.set_title('図3 教育・所得関連変数のPearson相関ヒートマップ(2022年度)', fontsize=13, fontweight='bold', pad=12) fig3.tight_layout() fig3.savefig(os.path.join(FIG_DIR, '2020_H3_fig3.png'), bbox_inches='tight') plt.close(fig3) print("fig3 saved.") |
fig3 saved.
fig, ax = plt.subplots(...) — 図全体(fig)と軸(ax)を作る定番。以降は ax.bar(...) 等で操作。np.cumsum(arr) は累積和、np.linspace(a, b, n) は「aからbを等間隔でn個」。NumPyの定石です。統計分析の結果をもとに、教育格差の縮小に向けた政策提言を示す。
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 | import os import numpy as np import pandas as pd import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt import matplotlib.patches as mpatches 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} のように書式も指定できます。156 157 158 159 160 161 162 163 164 165 | y_col = '大学進学率' x_cols = ['教育費', '学校数_万人', '消費支出総額', '人口対数', '高齢化率', '合計特殊出生率'] Y = df_ana[y_col] X = df_ana[x_cols] X_sm = sm.add_constant(X) model = sm.OLS(Y, X_sm).fit() print("\n=== OLS 重回帰分析結果 ===") print(model.summary()) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。sm.add_constant(X) — 切片項(定数1の列)を先頭に追加。statsmodelsで必須。sm.OLS(y, X).fit() — 最小二乗法でモデルを推定。model.params, model.pvalues, model.conf_int() で結果取得。r, p = stats.pearsonr(...) — Pythonは複数戻り値を同時に受け取れる(タプルアンパック)。166 167 168 169 170 171 172 173 174 175 176 177 178 179 | # 標準化偏回帰係数 X_std = (X - X.mean()) / X.std() Y_std = (Y - Y.mean()) / Y.std() X_std_sm = sm.add_constant(X_std) model_std = sm.OLS(Y_std, X_std_sm).fit() beta_std = model_std.params.drop('const') pval_std = model_std.pvalues.drop('const') print("\n=== 標準化偏回帰係数 ===") for v in x_cols: sig = '***' if pval_std[v] < 0.001 else ('**' if pval_std[v] < 0.01 else ('*' if pval_std[v] < 0.05 else '')) print(f" {v:12s}: β = {beta_std[v]:+.4f} p = {pval_std[v]:.4f} {sig}") print(f"\nR² = {model.rsquared:.4f}, 自由度調整済みR² = {model.rsquared_adj:.4f}") |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。sm.add_constant(X) — 切片項(定数1の列)を先頭に追加。statsmodelsで必須。sm.OLS(y, X).fit() — 最小二乗法でモデルを推定。model.params, model.pvalues, model.conf_int() で結果取得。x if cond else y は三項演算子。リスト内包表記と組み合わせると、forとifを1行で書けます。180 181 182 183 184 | # 地域別平均進学率 region_mean = df_ana.groupby('地域')['大学進学率'].agg(['mean', 'std', 'count']).reset_index() region_mean.columns = ['地域', '平均', '標準偏差', 'n'] print("\n=== 地域別大学進学率 ===") print(region_mean.to_string(index=False)) |
=== OLS 重回帰分析結果 ===
OLS Regression Results
==============================================================================
Dep. Variable: 大学進学率 R-squared: 0.535
Model: OLS Adj. R-squared: 0.465
Method: Least Squares F-statistic: 7.669
Date: Mon, 18 May 2026 Prob (F-statistic): 1.61e-05
Time: 11:23:35 Log-Likelihood: -139.69
No. Observations: 47 AIC: 293.4
Df Residuals: 40 BIC: 306.3
Df Model: 6
Covariance Type: nonrobust
==============================================================================
coef std err t P>|t| [0.025 0.975]
------------------------------------------------------------------------------
const 122.7400 44.215 2.776 0.008 33.379 212.101
教育費 0.0002 0.000 0.718 0.477 -0.000 0.001
学校数_万人 -2.2821 1.606 -1.421 0.163 -5.528 0.964
消費支出総額 2.946e-05 5.39e-05 0.546 0.588 -7.95e-05 0.000
人口対数 -1.7575 1.869 -0.940 0.353 -5.535 2.020
高齢化率 -0.7273 0.432 -1.685 0.100 -1.600 0.145
合計特殊出生率 -15.2748 7.210 -2.118 0.040 -29.848 -0.702
==============================================================================
Omnibus: 0.979 Durbin-Watson: 1.051
Prob(Omnibus): 0.613 Jarque-Bera (JB): 1.037
Skew: 0.269 Prob(JB): 0.595
Kurtosis: 2.510 Cond. No. 1.73e+07
==============================================================================
Notes:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
[2] The condition number is large, 1.73e+07. This might indicate that there are
strong multicollinearity or other numerical problems.
=== 標準化偏回帰係数 ===
教育費 : β = +0.1141 p = 0.4771
学校数_万人 : β = -0.2975 p = 0.1631
消費支出総額 : β = +0.0807 p = 0.5878
人口対数 : β = -0.2005 p = 0.3527
高齢化率 : β = -0.3394 p = 0.0998
合計特殊出生率 : β = -0.3257 p = 0.0404 *
R² = 0.5350, 自由度調整済みR² = 0.4652
=== 地域別大学進学率 ===
地域 平均 標準偏差 n
中国・四国 55.605576 5.329243 9
中部 58.672623 3.619017 9
九州・沖縄 49.600107 4.017378 8
北海道・東北 50.554095 2.932119 7
近畿 63.522463 6.364033 7
関東 62.490024 6.385505 7df.groupby('列').apply(関数) — グループごとに関数を適用。時系列や地域別の集計でよく使います。df[col](1列)と df[[col1, col2]](複数列)でカッコの数が違います。リストを渡していると覚えるとミスを減らせます。185 186 187 188 189 | corr_cols = ['大学進学率', '教育費', '学校数_万人', '消費支出総額', '人口対数', '高齢化率', '合計特殊出生率'] corr_labels = ['大学\n進学率', '教育費', '学校数\n/万人', '消費\n支出', '人口\n対数', '高齢化\n率', '合計\n出生率'] corr_mat = df_ana[corr_cols].corr() print("\n=== 相関行列 ===") print(corr_mat.round(3).to_string()) |
=== 相関行列 ===
大学進学率 教育費 学校数_万人 消費支出総額 人口対数 高齢化率 合計特殊出生率
大学進学率 1.000 0.494 -0.658 0.446 0.565 -0.588 -0.493
教育費 0.494 1.000 -0.495 0.634 0.548 -0.537 -0.336
学校数_万人 -0.658 -0.495 1.000 -0.487 -0.773 0.760 0.497
消費支出総額 0.446 0.634 -0.487 1.000 0.416 -0.361 -0.336
人口対数 0.565 0.548 -0.773 0.416 1.000 -0.707 -0.613
高齢化率 -0.588 -0.537 0.760 -0.361 -0.707 1.000 0.227
合計特殊出生率 -0.493 -0.336 0.497 -0.336 -0.613 0.227 1.000x if cond else y は三項演算子。リスト内包表記と組み合わせると、forとifを1行で書けます。190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 | var_labels = { '教育費': '教育費\n(消費支出内)', '学校数_万人': '学校数\n/万人', '消費支出総額': '消費支出\n総額', '人口対数': '人口\n(対数)', '高齢化率': '高齢化率', '合計特殊出生率':'合計\n特殊出生率', } # 係数の絶対値で降順ソート beta_sorted = beta_std.reindex(x_cols).sort_values(key=lambda x: x.abs()) labels_sorted = [var_labels[v] for v in beta_sorted.index] pvals_sorted = pval_std.reindex(beta_sorted.index) bar_colors = ['#e05c5c' if b > 0 else '#4e9af1' for b in beta_sorted.values] edge_colors = [] for p in pvals_sorted.values: if p < 0.05: edge_colors.append('#cc0000' if True else '#00008b') else: edge_colors.append('gray') fig4, ax4 = plt.subplots(figsize=(9, 5.5)) bars4 = ax4.barh(labels_sorted, beta_sorted.values, color=bar_colors, edgecolor='white', height=0.6, alpha=0.88) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。fig, ax = plt.subplots(...) — 図全体(fig)と軸(ax)を作る定番。以降は ax.bar(...) 等で操作。sort_values('列名', ascending=False) — 指定列で並べ替え(降順)。{値:.2f}(小数2桁)、{値:,}(3桁区切り)、{値:>10}(右寄せ10桁)など、覚えると出力が一気に整います。214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 | # 有意性マーク for i, (bar, p, b) in enumerate(zip(bars4, pvals_sorted.values, beta_sorted.values)): sig_mark = '***' if p < 0.001 else ('**' if p < 0.01 else ('*' if p < 0.05 else '')) offset = 0.01 if b >= 0 else -0.01 ha_val = 'left' if b >= 0 else 'right' ax4.text(b + offset, bar.get_y() + bar.get_height()/2, f'{b:+.3f} {sig_mark}', va='center', ha=ha_val, fontsize=9) ax4.axvline(0, color='black', linewidth=0.8) ax4.set_xlabel('標準化偏回帰係数 (β)', fontsize=12) ax4.set_title('図4 大学進学率に対する標準化偏回帰係数\n(重回帰OLS, 2022年度, n=47)', fontsize=13, fontweight='bold') ax4.set_xlim(beta_sorted.min() * 1.35, beta_sorted.max() * 1.35) ax4.grid(axis='x', alpha=0.3) ax4.tick_params(axis='y', labelsize=10) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。ax.axhline / ax.axvline — 水平/垂直の点線。平均線や基準線として定番。plt.subplots(figsize=(W, H)) で図サイズ指定、fig.savefig(..., bbox_inches='tight') で余白を自動で詰めて保存。229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 | # 凡例 pos_patch = mpatches.Patch(color='#e05c5c', label='正の効果') neg_patch = mpatches.Patch(color='#4e9af1', label='負の効果') ax4.legend(handles=[pos_patch, neg_patch], fontsize=9, loc='lower right') # R²テキスト ax4.text(0.98, 0.04, f'R²={model.rsquared:.3f}, Adj.R²={model.rsquared_adj:.3f}', transform=ax4.transAxes, ha='right', va='bottom', fontsize=9, color='#555555') ax4.text(0.98, 0.10, '* p<.05 ** p<.01 *** p<.001', transform=ax4.transAxes, ha='right', va='bottom', fontsize=8.5, color='#555555') fig4.tight_layout() fig4.savefig(os.path.join(FIG_DIR, '2020_H3_fig4.png'), bbox_inches='tight') plt.close(fig4) print("fig4 saved.") |
fig4 saved.
.dropna() は欠損行を除去、.copy() は独立したコピーを作る。pandasで警告を防ぐ定石。246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 | print("\n=== HTML用統計値サマリー ===") print(f"全国平均大学進学率: {df_ana['大学進学率'].mean():.1f}%") print(f"最高: {df_rank.iloc[0]['都道府県']} {df_rank.iloc[0]['大学進学率']:.1f}%") print(f"最低: {df_rank.iloc[-1]['都道府県']} {df_rank.iloc[-1]['大学進学率']:.1f}%") print(f"標準偏差: {df_ana['大学進学率'].std():.2f}%") print(f"教育費と進学率の相関: r = {corr_mat.loc['大学進学率','教育費']:.3f}") print(f"消費支出と進学率の相関: r = {corr_mat.loc['大学進学率','消費支出総額']:.3f}") print(f"高齢化率と進学率の相関: r = {corr_mat.loc['大学進学率','高齢化率']:.3f}") print(f"人口対数と進学率の相関: r = {corr_mat.loc['大学進学率','人口対数']:.3f}") print(f"重回帰: R² = {model.rsquared:.4f}, Adj.R² = {model.rsquared_adj:.4f}") print(f"F統計量 p値: {model.f_pvalue:.4f}") print("\n地域別平均:") for _, row in region_mean.iterrows(): print(f" {row['地域']}: {row['平均']:.1f}% (SD={row['標準偏差']:.1f}, n={int(row['n'])})") # 標準化係数(上位3) beta_abs_sorted = beta_std.abs().sort_values(ascending=False) print("\n標準化係数(影響力大→小):") for v in beta_abs_sorted.index: p = pval_std[v] sig = '***' if p < 0.001 else ('**' if p < 0.01 else ('*' if p < 0.05 else 'n.s.')) print(f" {v}: β={beta_std[v]:+.3f} ({sig})") print("\n全図の生成が完了しました。") print(f"保存先: {os.path.abspath(FIG_DIR)}") |
=== HTML用統計値サマリー === 全国平均大学進学率: 56.6% 最高: 京都府 73.0% 最低: 沖縄県 46.2% 標準偏差: 7.01% 教育費と進学率の相関: r = 0.494 消費支出と進学率の相関: r = 0.446 高齢化率と進学率の相関: r = -0.588 人口対数と進学率の相関: r = 0.565 重回帰: R² = 0.5350, Adj.R² = 0.4652 F統計量 p値: 0.0000 地域別平均: 中国・四国: 55.6% (SD=5.3, n=9) 中部: 58.7% (SD=3.6, n=9) 九州・沖縄: 49.6% (SD=4.0, n=8) 北海道・東北: 50.6% (SD=2.9, n=7) 近畿: 63.5% (SD=6.4, n=7) 関東: 62.5% (SD=6.4, n=7) 標準化係数(影響力大→小): 高齢化率: β=-0.339 (n.s.) 合計特殊出生率: β=-0.326 (*) 学校数_万人: β=-0.298 (n.s.) 人口対数: β=-0.201 (n.s.) 教育費: β=+0.114 (n.s.) 消費支出総額: β=+0.081 (n.s.) 全図の生成が完了しました。 保存先: /Users/shimpei/Dropbox/Works_Researches/2026 統計・データ解析コンペ/html/figures
sort_values('列名', ascending=False) — 指定列で並べ替え(降順)。for _, row in df.iterrows() — DataFrameを1行ずつ取り出すループ。1点ずつ描画したいときに使用。plt.subplots(figsize=(W, H)) で図サイズ指定、fig.savefig(..., bbox_inches='tight') で余白を自動で詰めて保存。本研究では、SSDSE-B-2026(47都道府県, 2022年度)を用い、大学進学率の地域差を 重回帰分析・相関分析・地域ブロック比較によって検討した。
| 知見 | 統計的根拠 |
|---|---|
| 大学進学率には26.8ポイントの都道府県間格差がある | 最高:京都府 73.0%、最低:沖縄県 46.2% |
| 教育費・人口規模(都市化)との正の相関が認められる | r = 0.49(教育費)、r = 0.57(人口対数) |
| 高齢化率・学校数/万人との負の相関が認められる | r = −0.59(高齢化率)、r = −0.66(学校数/万人) |
| 重回帰モデルでは合計特殊出生率のみ5%水準で有意 | β = −0.326, p = 0.040; R² = 0.535 |
| 地域ブロック別では近畿・関東が全国平均より約6〜7ポイント高い | 近畿 63.5%、関東 62.5%(全国平均 56.6%) |
使用データ:SSDSE-B-2026(総務省統計局)| 分析:OLS重回帰(statsmodels)、Pearson相関(scipy)| 可視化:matplotlib
統計分析の解釈で初心者がやりがちな勘違いをまとめます。特に「相関と因果の混同」「p値の過信」は研究現場でもよく起きる落とし穴です。本文を読む前にも、読んだ後にも、目を通してみてください。
統計の基本用語を初心者向けに解説します。本文中で見慣れない言葉が出てきたら、ここに戻って確認してください。
統計手法について「何のためか」「結果をどう読むか」を初心者向けに解説します。
この研究をさらに発展させるための3つの方向性を示します。「今回わかったこと(X)」から「次に検証すべき仮説(Y)」を立て、「具体的に何をするか(Z)」まで考えてみましょう。
学んだだけでは身につきません。実際に手を動かすのが最強の学習方法です。本論文のスクリプトをベースに、以下のチャレンジに挑戦してみてください。難易度別に5つ用意しました。
本論文で学んだ手法は、研究の世界だけでなく、行政・企業・NPO の現場でも様々に活用されています。具体的なシーンを紹介します。
この論文を読んで初心者が抱きやすい疑問に、教育的観点から答えます。