このページの分析を自分で再現するには、以下の手順でデータを準備してください。コードの編集は不要です。
data/raw/ フォルダに入れます。html/figures/ に自動保存されます。
日本は世界有数の長寿国でありながら、健康寿命(日常生活に制限のない期間)には都道府県間で最大3〜5年の差があることが知られている。本研究は、「なぜ健康寿命に地域差が生まれるのか」という問いに対し、生活習慣(食生活)・医療環境(医療機関密度)・高齢化の観点から重回帰分析を用いて実証的に迫った。
まず「健康寿命の地域差:生活習慣・医療環境の重回帰分析」を統計的にとらえることが有効だと考えられる。 その理由は感覚や経験則だけでは、複雑な社会要因の中で「何が本当に効いているか」を見極めにくいからである。 本研究では公開データと統計手法を組み合わせ、この問いに定量的な答えを出すことを目指す。
SSDSE-B 相関分析 OLS重回帰 地域比較 時系列分析
社会・人口統計体系(SSDSE-B-2026)の都道府県別パネルデータを使用。2012〜2023年度の12年間、47都道府県の計564観測を分析に用いた。
健康寿命は直接データに収録されていないため、「保健医療費比率」を代理変数として設計した。
| 変数コード | 変数名 | 計算式・意味 |
|---|---|---|
| A1303 / A1101 | 高齢化率(%) | 65歳以上人口 ÷ 総人口 × 100。加齢による医療需要増加の代理。 |
| L322101 / L3221 | 食料費割合(%) | 食料費 ÷ 消費支出 × 100。食生活の豊かさ・エンゲル係数類似指標。 |
| I510120 / A1101 | 医療機関密度(施設/万人) | 一般病院数 ÷ 総人口 × 10,000。医療アクセスの代理。 |
| log(L3221) | 消費支出_log | 消費支出の対数変換。所得水準・生活水準のコントロール変数。 |
直接測定が困難な概念(健康寿命)を、関連する観測可能な変数(保健医療費比率)で代替するのが代理変数のアイデア。重要なのは「代理変数が本来の概念と正の相関を持つという仮定が妥当か」を明示すること。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | df_raw = pd.read_csv(DATA_B, encoding='cp932', header=1) df_b = df_raw[df_raw['地域コード'].str.match(r'^R\d{5}$', na=False)].copy() # 使用列の数値変換 num_cols = [ '総人口', '65歳以上人口', '消費支出(二人以上の世帯)', '食料費(二人以上の世帯)', '保健医療費(二人以上の世帯)', '一般病院数', ] for c in num_cols: df_b[c] = pd.to_numeric(df_b[c], errors='coerce') df_b['年度'] = pd.to_numeric(df_b['年度'], errors='coerce') |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。pd.read_csv(...) でCSVを読み込みます。encoding='cp932' は日本語Windows由来の文字コード、header=1 は「2行目を列名として使う」。df['地域コード'].str.match(r'^R\d{5}', ...) — 正規表現で「R+数字5桁」の行(47都道府県)だけTrueにし、真偽値で行をフィルタ。[式 for x in リスト] はリスト内包表記。forループでappendする代わりに1行でリストを作れます。16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | df_b['保健医療費比率'] = df_b['保健医療費(二人以上の世帯)'] / df_b['消費支出(二人以上の世帯)'] * 100 df_b['食料費割合'] = df_b['食料費(二人以上の世帯)'] / df_b['消費支出(二人以上の世帯)'] * 100 df_b['高齢化率'] = df_b['65歳以上人口'] / df_b['総人口'] * 100 df_b['医療機関密度'] = df_b['一般病院数'] / df_b['総人口'] * 10000 df_b['消費支出_log'] = np.log(df_b['消費支出(二人以上の世帯)']) # 地域ブロック付与 df_b['地域ブロック'] = df_b['都道府県'].map(REGION_MAP) years = sorted(df_b['年度'].dropna().unique()) print("=" * 60) print("■ データ概要") print("=" * 60) print(f" 総観測数 : {len(df_b)} 行 ({df_b['都道府県'].nunique()} 都道府県 × {len(years)} 年度)") print(f" 期間 : {int(years[0])}〜{int(years[-1])} 年度") print() |
============================================================ ■ データ概要 ============================================================ 総観測数 : 564 行 (47 都道府県 × 12 年度) 期間 : 2012〜2023 年度
r, p = stats.pearsonr(...) — Pythonは複数戻り値を同時に受け取れる(タプルアンパック)。33 34 35 36 37 38 39 40 41 42 | df22 = df_b[df_b['年度'] == 2022].dropna( subset=['保健医療費比率', '高齢化率', '食料費割合', '医療機関密度', '消費支出_log'] ).copy() print("■ 2022年の基本統計") for col in ['保健医療費比率', '高齢化率', '食料費割合', '医療機関密度']: m = df22[col].mean() s = df22[col].std() print(f" {col:<14}: mean={m:.2f}, std={s:.2f}") print() |
■ 2022年の基本統計 保健医療費比率 : mean=4.96, std=0.53 高齢化率 : mean=31.35, std=3.27 食料費割合 : mean=26.47, std=1.39 医療機関密度 : mean=0.69, std=0.28
x if cond else y は三項演算子。リスト内包表記と組み合わせると、forとifを1行で書けます。2012〜2023年度の12年間にわたる保健医療費比率の推移を地域ブロック別に可視化した。北海道・東北、九州・沖縄などの地方ブロックと、関東・中部・近畿などの大都市圏ブロックで傾向の違いを確認する。
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | fig1, ax1 = plt.subplots(figsize=(12, 6)) for region in REGION_ORDER: df_reg = df_b[df_b['地域ブロック'] == region].copy() ts = df_reg.groupby('年度')['保健医療費比率'].mean().sort_index() ax1.plot(ts.index, ts.values, color=REGION_COLORS[region], linewidth=2.2, marker='o', markersize=4.5, label=region) ax1.set_xlabel('年度', fontsize=12) ax1.set_ylabel('保健医療費比率(保健医療費 / 消費支出 × 100)', fontsize=11) ax1.set_title('保健医療費比率の時系列推移(地域ブロック別平均)\n' 'SSDSE-B 2012〜2023年度, 二人以上世帯', fontsize=13, fontweight='bold') ax1.set_xticks(years) ax1.legend(fontsize=9.5, loc='upper left', ncol=2) ax1.grid(True, alpha=0.3, axis='y') ax1.yaxis.set_major_formatter(plt.FuncFormatter(lambda x, _: f'{x:.1f}%')) plt.tight_layout() fig1.savefig(os.path.join(FIG_DIR, '2022_H5_2_fig1_ts_health_ratio.png'), bbox_inches='tight', dpi=150) plt.close(fig1) print("図1保存: 2022_H5_2_fig1_ts_health_ratio.png") |
図1保存: 2022_H5_2_fig1_ts_health_ratio.png
df.groupby('列').apply(関数) — グループごとに関数を適用。時系列や地域別の集計でよく使います。fig, ax = plt.subplots(...) — 図全体(fig)と軸(ax)を作る定番。以降は ax.bar(...) 等で操作。np.cumsum(arr) は累積和、np.linspace(a, b, n) は「aからbを等間隔でn個」。NumPyの定石です。2022年度の断面データを用いて、高齢化率と保健医療費比率の関係を地域ブロック別に色分けした散布図で可視化した。Pearson相関係数と有意性検定も実施している。
| 説明変数 | 相関係数 r | p値 | 有意性 | 解釈 |
|---|---|---|---|---|
| 高齢化率 | -0.379 | 0.009 | ** | 高齢化率が高い県で比率が低い(後述で解説) |
| 食料費割合 | -0.103 | 0.492 | n.s. | 単純相関では有意差なし |
| 医療機関密度 | +0.014 | 0.924 | n.s. | 単純相関では有意差なし |
| 消費支出_log | +0.310 | 0.034 | * | 消費水準が高い県で医療費比率も高い |
相関係数は2変数の線形関係の強さと方向を示す(-1〜+1)。「統計的有意」と「実質的意義(効果量)」は別物であり、n=47では|r|≥0.29程度でp<0.05となる。符号(正負)の方向性も仮説と照合することが重要。
69 70 71 72 73 74 75 | fig2, ax2 = plt.subplots(figsize=(9, 7)) for region in REGION_ORDER: sub = df22[df22['地域ブロック'] == region] ax2.scatter(sub['高齢化率'], sub['保健医療費比率'], color=REGION_COLORS[region], s=65, alpha=0.82, label=region, zorder=3) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。fig, ax = plt.subplots(...) — 図全体(fig)と軸(ax)を作る定番。以降は ax.bar(...) 等で操作。{値:.2f}(小数2桁)、{値:,}(3桁区切り)、{値:>10}(右寄せ10桁)など、覚えると出力が一気に整います。76 77 78 79 80 81 82 83 | # 回帰直線(全体) x_all = df22['高齢化率'].values y_all = df22['保健医療費比率'].values m_fit, b_fit, r_val, p_val, _ = stats.linregress(x_all, y_all) x_line = np.linspace(x_all.min(), x_all.max(), 100) ax2.plot(x_line, m_fit * x_line + b_fit, color='#333333', linewidth=1.8, linestyle='--', label=f'回帰直線 (r={r_val:+.3f}, p={p_val:.3f})', zorder=2) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。stats.linregress(x, y) — 単回帰の傾き・切片・r値・p値・標準誤差を返します。使わない値は _ で受け取り。plt.subplots(figsize=(W, H)) で図サイズ指定、fig.savefig(..., bbox_inches='tight') で余白を自動で詰めて保存。84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | # 代表的な都道府県にラベル for _, row in df22.iterrows(): pref = row['都道府県'] if pref in ['秋田県', '東京都', '沖縄県', '高知県', '神奈川県', '愛知県']: ax2.annotate(pref, xy=(row['高齢化率'], row['保健医療費比率']), xytext=(5, 3), textcoords='offset points', fontsize=8.5, color='#333') ax2.set_xlabel('高齢化率(65歳以上人口 / 総人口 × 100)', fontsize=12) ax2.set_ylabel('保健医療費比率(保健医療費 / 消費支出 × 100)', fontsize=11) ax2.set_title('高齢化率 vs 保健医療費比率(2022年度, 47都道府県)', fontsize=13, fontweight='bold') ax2.legend(fontsize=9, loc='upper left') ax2.grid(True, alpha=0.3) plt.tight_layout() fig2.savefig(os.path.join(FIG_DIR, '2022_H5_2_fig2_scatter_aging.png'), bbox_inches='tight', dpi=150) plt.close(fig2) print("図2保存: 2022_H5_2_fig2_scatter_aging.png") |
図2保存: 2022_H5_2_fig2_scatter_aging.png
for _, row in df.iterrows() — DataFrameを1行ずつ取り出すループ。1点ずつ描画したいときに使用。.dropna() は欠損行を除去、.copy() は独立したコピーを作る。pandasで警告を防ぐ定石。4つの説明変数(高齢化率、食料費割合、医療機関密度、消費支出_log)を同時投入したOLS重回帰モデルを構築し、各変数の独立した効果を推定した。
| 変数 | 標準化係数 | p値 | 有意性 | 解釈 |
|---|---|---|---|---|
| 高齢化率 | -0.079(/1%) | 0.005 | ** | 高齢化率↑→保健医療費比率↓(交絡の抑制後も有意) |
| 食料費割合 | -0.003 | 0.968 | n.s. | 他変数コントロール後は影響なし |
| 医療機関密度 | +0.695 | 0.047 | * | 病院が多い県で保健医療費比率が高い |
| 消費支出_log | +2.059 | 0.122 | n.s. | 単変量有意も多変量では消える(多重共線性の可能性) |
| モデル全体: R² = 0.271, 調整済みR² = 0.201, F = 3.90, p(F) = 0.009 | ||||
非標準化係数は単位が異なる変数間の比較に不向き。標準化係数(各変数をz変換してから回帰)を使うと「どの変数が相対的に強く効いているか」を比較できる。statsmodels では手動でz変換してから回帰するのが一般的。
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 131 132 133 134 135 136 137 138 139 140 141 | fig3, ax3 = plt.subplots(figsize=(9, 5)) # 標準化係数を計算(比較のため) df22_std = df22[x_cols + [y_col]].copy() for c in df22_std.columns: df22_std[c] = (df22_std[c] - df22_std[c].mean()) / df22_std[c].std() X_std = sm.add_constant(df22_std[x_cols]) model_std = sm.OLS(df22_std[y_col], X_std).fit() vars_plot = x_cols coefs = model_std.params[vars_plot].values ci_low = model_std.conf_int().loc[vars_plot, 0].values ci_high = model_std.conf_int().loc[vars_plot, 1].values pvals = model_std.pvalues[vars_plot].values colors_bar = [] for p in pvals: if p < 0.001: colors_bar.append('#C62828') elif p < 0.05: colors_bar.append('#E65100') else: colors_bar.append('#9E9E9E') y_pos = np.arange(len(vars_plot)) ax3.barh(y_pos, coefs, color=colors_bar, alpha=0.82, height=0.55, zorder=3) ax3.errorbar(coefs, y_pos, xerr=[coefs - ci_low, ci_high - coefs], fmt='none', color='#333', capsize=5, linewidth=1.5, zorder=4) ax3.axvline(0, color='black', linewidth=1.2, linestyle='-') ax3.set_yticks(y_pos) ax3.set_yticklabels(vars_plot, fontsize=11) ax3.set_xlabel('標準化回帰係数(95%信頼区間)', fontsize=12) ax3.set_title('OLS重回帰:標準化回帰係数プロット(2022年度)\n' '目的変数:保健医療費比率', fontsize=13, fontweight='bold') |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。fig, ax = plt.subplots(...) — 図全体(fig)と軸(ax)を作る定番。以降は ax.bar(...) 等で操作。ax.axhline / ax.axvline — 水平/垂直の点線。平均線や基準線として定番。sm.add_constant(X) — 切片項(定数1の列)を先頭に追加。statsmodelsで必須。sm.OLS(y, X).fit() — 最小二乗法でモデルを推定。model.params, model.pvalues, model.conf_int() で結果取得。plt.subplots(figsize=(W, H)) で図サイズ指定、fig.savefig(..., bbox_inches='tight') で余白を自動で詰めて保存。142 143 144 145 146 147 148 149 | # 凡例パッチ import matplotlib.patches as mpatches patches = [ mpatches.Patch(color='#C62828', label='p < 0.001 ***'), mpatches.Patch(color='#E65100', label='p < 0.05 *'), mpatches.Patch(color='#9E9E9E', label='n.s.'), ] ax3.legend(handles=patches, fontsize=9, loc='lower right') |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。import pandas as pd など — 必要なライブラリをまとめて呼び出します。as pd は短い別名(alias)。.dropna() は欠損行を除去、.copy() は独立したコピーを作る。pandasで警告を防ぐ定石。150 151 152 153 154 155 156 157 158 159 160 | # p値アノテーション for i, (coef, p) in enumerate(zip(coefs, pvals)): sig = '***' if p < 0.001 else '**' if p < 0.01 else '*' if p < 0.05 else 'n.s.' ax3.text(ci_high[i] + 0.005, i, f' {sig}', va='center', fontsize=10) ax3.grid(True, alpha=0.3, axis='x') plt.tight_layout() fig3.savefig(os.path.join(FIG_DIR, '2022_H5_2_fig3_coef.png'), bbox_inches='tight', dpi=150) plt.close(fig3) print("図3保存: 2022_H5_2_fig3_coef.png") |
図3保存: 2022_H5_2_fig3_coef.png
f"...{x}..." はf-string。文字列の中に {変数} と書くだけで埋め込めて、{x:.2f} のように書式も指定できます。医療機関密度(一般病院数/総人口×1万)の地域ブロック別分布を箱ひげ図で可視化した。重回帰で有意な説明変数となった医療機関密度について、地域間でどのような格差があるかを確認する。
箱ひげ図は中央値・IQR・外れ値を一目で把握できる。ただしデータが少ない場合、個別値が見えないという欠点がある。ジッター(小さなランダム横ずれ)を加えた散布図を重ねることで、データ点の分布をより正確に伝えられる。
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 | import os import warnings 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 warnings.filterwarnings('ignore') 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') — グラフを画面表示せずファイルに保存するためのおまじない。os.makedirs('html/figures', exist_ok=True) — 図の保存先フォルダを作る(既にあってもOK)。f"...{x}..." はf-string。文字列の中に {変数} と書くだけで埋め込めて、{x:.2f} のように書式も指定できます。177 178 179 | plt.rcParams['font.family'] = 'Hiragino Sans' plt.rcParams['axes.unicode_minus'] = False plt.rcParams['figure.dpi'] = 150 |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。plt.rcParams['font.family'] — グラフの日本語表示用フォント指定(Macは Hiragino Sans、Windowsなら Yu Gothic 等)。df['A'] / df['B'] — pandasの列同士の四則演算は要素ごと(element-wise)。forループ不要なのが強み。180 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 209 210 | REGION_MAP = { '北海道': '北海道・東北', '青森県': '北海道・東北', '岩手県': '北海道・東北', '宮城県': '北海道・東北', '秋田県': '北海道・東北', '山形県': '北海道・東北', '福島県': '北海道・東北', '茨城県': '関東', '栃木県': '関東', '群馬県': '関東', '埼玉県': '関東', '千葉県': '関東', '東京都': '関東', '神奈川県': '関東', '新潟県': '中部', '富山県': '中部', '石川県': '中部', '福井県': '中部', '山梨県': '中部', '長野県': '中部', '岐阜県': '中部', '静岡県': '中部', '愛知県': '中部', '三重県': '近畿', '滋賀県': '近畿', '京都府': '近畿', '大阪府': '近畿', '兵庫県': '近畿', '奈良県': '近畿', '和歌山県': '近畿', '鳥取県': '中国・四国', '島根県': '中国・四国', '岡山県': '中国・四国', '広島県': '中国・四国', '山口県': '中国・四国', '徳島県': '中国・四国', '香川県': '中国・四国', '愛媛県': '中国・四国', '高知県': '中国・四国', '福岡県': '九州・沖縄', '佐賀県': '九州・沖縄', '長崎県': '九州・沖縄', '熊本県': '九州・沖縄', '大分県': '九州・沖縄', '宮崎県': '九州・沖縄', '鹿児島県': '九州・沖縄', '沖縄県': '九州・沖縄', } REGION_ORDER = ['北海道・東北', '関東', '中部', '近畿', '中国・四国', '九州・沖縄'] REGION_COLORS = { '北海道・東北': '#1565C0', '関東': '#E65100', '中部': '#2E7D32', '近畿': '#6A1B9A', '中国・四国': '#00838F', '九州・沖縄': '#C62828', } |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。.map() は「1対1の置き換え」、.apply() は「関数を当てる」。辞書なら .map()、ロジックなら .apply()。211 212 213 214 215 216 217 218 219 220 221 | y_col = '保健医療費比率' x_cols = ['高齢化率', '食料費割合', '医療機関密度', '消費支出_log'] print("■ 相関分析(2022年, n=47)") corr_results = {} for xc in x_cols: r, p = stats.pearsonr(df22[xc].dropna(), df22[y_col][df22[xc].notna()]) corr_results[xc] = {'r': r, 'p': p} sig = '***' if p < 0.001 else '**' if p < 0.01 else '*' if p < 0.05 else 'n.s.' print(f" {xc:<16}: r = {r:+.3f} p = {p:.4f} {sig}") print() |
■ 相関分析(2022年, n=47) 高齢化率 : r = -0.379 p = 0.0086 ** 食料費割合 : r = -0.103 p = 0.4921 n.s. 医療機関密度 : r = +0.014 p = 0.9244 n.s. 消費支出_log : r = +0.310 p = 0.0337 *
stats.pearsonr(x, y) — Pearson相関係数 r と p値を同時に返します。df[col](1列)と df[[col1, col2]](複数列)でカッコの数が違います。リストを渡していると覚えるとミスを減らせます。222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 | X_ols = sm.add_constant(df22[x_cols]) model = sm.OLS(df22[y_col], X_ols).fit() print("■ OLS 重回帰結果(2022年)") print(f" R² = {model.rsquared:.4f}, 調整済みR² = {model.rsquared_adj:.4f}, n = {len(df22)}") print(f" F統計量 = {model.fvalue:.2f}, p(F) = {model.f_pvalue:.4f}") print() print(f" {'変数':<16} {'係数':>8} {'標準誤差':>8} {'t値':>7} {'p値':>8} 有意性") print(" " + "-" * 62) for nm, coef, se, t, p in zip( model.params.index, model.params.values, model.bse.values, model.tvalues.values, model.pvalues.values): sig = '***' if p < 0.001 else '**' if p < 0.01 else '*' if p < 0.05 else 'n.s.' print(f" {nm:<16} {coef:>8.4f} {se:>8.4f} {t:>7.3f} {p:>8.4f} {sig}") print() |
■ OLS 重回帰結果(2022年) R² = 0.2708, 調整済みR² = 0.2014, n = 47 F統計量 = 3.90, p(F) = 0.0088 変数 係数 標準誤差 t値 p値 有意性 -------------------------------------------------------------- const -18.8749 17.6078 -1.072 0.2899 n.s. 高齢化率 -0.0786 0.0263 -2.986 0.0047 ** 食料費割合 -0.0026 0.0626 -0.041 0.9675 n.s. 医療機関密度 0.6952 0.3392 2.050 0.0467 * 消費支出_log 2.0586 1.3040 1.579 0.1219 n.s.
sm.add_constant(X) — 切片項(定数1の列)を先頭に追加。statsmodelsで必須。sm.OLS(y, X).fit() — 最小二乗法でモデルを推定。model.params, model.pvalues, model.conf_int() で結果取得。s[:-n]「末尾n文字を除く」/s[n:]「先頭n文字を除く」。スライス [start:stop:step] はリスト・タプル・文字列共通の基本ワザです。240 241 242 243 244 245 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 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 | fig4, ax4 = plt.subplots(figsize=(11, 6)) data_by_region = [] labels_region = [] colors_box = [] for region in REGION_ORDER: vals = df_b[df_b['地域ブロック'] == region]['医療機関密度'].dropna().values data_by_region.append(vals) labels_region.append(region) colors_box.append(REGION_COLORS[region]) bp = ax4.boxplot(data_by_region, labels=labels_region, patch_artist=True, notch=False, widths=0.5, medianprops=dict(color='white', linewidth=2.5), whiskerprops=dict(linewidth=1.5), capprops=dict(linewidth=1.5), flierprops=dict(marker='o', markersize=4, alpha=0.6)) for patch, color in zip(bp['boxes'], colors_box): patch.set_facecolor(color) patch.set_alpha(0.78) for i, (vals, region) in enumerate(zip(data_by_region, labels_region)): jitter = np.random.default_rng(42).uniform(-0.18, 0.18, size=len(vals)) ax4.scatter(np.full(len(vals), i + 1) + jitter, vals, color=REGION_COLORS[region], alpha=0.45, s=20, zorder=3) ax4.set_xlabel('地域ブロック', fontsize=12) ax4.set_ylabel('医療機関密度(一般病院数 / 総人口 × 10,000)', fontsize=11) ax4.set_title('地域ブロック別 医療機関密度の分布\n(SSDSE-B 2012〜2023年度, 47都道府県×12年分)', fontsize=13, fontweight='bold') ax4.grid(True, alpha=0.3, axis='y') plt.xticks(rotation=15, ha='right') plt.tight_layout() fig4.savefig(os.path.join(FIG_DIR, '2022_H5_2_fig4_boxplot_density.png'), bbox_inches='tight', dpi=150) plt.close(fig4) print("図4保存: 2022_H5_2_fig4_boxplot_density.png") print() print("=" * 60) print("■ 全図の生成完了") print(f" 保存先: {FIG_DIR}") print("=" * 60) |
図4保存: 2022_H5_2_fig4_boxplot_density.png ============================================================ ■ 全図の生成完了 保存先: html/figures ============================================================
fig, ax = plt.subplots(...) — 図全体(fig)と軸(ax)を作る定番。以降は ax.bar(...) 等で操作。.dropna() は欠損行を除去、.copy() は独立したコピーを作る。pandasで警告を防ぐ定石。SSDSE-B(都道府県別パネルデータ, 2012〜2023年度)を用いた保健医療費比率の分析から、以下が明らかになった:
| データ・リソース | 出典・説明 |
|---|---|
| SSDSE-B-2026(都道府県別データ) | 統計数理研究所 SSDSE(社会・人口統計体系)。47都道府県×12年度のパネルデータ。 |
| L322106 保健医療費(二人以上の世帯) | 家計調査(総務省統計局)。月間保健医療費支出(円)。 |
| I510120 一般病院数 | 医療施設調査(厚生労働省)。病床20床以上の一般病院の施設数。 |
| A1303 65歳以上人口 / A1101 総人口 | 国勢調査・人口推計(総務省統計局)。 |
本教育用コードは SSDSE-B-2026.csv の実データを使用しています。合成データは一切使用していません。
統計分析の解釈で初心者がやりがちな勘違いをまとめます。特に「相関と因果の混同」「p値の過信」は研究現場でもよく起きる落とし穴です。本文を読む前にも、読んだ後にも、目を通してみてください。
統計の基本用語を初心者向けに解説します。本文中で見慣れない言葉が出てきたら、ここに戻って確認してください。
統計手法について「何のためか」「結果をどう読むか」を初心者向けに解説します。
この研究をさらに発展させるための3つの方向性を示します。「今回わかったこと(X)」から「次に検証すべき仮説(Y)」を立て、「具体的に何をするか(Z)」まで考えてみましょう。
学んだだけでは身につきません。実際に手を動かすのが最強の学習方法です。本論文のスクリプトをベースに、以下のチャレンジに挑戦してみてください。難易度別に5つ用意しました。
本論文で学んだ手法は、研究の世界だけでなく、行政・企業・NPO の現場でも様々に活用されています。具体的なシーンを紹介します。
この論文を読んで初心者が抱きやすい疑問に、教育的観点から答えます。