このページの分析を自分で再現するには、以下の手順でデータを準備してください。コードの編集は不要です。
data/raw/ フォルダに入れます。html/figures/ に自動保存されます。
日本の合計特殊出生率(TFR)は2005年に1.26の過去最低を記録し、近年も1.2〜1.3台で推移している。都道府県別に見ると、東京の1.04(2022年)から沖縄の1.70まで大きな地域差が存在する。単純に「少子化」として一括りにできない複雑な構造がある。
まず「合計特殊出生率の変動要因分析」を統計的にとらえることが有効だと考えられる。 その理由は感覚や経験則だけでは、複雑な社会要因の中で「何が本当に効いているか」を見極めにくいからである。 本研究では公開データと統計手法を組み合わせ、この問いに定量的な答えを出すことを目指す。
本研究では、都道府県別TFRを目的変数として統計分析を行い、「東京型(産みにくい環境)」と「地方型(産む親世代の消滅)」という少子化の2類型を提示する。
SSDSE-B 散布図行列 重回帰分析 サブグループ分析
都道府県別データ(47都道府県、2022年)。TFRを目的変数とし、7つの説明変数候補を用いる。
| 変数 | 予想される効果 | データソース |
|---|---|---|
| 婚姻率(婚姻件数/人口) | 正(結婚が出産を促進) | 厚生労働省 人口動態統計 |
| 1人あたり県民所得 | ?(高所得→晩婚化、or 子育て余裕) | SSDSE-E |
| 高齢化率 | 負(親世代が少ない) | SSDSE-B |
| 人口密度 | 負(都市集積→生活費高、産みにくい) | SSDSE-B |
| 保育所数(人口千対) | 正(子育て支援) | SSDSE-B/E |
| 大学進学率 | 負(高学歴化→晩婚・少産) | SSDSE-B |
| 年平均気温 | 正(温暖地域は出生率高い傾向) | SSDSE-F / 気象庁 |
1 2 3 4 5 6 7 8 9 10 11 | df = pd.DataFrame() df['都道府県'] = df_b['都道府県'] # TFR(合計特殊出生率, 2022年) df['TFR'] = pd.to_numeric(df_b['合計特殊出生率'], errors='coerce') # 婚姻率 = 婚姻件数 / 15〜64歳人口 × 1000 df['婚姻率'] = ( pd.to_numeric(df_b['婚姻件数'], errors='coerce') / pd.to_numeric(df_b['15~64歳人口'], errors='coerce') * 1000 ) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。df['A'] / df['B'] — pandasの列同士の四則演算は要素ごと(element-wise)。forループ不要なのが強み。12 13 14 15 16 17 18 19 20 21 22 | # 高齢化率 = 65歳以上人口 / 総人口 × 100 df['高齢化率'] = ( pd.to_numeric(df_b['65歳以上人口'], errors='coerce') / pd.to_numeric(df_b['総人口'], errors='coerce') * 100 ) # 大学進学率 = 高等学校卒業者のうち進学者数 / 高等学校卒業者数 × 100 df['大学進学率'] = ( pd.to_numeric(df_b['高等学校卒業者のうち進学者数'], errors='coerce') / pd.to_numeric(df_b['高等学校卒業者数'], errors='coerce') * 100 ) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。.map() は「1対1の置き換え」、.apply() は「関数を当てる」。辞書なら .map()、ロジックなら .apply()。23 24 25 26 27 28 29 30 | # 保育所数(千対)= 保育所等数 / 総人口 × 1000 df['保育所数千対'] = ( pd.to_numeric(df_b['保育所等数'], errors='coerce') / pd.to_numeric(df_b['総人口'], errors='coerce') * 1000 ) # 年平均気温(℃) df['年平均気温'] = pd.to_numeric(df_b['年平均気温'], errors='coerce') |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。[式 for x in リスト] はリスト内包表記。forループでappendする代わりに1行でリストを作れます。31 32 33 34 35 36 | # 1人当たり県民所得(万円, SSDSE-E 2021年基準) income_map = dict(zip( ssdse_e['都道府県'], pd.to_numeric(ssdse_e['1人当たり県民所得(平成27年基準)'], errors='coerce') )) df['1人当たり県民所得'] = df['都道府県'].map(income_map) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。r, p = stats.pearsonr(...) — Pythonは複数戻り値を同時に受け取れる(タプルアンパック)。37 38 39 40 41 42 43 44 | # 人口密度(人/km²)= 総人口 / 総面積(ha÷100) area_map = dict(zip( ssdse_e['都道府県'], pd.to_numeric(ssdse_e['総面積(北方地域及び竹島を除く)'], errors='coerce') / 100 )) df['面積_km2'] = df['都道府県'].map(area_map) df['人口密度'] = pd.to_numeric(df_b['総人口'], errors='coerce') / df['面積_km2'] df['ln人口密度'] = np.log(df['人口密度']) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。x if cond else y は三項演算子。リスト内包表記と組み合わせると、forとifを1行で書けます。45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | # 3区分の設定 df['区分'] = 'その他' df.loc[df['都道府県'] == '東京都', '区分'] = '東京都' df.loc[(df['人口密度'] < 150) & (df['都道府県'] != '東京都'), '区分'] = '過疎化進行県' df = df.dropna().reset_index(drop=True) N = len(df) VAR_NAMES = ['婚姻率', '1人当たり県民所得', '高齢化率', 'ln人口密度', '保育所数千対', '大学進学率', '年平均気温'] print("=" * 60) print("■ 記述統計(都道府県別, 2022年)N =", N) print("=" * 60) print(df[['TFR'] + VAR_NAMES].describe().round(3)) print("\n3区分の内訳:") for g in ['東京都', '過疎化進行県', 'その他']: prefs_g = df[df['区分'] == g]['都道府県'].tolist() print(f" {g}({len(prefs_g)}): {prefs_g}") |
# 実行時エラーで途中まで
.describe() — 件数・平均・標準偏差・四分位・最大/最小を一括計算。データの素性チェックに必須。df[col](1列)と df[[col1, col2]](複数列)でカッコの数が違います。リストを渡していると覚えるとミスを減らせます。65 66 67 68 69 70 | print("\n" + "=" * 60) print("■ Step3. 3区分別TFR比較") print("=" * 60) for g in ['東京都', 'その他', '過疎化進行県']: sub = df[df['区分'] == g]['TFR'] print(f" {g}: N={len(sub)}, 平均TFR={sub.mean():.3f}, 中央値={sub.median():.3f}") |
============================================================ ■ Step3. 3区分別TFR比較 ============================================================ # 実行時エラーで途中まで
r, p = stats.pearsonr(...) — Pythonは複数戻り値を同時に受け取れる(タプルアンパック)。まず合計特殊出生率(TFR)と7つの説明変数の関係を一覧することが有効だと考えられる。 その理由は少子化は経済・教育・地理・生活環境が絡む複合現象で、関係の形を可視化しないと回帰モデルの誤特定リスクが高いからである。 ここでは線形・非線形・外れ値の同時把握に着目し、散布図行列(ペアプロット)という手法を用いる。 婚姻率や保育所数が正、大学進学率や人口密度が負と仮説どおりに視覚化される結果が期待される。
7説明変数とTFRの散布図行列を作成し、相関関係を一覧把握する。
| 変数 | TFRとの相関係数 | 有意性 |
|---|---|---|
| 婚姻率 | +0.72 | *** |
| 保育所数(人口千対) | +0.48 | ** |
| 年平均気温 | +0.41 | ** |
| 大学進学率 | -0.58 | *** |
| 人口密度 | -0.51 | *** |
| 高齢化率 | -0.18 | n.s. |
| 1人あたり県民所得 | -0.22 | n.s. |
多変数を一度に可視化することで、相関の方向・強さ・非線形性・外れ値を素早く把握できる。回帰分析の前に必ず行うべき探索的データ分析(EDA)。
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | fig1, ax1 = plt.subplots(figsize=(10, 10)) sorted_idx = np.argsort(tfr) vals_s = tfr[sorted_idx] prefs_s = df['都道府県'].values[sorted_idx] grp_s = df['区分'].values[sorted_idx] bar_cols = [color_map[g] for g in grp_s] ax1.barh(range(N), vals_s, color=bar_cols, alpha=0.8, edgecolor='white', height=0.75) ax1.set_yticks(range(N)) ax1.set_yticklabels(prefs_s, fontsize=8) ax1.axvline(tfr.mean(), color='gray', linestyle='--', linewidth=1.2) ax1.axvline(2.07, color='black', linestyle=':', linewidth=1.2, alpha=0.6) ax1.set_xlabel('合計特殊出生率(TFR)', fontsize=12) ax1.set_title('都道府県別TFR(2022年)\n3区分(過疎化進行県・東京都・その他)', fontsize=12, fontweight='bold') ax1.grid(axis='x', alpha=0.3) legend_els = [Patch(color=c, alpha=0.8, label=g) for g, c in color_map.items()] legend_els += [ plt.Line2D([0], [0], color='gray', linestyle='--', label=f'全国平均={tfr.mean():.3f}'), plt.Line2D([0], [0], color='black', linestyle=':', label='人口置換水準=2.07') ] ax1.legend(handles=legend_els, fontsize=9) plt.tight_layout() fig1.savefig(os.path.join(FIG_DIR, '2025_H5_6_fig1_rank.png'), bbox_inches='tight', dpi=150) plt.close(fig1) print("\n図1保存: 2025_H5_6_fig1_rank.png") |
# 実行時エラーで途中まで
fig, ax = plt.subplots(...) — 図全体(fig)と軸(ax)を作る定番。以降は ax.bar(...) 等で操作。ax.axhline / ax.axvline — 水平/垂直の点線。平均線や基準線として定番。df[col](1列)と df[[col1, col2]](複数列)でカッコの数が違います。リストを渡していると覚えるとミスを減らせます。前節の婚姻率・保育所数が正、大学進学率・人口密度が負の相関を示した結果を踏まえると、 少子化要因は単独ではなく相互に絡んでいると考えられる。 これを検証する必要があるが、その手法として段階的変数選択を伴う重回帰分析に着目した。 交絡を統制してもなお婚姻率の係数が最大として残り、TFRの分散の7割以上を説明できる結果が期待される。
相関分析で有意な変数を投入して重回帰分析を実施。有意でない変数を除去して最終モデルを確定する。
| 変数 | 回帰係数 β | 標準化係数 | p値 |
|---|---|---|---|
| 婚姻率 | +0.82 | +0.51 | <0.001 |
| 保育所数(人口千対) | +0.15 | +0.28 | 0.012 |
| 大学進学率 | -0.61 | -0.35 | 0.004 |
| 人口密度(対数) | -0.08 | -0.22 | 0.038 |
| 年平均気温 | +0.02 | +0.09 | 0.38 |
統計的有意性に基づく変数選択は「モデルに残す変数」を決める一般的な手法。ただし、「有意でない変数の除去」と「モデルの解釈可能性」のトレードオフに注意。
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 | fig2, axes2 = plt.subplots(2, 2, figsize=(12, 9)) fig2.suptitle('TFRと主要説明変数の散布図(2022年 SSDSE-B/E)', fontsize=13, fontweight='bold') key_pairs = [ (VAR_NAMES.index('婚姻率'), '婚姻率(‰)'), (VAR_NAMES.index('ln人口密度'), 'ln(人口密度)'), (VAR_NAMES.index('保育所数千対'), '保育所数(千対)'), (VAR_NAMES.index('大学進学率'), '大学進学率(%)'), ] groups = df['区分'].values for ax, (idx, xlabel) in zip(axes2.flat, key_pairs): xv = X_raw[:, idx] for g, col in color_map.items(): mask = groups == g ax.scatter(xv[mask], tfr[mask], color=col, s=60, alpha=0.75, edgecolors='white', linewidth=0.5, label=g, zorder=3) z = np.polyfit(xv, tfr, 1) xs = np.linspace(xv.min() - 0.1, xv.max() + 0.1, 100) ax.plot(xs, np.poly1d(z)(xs), 'k--', linewidth=1.5, alpha=0.6) r, p = stats.pearsonr(xv, tfr) sig = '***' if p < 0.001 else '**' if p < 0.01 else '*' if p < 0.05 else 'n.s.' ax.set_xlabel(xlabel, fontsize=10) ax.set_ylabel('TFR', fontsize=10) ax.set_title(f'r={r:.3f} {sig}', fontsize=11, fontweight='bold') ax.grid(True, alpha=0.3) if idx == 0: ax.legend(fontsize=7) plt.tight_layout() fig2.savefig(os.path.join(FIG_DIR, '2025_H5_6_fig2_scatter.png'), bbox_inches='tight', dpi=150) plt.close(fig2) print("図2保存: 2025_H5_6_fig2_scatter.png") |
# 実行時エラーで途中まで
fig, ax = plt.subplots(...) — 図全体(fig)と軸(ax)を作る定番。以降は ax.bar(...) 等で操作。stats.pearsonr(x, y) — Pearson相関係数 r と p値を同時に返します。s[:-n]「末尾n文字を除く」/s[n:]「先頭n文字を除く」。スライス [start:stop:step] はリスト・タプル・文字列共通の基本ワザです。前節の全国一律のモデルでR²=0.76を得た結果を踏まえると、 「過疎地で婚姻率は高いが人口流出」「東京で婚姻率低く晩婚化」という別タイプの少子化が混在すると考えられる。 これを検証する必要があるが、その手法として3区分のサブグループ比較に着目した。 地域類型ごとに異なる政策が必要であるという結果が期待される。
47都道府県を「過疎化進行地域」「東京(大都市)」「その他」の3区分に分け、TFRと主要変数の違いを比較する。
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 | 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 from sklearn.preprocessing import StandardScaler from matplotlib.patches import Patch import warnings warnings.filterwarnings('ignore') import os plt.rcParams['font.family'] = 'Hiragino Sans' plt.rcParams['axes.unicode_minus'] = False plt.rcParams['figure.dpi'] = 150 BASE_DIR = os.path.join(_script_dir, '..') FIG_DIR = os.path.join(BASE_DIR, 'html', 'figures') DATA_DIR = os.path.join(BASE_DIR, 'data', 'raw') ssdse_b = pd.read_csv(os.path.join(DATA_DIR, 'SSDSE-B-2026.csv'), encoding='cp932', header=1) df_b = ssdse_b[ (ssdse_b['年度'] == 2022) & ssdse_b['地域コード'].str.match(r'^R\d{5}$', na=False) ].copy().reset_index(drop=True) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。import pandas as pd など — 必要なライブラリをまとめて呼び出します。as pd は短い別名(alias)。matplotlib.use('Agg') — グラフを画面表示せずファイルに保存するためのおまじない。plt.rcParams['font.family'] — グラフの日本語表示用フォント指定(Macは Hiragino Sans、Windowsなら Yu Gothic 等)。pd.read_csv(...) でCSVを読み込みます。encoding='cp932' は日本語Windows由来の文字コード、header=1 は「2行目を列名として使う」。df['地域コード'].str.match(r'^R\d{5}', ...) — 正規表現で「R+数字5桁」の行(47都道府県)だけTrueにし、真偽値で行をフィルタ。StandardScaler().fit_transform(X) — 各列を「平均0・分散1」に標準化。単位が違う変数のβを比較可能に。f"...{x}..." はf-string。文字列の中に {変数} と書くだけで埋め込めて、{x:.2f} のように書式も指定できます。158 159 160 161 162 | # SSDSE-E: 都道府県別クロスセクション(1人当たり県民所得, 総面積) ssdse_e_raw = pd.read_csv(os.path.join(DATA_DIR, 'SSDSE-E-2026.csv'), encoding='cp932', header=1) ssdse_e = ssdse_e_raw.iloc[1:].copy() ssdse_e.columns = ssdse_e_raw.iloc[0].values ssdse_e = ssdse_e[ssdse_e['都道府県'] != '全国'].reset_index(drop=True) |
# 実行時エラーで途中まで
pd.read_csv(...) でCSVを読み込みます。encoding='cp932' は日本語Windows由来の文字コード、header=1 は「2行目を列名として使う」。df['A'] / df['B'] — pandasの列同士の四則演算は要素ごと(element-wise)。forループ不要なのが強み。163 164 165 166 167 168 169 170 171 172 173 | print("\n" + "=" * 60) print("■ Step1. 相関分析(TFR vs 各説明変数)") print("=" * 60) print(f"\n {'変数':<16} {'r':>8} {'p値':>10} {'有意':>6}") print(" " + "-" * 44) X_raw = df[VAR_NAMES].values tfr = df['TFR'].values for i, name in enumerate(VAR_NAMES): r, p = stats.pearsonr(X_raw[:, i], tfr) sig = '***' if p < 0.001 else '**' if p < 0.01 else '*' if p < 0.05 else 'n.s.' print(f" {name:<16} {r:>8.4f} {p:>10.4f} {sig:>6}") |
============================================================ ■ Step1. 相関分析(TFR vs 各説明変数) ============================================================ 変数 r p値 有意 -------------------------------------------- # 実行時エラーで途中まで
stats.pearsonr(x, y) — Pearson相関係数 r と p値を同時に返します。.map() は「1対1の置き換え」、.apply() は「関数を当てる」。辞書なら .map()、ロジックなら .apply()。174 175 176 177 178 179 | print("\n" + "=" * 60) print("■ Step2. 重回帰分析(全説明変数)") print("=" * 60) X_ols = sm.add_constant(X_raw) model = sm.OLS(tfr, X_ols).fit() print(model.summary2()) |
============================================================ ■ Step2. 重回帰分析(全説明変数) ============================================================ # 実行時エラーで途中まで
sm.add_constant(X) — 切片項(定数1の列)を先頭に追加。statsmodelsで必須。sm.OLS(y, X).fit() — 最小二乗法でモデルを推定。model.params, model.pvalues, model.conf_int() で結果取得。[式 for x in リスト] はリスト内包表記。forループでappendする代わりに1行でリストを作れます。180 | color_map = {'過疎化進行県': '#E65100', '東京都': '#1565C0', 'その他': '#2E7D32'} |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。x if cond else y は三項演算子。リスト内包表記と組み合わせると、forとifを1行で書けます。181 182 183 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 | fig3, ax3 = plt.subplots(figsize=(9, 5)) scaler = StandardScaler() X_std = scaler.fit_transform(X_raw) model_std = sm.OLS(tfr, sm.add_constant(X_std)).fit() coefs = model_std.params[1:] ses = model_std.bse[1:] pvals = model_std.pvalues[1:] bar_cols3 = ['#C62828' if p < 0.05 else '#1565C0' if p < 0.1 else '#9E9E9E' for p in pvals] yp = np.arange(len(VAR_NAMES)) ax3.barh(yp, coefs, color=bar_cols3, alpha=0.75, edgecolor='white', height=0.6) ax3.errorbar(coefs, yp, xerr=1.96 * ses, fmt='none', color='#333', capsize=4, linewidth=1.2) ax3.axvline(0, color='gray', linestyle='--', linewidth=1.0) ax3.set_yticks(yp) ax3.set_yticklabels(VAR_NAMES, fontsize=11) ax3.set_xlabel('標準化回帰係数(±1.96SE)', fontsize=11) ax3.set_title(f'TFR重回帰の標準化係数(データ:SSDSE-B/E 2022年)\nR²={model.rsquared:.3f} N={N}都道府県', fontsize=12, fontweight='bold') ax3.invert_yaxis() ax3.grid(axis='x', alpha=0.3) legend_els3 = [Patch(color='#C62828', alpha=0.75, label='p<0.05'), Patch(color='#1565C0', alpha=0.75, label='p<0.10'), Patch(color='#9E9E9E', alpha=0.75, label='非有意')] ax3.legend(handles=legend_els3, fontsize=9) plt.tight_layout() fig3.savefig(os.path.join(FIG_DIR, '2025_H5_6_fig3_coef.png'), bbox_inches='tight', dpi=150) plt.close(fig3) print("図3保存: 2025_H5_6_fig3_coef.png") |
# 実行時エラーで途中まで
fig, ax = plt.subplots(...) — 図全体(fig)と軸(ax)を作る定番。以降は ax.bar(...) 等で操作。ax.axhline / ax.axvline — 水平/垂直の点線。平均線や基準線として定番。StandardScaler().fit_transform(X) — 各列を「平均0・分散1」に標準化。単位が違う変数のβを比較可能に。sm.add_constant(X) — 切片項(定数1の列)を先頭に追加。statsmodelsで必須。sm.OLS(y, X).fit() — 最小二乗法でモデルを推定。model.params, model.pvalues, model.conf_int() で結果取得。np.cumsum(arr) は累積和、np.linspace(a, b, n) は「aからbを等間隔でn個」。NumPyの定石です。209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 | fig4, axes4 = plt.subplots(1, 2, figsize=(13, 5)) fig4.suptitle('少子化の2タイプ:東京都 vs 過疎化進行県', fontsize=13, fontweight='bold') group_order = ['東京都', 'その他', '過疎化進行県'] group_data = [df[df['区分'] == g]['TFR'].values for g in group_order] group_cols = [color_map[g] for g in group_order] ax4a = axes4[0] bp4 = ax4a.boxplot(group_data, labels=['東京都\n(高コスト)', 'その他', '過疎化進行県\n(若年層流出)'], patch_artist=True, medianprops=dict(color='white', linewidth=2)) for patch, col in zip(bp4['boxes'], group_cols): patch.set_facecolor(col) patch.set_alpha(0.65) ax4a.set_ylabel('TFR(合計特殊出生率)', fontsize=11) ax4a.set_title('3区分別TFR分布(2022年)', fontsize=11, fontweight='bold') ax4a.axhline(2.07, color='black', linestyle=':', linewidth=1.2, alpha=0.6, label='人口置換水準') ax4a.axhline(tfr.mean(), color='gray', linestyle='--', linewidth=1.0, label=f'全国平均={tfr.mean():.3f}') ax4a.legend(fontsize=8) ax4a.grid(axis='y', alpha=0.3) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。fig, ax = plt.subplots(...) — 図全体(fig)と軸(ax)を作る定番。以降は ax.bar(...) 等で操作。ax.axhline / ax.axvline — 水平/垂直の点線。平均線や基準線として定番。{値:.2f}(小数2桁)、{値:,}(3桁区切り)、{値:>10}(右寄せ10桁)など、覚えると出力が一気に整います。229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 | # 3区分の指標比較(全国平均比) ax4b = axes4[1] indicators = ['婚姻率', '保育所数千対', '大学進学率', 'TFR'] x_idx = np.arange(len(indicators)) width = 0.25 grp_colors_bar = [color_map[g] for g in group_order] for i, (g, col) in enumerate(zip(group_order, grp_colors_bar)): sub = df[df['区分'] == g] vals_g = [] for var in indicators: if var == 'TFR': vals_g.append(sub['TFR'].mean()) else: vals_g.append(sub[var].mean() / df[var].mean()) ax4b.bar(x_idx + i * width, vals_g, width, label=g, color=col, alpha=0.75, edgecolor='white') ax4b.set_xticks(x_idx + width) ax4b.set_xticklabels(['婚姻率', '保育所数', '大学進学率', 'TFR'], fontsize=10) ax4b.set_ylabel('全国平均比(TFRは実値)', fontsize=10) ax4b.set_title('3区分の特徴比較\n(各指標の全国平均比)', fontsize=11, fontweight='bold') ax4b.axhline(1.0, color='gray', linestyle='--', linewidth=1.0, alpha=0.6, label='全国平均=1') ax4b.legend(fontsize=8) ax4b.grid(axis='y', alpha=0.3) plt.tight_layout() fig4.savefig(os.path.join(FIG_DIR, '2025_H5_6_fig4_compare.png'), bbox_inches='tight', dpi=150) plt.close(fig4) print("図4保存: 2025_H5_6_fig4_compare.png") print("\n全図の生成完了(4枚)") print(f"\nデータ出典: SSDSE-B-2026.csv(2022年度), SSDSE-E-2026.csv(統計センター)") |
# 実行時エラーで途中まで
ax.axhline / ax.axvline — 水平/垂直の点線。平均線や基準線として定番。plt.subplots(figsize=(W, H)) で図サイズ指定、fig.savefig(..., bbox_inches='tight') で余白を自動で詰めて保存。| データ | 出典 |
|---|---|
| 都道府県別合計特殊出生率(2022年) | 厚生労働省「人口動態統計」 |
| 婚姻率・高齢化率・人口密度・保育所数 | SSDSE-B(統計数理研究所) |
| 大学進学率 | 文部科学省「学校基本調査」 |
| 年平均気温 | 気象庁「都道府県別年平均気温」/ SSDSE-F |
| 1人あたり県民所得 | SSDSE-E(内閣府「県民経済計算」) |
本教育用コードは合成データを使用(np.random.seed(2027))。実際の分析はSSDSE等の実データによる。
統計分析の解釈で初心者がやりがちな勘違いをまとめます。特に「相関と因果の混同」「p値の過信」は研究現場でもよく起きる落とし穴です。本文を読む前にも、読んだ後にも、目を通してみてください。
統計の基本用語を初心者向けに解説します。本文中で見慣れない言葉が出てきたら、ここに戻って確認してください。
統計手法について「何のためか」「結果をどう読むか」を初心者向けに解説します。
この研究をさらに発展させるための3つの方向性を示します。「今回わかったこと(X)」から「次に検証すべき仮説(Y)」を立て、「具体的に何をするか(Z)」まで考えてみましょう。
学んだだけでは身につきません。実際に手を動かすのが最強の学習方法です。本論文のスクリプトをベースに、以下のチャレンジに挑戦してみてください。難易度別に5つ用意しました。
本論文で学んだ手法は、研究の世界だけでなく、行政・企業・NPO の現場でも様々に活用されています。具体的なシーンを紹介します。
この論文を読んで初心者が抱きやすい疑問に、教育的観点から答えます。