このページの分析を自分で再現するには、以下の手順でデータを準備してください。コードの編集は不要です。
data/raw/ フォルダに入れます。html/figures/ に自動保存されます。
「何を食べるか」は健康に直結する。食料費支出の割合(いわゆる食料費割合・エンゲル係数に相当する指標)が高い都道府県は、健康関連の医療費支出とどのような関係にあるのか。本研究は SSDSE-B の都道府県別パネルデータを用い、食生活指標と健康アウトカムの関連を多角的に検証する。
まず「食料費支出と健康都道府県別食生活指標の回帰分析」を統計的にとらえることが有効だと考えられる。 その理由は感覚や経験則だけでは、複雑な社会要因の中で「何が本当に効いているか」を見極めにくいからである。 本研究では公開データと統計手法を組み合わせ、この問いに定量的な答えを出すことを目指す。
SSDSE-B 相関分析 OLS回帰 時系列 地域比較
SSDSE-B-2026.csv(社会・人口統計体系 都道府県データ)を使用。47都道府県 × 2012〜2023年(12年間)のパネルデータ。横断面分析は2022年データを使用。
| 変数名 | 定義(計算式) | 単位 | 役割 |
|---|---|---|---|
| 食料費割合 | 食料費(二人以上の世帯)÷ 消費支出(二人以上の世帯)× 100 | % | 主要説明変数(食生活指標) |
| 保健医療費_千円 | 保健医療費(二人以上の世帯)÷ 1,000 | 千円/月 | 目的変数(健康の代理変数) |
| 高齢化率 | 65歳以上人口 ÷ 総人口 × 100 | % | 統制変数(年齢構造) |
| 消費支出_万円 | 消費支出(二人以上の世帯)÷ 10,000 | 万円/月 | 統制変数(生活水準) |
| 医療機関密度 | 一般診療所数 ÷ 総人口 × 10,000 | 施設/万人 | 統制変数(医療供給) |
| 変数 | 平均 | 標準偏差 | 最小 | 中央値 | 最大 |
|---|---|---|---|---|---|
| 食料費割合(%) | 26.47 | 1.39 | 23.30 | 26.53 | 30.51 |
| 保健医療費(千円/月) | 14.39 | 2.01 | 9.41 | 14.49 | 19.11 |
| 高齢化率(%) | 31.35 | 3.27 | 22.81 | 31.42 | 38.60 |
| 消費支出(万円/月) | 28.96 | 1.92 | 24.51 | 28.78 | 32.48 |
| 医療機関密度(施設/万人) | 8.48 | 1.21 | 6.13 | 8.64 | 11.41 |
エンゲル係数 = 食料費 / 消費支出 は19世紀ドイツの統計学者エンゲルが提唱。所得が増えると食料費の絶対額は増えるが、消費支出全体の割合は下がる(=生活が豊かになる)という法則。ただし現代では高級食材志向など「食への高支出」が富裕層でも起こりえる。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | df_raw = pd.read_csv(DATA_B, encoding='cp932', header=1) # 都道府県のみ(地域コードが R + 5桁数字) pref_mask = df_raw['地域コード'].str.match(r'^R\d{5}$', na=False) df_all = df_raw[pref_mask].copy().reset_index(drop=True) # 数値変換 num_cols = [ '総人口', '65歳以上人口', '消費支出(二人以上の世帯)', '食料費(二人以上の世帯)', '保健医療費(二人以上の世帯)', '一般診療所数', ] for c in num_cols: df_all[c] = pd.to_numeric(df_all[c], errors='coerce') |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。pd.read_csv(...) でCSVを読み込みます。encoding='cp932' は日本語Windows由来の文字コード、header=1 は「2行目を列名として使う」。df['地域コード'].str.match(r'^R\d{5}', ...) — 正規表現で「R+数字5桁」の行(47都道府県)だけTrueにし、真偽値で行をフィルタ。df['A'] / df['B'] — pandasの列同士の四則演算は要素ごと(element-wise)。forループ不要なのが強み。17 18 19 20 21 22 23 24 25 26 | # ── 派生変数を計算 ───────────────────────────────────────────── df_all['食料費割合'] = df_all['食料費(二人以上の世帯)'] / df_all['消費支出(二人以上の世帯)'] * 100 df_all['保健医療費_千円'] = df_all['保健医療費(二人以上の世帯)'] / 1000 df_all['高齢化率'] = df_all['65歳以上人口'] / df_all['総人口'] * 100 df_all['消費支出_万円'] = df_all['消費支出(二人以上の世帯)'] / 10000 df_all['医療機関密度'] = df_all['一般診療所数'] / df_all['総人口'] * 10000 print("=" * 65) print(f"■ 全データ: {len(df_all)}行(47都道府県 × 12年間)") print("=" * 65) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。.map() は「1対1の置き換え」、.apply() は「関数を当てる」。辞書なら .map()、ロジックなら .apply()。27 28 29 30 31 32 33 34 35 36 37 | # 2022年断面 df2022 = df_all[df_all['年度'] == 2022].copy().reset_index(drop=True) print(f" 2022年データ: {len(df2022)}都道府県") # 欠損除外(2022年) key_vars = ['食料費割合', '保健医療費_千円', '高齢化率', '消費支出_万円', '医療機関密度'] df2022_clean = df2022.dropna(subset=key_vars).reset_index(drop=True) N = len(df2022_clean) print(f" 欠損除外後: N={N}都道府県") print() print(df2022_clean[['都道府県'] + key_vars].describe().round(2)) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。.describe() — 件数・平均・標準偏差・四分位・最大/最小を一括計算。データの素性チェックに必須。[式 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 62 63 64 65 66 67 68 69 | # ── 地域ブロック区分(全国6ブロック)──────────────────────────── region_map = { '北海道': '北海道・東北', '青森県': '北海道・東北', '岩手県': '北海道・東北', '宮城県': '北海道・東北', '秋田県': '北海道・東北', '山形県': '北海道・東北', '福島県': '北海道・東北', '茨城県': '関東', '栃木県': '関東', '群馬県': '関東', '埼玉県': '関東', '千葉県': '関東', '東京都': '関東', '神奈川県': '関東', '新潟県': '中部', '富山県': '中部', '石川県': '中部', '福井県': '中部', '山梨県': '中部', '長野県': '中部', '岐阜県': '中部', '静岡県': '中部', '愛知県': '中部', '三重県': '近畿', '滋賀県': '近畿', '京都府': '近畿', '大阪府': '近畿', '兵庫県': '近畿', '奈良県': '近畿', '和歌山県': '近畿', '鳥取県': '中国・四国', '島根県': '中国・四国', '岡山県': '中国・四国', '広島県': '中国・四国', '山口県': '中国・四国', '徳島県': '中国・四国', '香川県': '中国・四国', '愛媛県': '中国・四国', '高知県': '中国・四国', '福岡県': '九州・沖縄', '佐賀県': '九州・沖縄', '長崎県': '九州・沖縄', '熊本県': '九州・沖縄', '大分県': '九州・沖縄', '宮崎県': '九州・沖縄', '鹿児島県': '九州・沖縄', '沖縄県': '九州・沖縄', } region_order = ['北海道・東北', '関東', '中部', '近畿', '中国・四国', '九州・沖縄'] region_colors = { '北海道・東北': '#1565C0', '関東': '#C62828', '中部': '#2E7D32', '近畿': '#E65100', '中国・四国': '#6A1B9A', '九州・沖縄': '#00838F', } df_all['地域ブロック'] = df_all['都道府県'].map(region_map) df2022_clean['地域ブロック'] = df2022_clean['都道府県'].map(region_map) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。r, p = stats.pearsonr(...) — Pythonは複数戻り値を同時に受け取れる(タプルアンパック)。70 71 72 73 74 75 76 77 78 | # ── 時系列用データ(全年度)──────────────────────────────────── df_ts = df_all.dropna(subset=['食料費割合', '地域ブロック']).copy() # 相関確認(2022年) print("\n■ 2022年 主要変数間の相関(vs 保健医療費_千円)") for v in ['食料費割合', '高齢化率', '消費支出_万円', '医療機関密度']: r, p = stats.pearsonr(df2022_clean[v], df2022_clean['保健医療費_千円']) sig = '***' if p < 0.001 else '**' if p < 0.01 else '*' if p < 0.05 else 'n.s.' print(f" {v:<18} r={r:>7.4f} p={p:.4f} {sig}") |
=================================================================
■ 全データ: 564行(47都道府県 × 12年間)
=================================================================
2022年データ: 47都道府県
欠損除外後: N=47都道府県
食料費割合 保健医療費_千円 高齢化率 消費支出_万円 医療機関密度
count 47.00 47.00 47.00 47.00 47.00
mean 26.47 14.39 31.35 28.96 8.48
std 1.39 2.01 3.27 1.92 1.21
min 23.30 9.41 22.81 24.51 6.13
25% 25.41 12.57 29.85 27.68 7.70
50% 26.53 14.49 31.42 28.78 8.64
75% 27.30 15.74 33.72 30.23 9.26
max 30.51 19.11 38.60 32.48 11.41
■ 2022年 主要変数間の相関(vs 保健医療費_千円)
食料費割合 r=-0.1937 p=0.1920 n.s.
高齢化率 r=-0.4683 p=0.0009 ***
消費支出_万円 r= 0.6959 p=0.0000 ***
医療機関密度 r= 0.0433 p=0.7728 n.s.stats.pearsonr(x, y) — Pearson相関係数 r と p値を同時に返します。x if cond else y は三項演算子。リスト内包表記と組み合わせると、forとifを1行で書けます。まず食料費割合が近年どのように変化してきたかを確認する。2019〜2020年のコロナ禍や2022年の物価上昇が食料費割合に影響を与えた可能性がある。6地域ブロック別の平均値を時系列でプロットする。
| 地域ブロック | 食料費割合 平均(%) | 特徴 |
|---|---|---|
| 北海道・東北 | 高め(28〜30%) | 農業地帯、所得水準が相対的に低い地域を含む |
| 関東 | 低め(24〜26%) | 東京・神奈川など消費支出が高い大都市圏 |
| 中部 | 中程度(26〜27%) | 製造業が盛んな工業地帯 |
| 近畿 | 中程度(26〜27%) | 大阪・京都など都市と農村が混在 |
| 中国・四国 | 高め(27〜29%) | 高齢化率が高く消費水準が低い地域多い |
| 九州・沖縄 | 高め(28〜31%) | 沖縄の高い食料費割合が特に目立つ |
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | fig1, ax1 = plt.subplots(figsize=(11, 6)) for region in region_order: df_r = df_ts[df_ts['地域ブロック'] == region].groupby('年度')['食料費割合'].mean().sort_index() if len(df_r) == 0: continue ax1.plot(df_r.index, df_r.values, color=region_colors[region], linewidth=2.0, marker='o', markersize=5, label=region) ax1.set_xlabel('年度', fontsize=12) ax1.set_ylabel('食料費割合(%)\n[食料費 / 消費支出 × 100]', fontsize=11) ax1.set_title('食料費割合の地域別推移(2012〜2023年)\n' '6地域ブロック平均値(SSDSE-B実データ)', fontsize=13, fontweight='bold') ax1.legend(fontsize=10, loc='upper right') ax1.grid(True, alpha=0.3) ax1.set_xticks(range(2012, 2024, 2)) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。df.groupby('列').apply(関数) — グループごとに関数を適用。時系列や地域別の集計でよく使います。fig, ax = plt.subplots(...) — 図全体(fig)と軸(ax)を作る定番。以降は ax.bar(...) 等で操作。[式 for x in リスト] はリスト内包表記。forループでappendする代わりに1行でリストを作れます。98 99 100 101 102 103 104 105 106 107 108 109 | # 全国平均を太線で重ね書き df_nat = df_ts.groupby('年度')['食料費割合'].mean().sort_index() ax1.plot(df_nat.index, df_nat.values, color='black', linewidth=2.5, linestyle='--', marker='D', markersize=5, label='全国平均', zorder=10) ax1.legend(fontsize=10, loc='upper right') plt.tight_layout() fig1_path = os.path.join(FIG_DIR, '2022_H5_4_fig1_timeseries.png') fig1.savefig(fig1_path, bbox_inches='tight', dpi=150) plt.close(fig1) print(f"\n図1保存: {os.path.basename(fig1_path)}") |
図1保存: 2022_H5_4_fig1_timeseries.png
df.groupby('列').apply(関数) — グループごとに関数を適用。時系列や地域別の集計でよく使います。r, p = stats.pearsonr(...) — Pythonは複数戻り値を同時に受け取れる(タプルアンパック)。食料費割合(説明変数)と保健医療費(健康の代理変数:目的変数)の関係を2022年の47都道府県データで可視化する。各都道府県をラベル付きでプロットし、単純相関係数を確認する。
| 変数 | 保健医療費との相関係数 r | p値 | 有意性 |
|---|---|---|---|
| 食料費割合 | −0.194 | 0.192 | n.s. |
| 高齢化率 | −0.468 | 0.001 | *** 有意 |
| 消費支出_万円 | +0.696 | <0.001 | *** 有意 |
| 医療機関密度 | +0.043 | 0.773 | n.s. |
111 112 113 114 115 116 117 118 | fig2, ax2 = plt.subplots(figsize=(12, 8)) for region in region_order: mask = df2022_clean['地域ブロック'] == region ax2.scatter(df2022_clean.loc[mask, '食料費割合'], df2022_clean.loc[mask, '保健医療費_千円'], color=region_colors[region], s=60, alpha=0.8, label=region, zorder=3) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。fig, ax = plt.subplots(...) — 図全体(fig)と軸(ax)を作る定番。以降は ax.bar(...) 等で操作。r, p = stats.pearsonr(...) — Pythonは複数戻り値を同時に受け取れる(タプルアンパック)。119 120 121 122 123 124 | # 都道府県ラベル for _, row in df2022_clean.iterrows(): ax2.annotate(row['都道府県'], (row['食料費割合'], row['保健医療費_千円']), fontsize=7.5, alpha=0.85, xytext=(3, 3), textcoords='offset points') |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。for _, row in df.iterrows() — DataFrameを1行ずつ取り出すループ。1点ずつ描画したいときに使用。x if cond else y は三項演算子。リスト内包表記と組み合わせると、forとifを1行で書けます。125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 | # 回帰直線(単相関) x_vals = df2022_clean['食料費割合'].values y_vals_s = df2022_clean['保健医療費_千円'].values z = np.polyfit(x_vals, y_vals_s, 1) xs = np.linspace(x_vals.min() - 0.5, x_vals.max() + 0.5, 200) ax2.plot(xs, np.poly1d(z)(xs), color='gray', linewidth=1.8, linestyle='--', alpha=0.7, zorder=2) r2, p2 = stats.pearsonr(x_vals, y_vals_s) ax2.set_xlabel('食料費割合(%)[食料費 / 消費支出 × 100]', fontsize=12) ax2.set_ylabel('保健医療費(千円/月)', fontsize=12) ax2.set_title(f'食料費割合 vs 保健医療費(2022年・47都道府県)\n' f'Pearson r = {r2:.3f}(p = {p2:.4f})', fontsize=13, fontweight='bold') ax2.legend(fontsize=10, loc='upper right') ax2.grid(True, alpha=0.3) plt.tight_layout() fig2_path = os.path.join(FIG_DIR, '2022_H5_4_fig2_scatter.png') fig2.savefig(fig2_path, bbox_inches='tight', dpi=150) plt.close(fig2) print(f"図2保存: {os.path.basename(fig2_path)}") |
図2保存: 2022_H5_4_fig2_scatter.png
stats.pearsonr(x, y) — Pearson相関係数 r と p値を同時に返します。df[col](1列)と df[[col1, col2]](複数列)でカッコの数が違います。リストを渡していると覚えるとミスを減らせます。単純相関では見えなかった食料費割合の効果を、重回帰分析により交絡変数(高齢化率・消費水準・医療機関密度)を統制したうえで検証する。
| 変数 | 係数 (β) | 標準誤差 | t値 | p値 | 有意性 |
|---|---|---|---|---|---|
| (定数) | 3.202 | 8.006 | 0.400 | 0.691 | n.s. |
| 食料費割合 | −0.139 | 0.160 | −0.868 | 0.391 | n.s. |
| 高齢化率 | −0.201 | 0.071 | −2.847 | 0.007 | ** 有意 |
| 消費支出_万円 | +0.621 | 0.122 | 5.109 | <0.001 | *** 有意 |
| 医療機関密度 | +0.375 | 0.168 | 2.229 | 0.031 | * 有意 |
R² = 0.595、調整済み R² = 0.557、F統計量 = 15.43(p < 0.001)、N = 47都道府県(2022年)
「健康な都道府県」を直接計測するのは困難なため、保健医療費を代理変数(proxy variable)として使う。しかしこのアプローチには重要な注意点がある。
根拠:健康上の問題を抱えた人は医療費がかかる。保健医療費が高い地域は医療需要が高い(=健康問題が多い)可能性。
限界:①医療へのアクセス格差(医療機関が少ない地域は費用がかかっても受診できない)、②高所得者が予防医療に積極的で医療費が高くなるケース、③保険制度の違いなど外部要因の影響。
回帰分析では外れ値(outlier)が推定結果を大きく歪めることがある。特に都道府県データでは東京・沖縄などが外れ値になりやすい。
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 | fig3, ax3 = plt.subplots(figsize=(9, 5)) n_vars = len(ols_varnames) y_pos = np.arange(n_vars) bar_colors = ['#C62828' if p < 0.01 else '#FF8F00' if p < 0.05 else '#9E9E9E' for p in pvals] ax3.barh(y_pos, coefs, color=bar_colors, alpha=0.78, edgecolor='white', height=0.55) ax3.errorbar(coefs, y_pos, xerr=1.96 * ses, fmt='none', color='#333333', capsize=5, linewidth=1.4) ax3.axvline(0, color='gray', linestyle='--', linewidth=1.0) ax3.set_yticks(y_pos) ax3.set_yticklabels(ols_varnames, fontsize=11) ax3.set_xlabel('回帰係数(±1.96×SE)', fontsize=12) ax3.set_title(f'保健医療費(千円)の決定要因 — OLS回帰係数\n' f'R² = {ols_model.rsquared:.3f}、N = {N}都道府県(2022年)', fontsize=12, fontweight='bold') ax3.invert_yaxis() ax3.grid(axis='x', alpha=0.3) legend_handles = [ Patch(color='#C62828', alpha=0.78, label='p < 0.01(有意)'), Patch(color='#FF8F00', alpha=0.78, label='p < 0.05(有意)'), Patch(color='#9E9E9E', alpha=0.78, label='n.s.(非有意)'), ] ax3.legend(handles=legend_handles, fontsize=9, loc='lower right') |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。fig, ax = plt.subplots(...) — 図全体(fig)と軸(ax)を作る定番。以降は ax.bar(...) 等で操作。ax.axhline / ax.axvline — 水平/垂直の点線。平均線や基準線として定番。x if cond else y は三項演算子。リスト内包表記と組み合わせると、forとifを1行で書けます。174 175 176 177 178 179 180 181 182 183 184 185 | # p値ラベル for i, (c, p) in enumerate(zip(coefs, pvals)): sig = '***' if p < 0.001 else '**' if p < 0.01 else '*' if p < 0.05 else '' offset = 0.05 if c >= 0 else -0.05 ax3.text(c + offset, i, sig, va='center', ha='left' if c >= 0 else 'right', fontsize=10, fontweight='bold') plt.tight_layout() fig3_path = os.path.join(FIG_DIR, '2022_H5_4_fig3_coef.png') fig3.savefig(fig3_path, bbox_inches='tight', dpi=150) plt.close(fig3) print(f"図3保存: {os.path.basename(fig3_path)}") |
図3保存: 2022_H5_4_fig3_coef.png
df[col](1列)と df[[col1, col2]](複数列)でカッコの数が違います。リストを渡していると覚えるとミスを減らせます。都道府県を6つの地域ブロックに分類し、食料費割合の分布を箱ひげ図で比較する。地域ブロック間の中央値の差・ばらつき・外れ値の存在を視覚的に確認する。
| 要素 | 意味 | 計算式 |
|---|---|---|
| 箱の中央線 | 中央値(Q2) | データを昇順に並べて50%点 |
| 箱の下端 | 第1四分位数(Q1) | 25%点 |
| 箱の上端 | 第3四分位数(Q3) | 75%点 |
| 箱の幅 | 四分位範囲(IQR) | IQR = Q3 − Q1 |
| ひげの先端 | 最大・最小(外れ値除く) | Q1 − 1.5×IQR〜Q3 + 1.5×IQR |
| ●(丸点) | 外れ値 | ひげの範囲外の観測値 |
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 | import numpy as np import pandas as pd import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt from matplotlib.patches import Patch import statsmodels.api as sm from scipy import stats import warnings warnings.filterwarnings('ignore') plt.rcParams['font.family'] = 'Hiragino Sans' plt.rcParams['axes.unicode_minus'] = False plt.rcParams['figure.dpi'] = 150 import os 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} のように書式も指定できます。206 207 208 209 210 211 212 213 214 215 216 217 | y_ols = df2022_clean['保健医療費_千円'].values X_ols = df2022_clean[['食料費割合', '高齢化率', '消費支出_万円', '医療機関密度']].values X_ols_c = sm.add_constant(X_ols) ols_model = sm.OLS(y_ols, X_ols_c).fit() print("\n■ OLS回帰結果(目的変数: 保健医療費_千円)") print(ols_model.summary2()) ols_varnames = ['食料費割合', '高齢化率', '消費支出_万円', '医療機関密度'] coefs = ols_model.params[1:] ses = ols_model.bse[1:] pvals = ols_model.pvalues[1:] |
■ OLS回帰結果(目的変数: 保健医療費_千円)
Results: Ordinary least squares
=================================================================
Model: OLS Adj. R-squared: 0.557
Dependent Variable: y AIC: 165.3712
Date: 2026-05-18 11:24 BIC: 174.6220
No. Observations: 47 Log-Likelihood: -77.686
Df Model: 4 F-statistic: 15.43
Df Residuals: 42 Prob (F-statistic): 7.65e-08
R-squared: 0.595 Scale: 1.7867
-------------------------------------------------------------------
Coef. Std.Err. t P>|t| [0.025 0.975]
-------------------------------------------------------------------
const 3.2024 8.0059 0.4000 0.6912 -12.9542 19.3590
x1 -0.1387 0.1598 -0.8675 0.3906 -0.4612 0.1839
x2 -0.2013 0.0707 -2.8466 0.0068 -0.3439 -0.0586
x3 0.6212 0.1216 5.1091 0.0000 0.3758 0.8665
x4 0.3746 0.1681 2.2286 0.0312 0.0354 0.7137
-----------------------------------------------------------------
Omnibus: 1.544 Durbin-Watson: 2.110
Prob(Omnibus): 0.462 Jarque-Bera (JB): 1.515
Skew: 0.392 Prob(JB): 0.469
Kurtosis: 2.601 Condition No.: 2094
=================================================================
Notes:
[1] Standard Errors assume that the covariance matrix of the
errors is correctly specified.
[2] The condition number is large, 2.09e+03. This might indicate
that there are strong multicollinearity or other numerical
problems.sm.add_constant(X) — 切片項(定数1の列)を先頭に追加。statsmodelsで必須。sm.OLS(y, X).fit() — 最小二乗法でモデルを推定。model.params, model.pvalues, model.conf_int() で結果取得。.map() は「1対1の置き換え」、.apply() は「関数を当てる」。辞書なら .map()、ロジックなら .apply()。218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 | fig4, ax4 = plt.subplots(figsize=(12, 6)) # 2022年の地域別データ box_data = [] box_labels = [] for region in region_order: vals = df2022_clean.loc[df2022_clean['地域ブロック'] == region, '食料費割合'].dropna().values box_data.append(vals) box_labels.append(f'{region}\n(n={len(vals)})') bp = ax4.boxplot( box_data, patch_artist=True, notch=False, medianprops=dict(color='black', linewidth=2.0), flierprops=dict(marker='o', markersize=5, alpha=0.6), whiskerprops=dict(linewidth=1.4), capprops=dict(linewidth=1.4), ) for patch, region in zip(bp['boxes'], region_order): patch.set_facecolor(region_colors[region]) patch.set_alpha(0.65) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。fig, ax = plt.subplots(...) — 図全体(fig)と軸(ax)を作る定番。以降は ax.bar(...) 等で操作。df[col](1列)と df[[col1, col2]](複数列)でカッコの数が違います。リストを渡していると覚えるとミスを減らせます。239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 | # 全国平均線 national_mean = df2022_clean['食料費割合'].mean() ax4.axhline(national_mean, color='black', linestyle='--', linewidth=1.5, label=f'全国平均 {national_mean:.1f}%') ax4.set_xticklabels(box_labels, fontsize=10) ax4.set_ylabel('食料費割合(%)', fontsize=12) ax4.set_title('地域ブロック別 食料費割合の分布(2022年)\n' '箱ひげ図:中央値・四分位範囲・外れ値(SSDSE-B実データ)', fontsize=13, fontweight='bold') ax4.grid(axis='y', alpha=0.3) ax4.legend(fontsize=10) plt.tight_layout() fig4_path = os.path.join(FIG_DIR, '2022_H5_4_fig4_boxplot.png') fig4.savefig(fig4_path, bbox_inches='tight', dpi=150) plt.close(fig4) print(f"図4保存: {os.path.basename(fig4_path)}") |
図4保存: 2022_H5_4_fig4_boxplot.png
ax.axhline / ax.axvline — 水平/垂直の点線。平均線や基準線として定番。s[:-n]「末尾n文字を除く」/s[n:]「先頭n文字を除く」。スライス [start:stop:step] はリスト・タプル・文字列共通の基本ワザです。257 258 259 260 261 262 263 264 | print("\n" + "=" * 65) print("■ 全図の生成完了(4枚)") print("=" * 65) print(f" fig1_timeseries.png : 食料費割合の地域別時系列(2012〜2023年)") print(f" fig2_scatter.png : 食料費割合 vs 保健医療費 散布図(2022年)") print(f" fig3_coef.png : OLS回帰係数プロット(保健医療費の決定要因)") print(f" fig4_boxplot.png : 地域別 食料費割合 箱ひげ図(6ブロック比較)") print(f" 保存先: {os.path.abspath(FIG_DIR)}") |
================================================================= ■ 全図の生成完了(4枚) ================================================================= fig1_timeseries.png : 食料費割合の地域別時系列(2012〜2023年) fig2_scatter.png : 食料費割合 vs 保健医療費 散布図(2022年) fig3_coef.png : OLS回帰係数プロット(保健医療費の決定要因) fig4_boxplot.png : 地域別 食料費割合 箱ひげ図(6ブロック比較) 保存先: /Users/shimpei/Dropbox/Works_Researches/2026 統計・データ解析コンペ/html/figures
s[:-n]「末尾n文字を除く」/s[n:]「先頭n文字を除く」。スライス [start:stop:step] はリスト・タプル・文字列共通の基本ワザです。「食料費割合が高い地域ほど医療費が低い(健康)」という仮説は、交絡変数を統制すると支持されなかった。これは「統計的有意でない = 効果がない」ではなく、「都道府県レベルのデータでは効果を検出できなかった」と解釈すべき。
より適切な分析には:①個人レベルの食事調査データ(NDB等)の活用、②食品群別支出の分解(野菜・肉・菓子等)、③交差遅延モデルによる因果方向の検証、④疾病別医療費(生活習慣病等)の活用、が考えられる。
| データ・資料 | 出典 |
|---|---|
| SSDSE-B-2026.csv(都道府県データ) | 統計数理研究所・統計センター SSDSE(社会・人口統計体系) |
| 家計調査(食料費・消費支出) | 総務省統計局 家計調査(都道府県庁所在地別) |
| 医療施設調査(一般診療所数) | 厚生労働省 医療施設(静態・動態)調査 |
| 人口推計(65歳以上人口) | 総務省統計局 人口推計 |
本コードは実公的データ(SSDSE-B-2026.csv)を直接使用する教育用再現スクリプト。合成データは使用していない。
統計分析の解釈で初心者がやりがちな勘違いをまとめます。特に「相関と因果の混同」「p値の過信」は研究現場でもよく起きる落とし穴です。本文を読む前にも、読んだ後にも、目を通してみてください。
統計の基本用語を初心者向けに解説します。本文中で見慣れない言葉が出てきたら、ここに戻って確認してください。
統計手法について「何のためか」「結果をどう読むか」を初心者向けに解説します。
この研究をさらに発展させるための3つの方向性を示します。「今回わかったこと(X)」から「次に検証すべき仮説(Y)」を立て、「具体的に何をするか(Z)」まで考えてみましょう。
学んだだけでは身につきません。実際に手を動かすのが最強の学習方法です。本論文のスクリプトをベースに、以下のチャレンジに挑戦してみてください。難易度別に5つ用意しました。
本論文で学んだ手法は、研究の世界だけでなく、行政・企業・NPO の現場でも様々に活用されています。具体的なシーンを紹介します。
この論文を読んで初心者が抱きやすい疑問に、教育的観点から答えます。