このページの分析を自分で再現するには、以下の手順でデータを準備してください。コードの編集は不要です。
data/raw/ フォルダに入れます。html/figures/ に自動保存されます。
気象条件は農業生産や観光需要にとどまらず、家計の日常的な消費行動にも影響を及ぼす可能性がある。 本研究は、都道府県別の気温・降水量などの気象データと、二人以上世帯の消費支出・食料費データを用いて、 その統計的関係を明らかにする。
まず「気象条件と地域経済降水量・気温が消費行動に与える影響」を統計的にとらえることが有効だと考えられる。 その理由は感覚や経験則だけでは、複雑な社会要因の中で「何が本当に効いているか」を見極めにくいからである。 本研究では公開データと統計手法を組み合わせ、この問いに定量的な答えを出すことを目指す。
「気象は誰もコントロールできない」という外生性(exogeneity)の特性から、 気象変数は消費行動の決定要因を分析する際に有用な説明変数となる。 気温が下がれば暖房費・鍋料理需要が増し、降水量が多い地域では外出頻度が低下して 内食(自炊)消費が増加するといった理論的仮説を検証する。
相関分析 OLS回帰 散布図 時系列視点 地域比較
SSDSE-B(社会・人口統計体系 都道府県データ)は、日本の47都道府県について、 人口・気象・産業・家計などの多分野統計を収録した公的統計データセットである。 2022年度の横断面データ(N=47)を使用する。
| 区分 | 変数名 | 単位 | 全国平均 | 役割 |
|---|---|---|---|---|
| 気象変数 (説明変数) |
年平均気温 | ℃ | 16.1 | 主要気象指標 |
| 最高気温(日最高気温の月平均の最高値) | ℃ | 30.8 | 夏季の暑さ指標 | |
| 降水量(年間) | mm | 1,544 | 主要降水指標 | |
| 降水日数(年間) | 日 | 107 | 雨天頻度 | |
| 家計変数 (目的変数) |
消費支出(二人以上の世帯) | 円/月 | 289,556 | 全体の消費活動 |
| 食料費(二人以上の世帯) | 円/月 | 76,580 | 食料消費(内食需要) | |
| 制御変数 | 高齢化率 | % | 31.4 | 人口構造の交絡除去 |
| 総人口 | 万人 | 266 | 規模の交絡除去 |
SSDSE-Bは都道府県×年度のパネルデータ。2022年の横断面を抽出し、分析変数を計算する。
まず気象変数の地域的な分布を把握する。年平均気温は沖縄(23.7℃)が最も高く、 北海道(10.2℃)が最も低い。この温度差は約13.5℃に及び、日本の地理的多様性を反映している。 南北の緯度差だけでなく、海流・標高・都市熱島効果も気温差に影響する。
沖縄・鹿児島・宮崎・高知・熊本。九州・沖縄ブロックが上位を占める。温暖な気候はクーラー需要や飲料消費を押し上げる一方、防寒コスト(暖房・衣料)を低下させる。
北海道・青森・岩手・秋田・山形。東北・北海道ブロックが底位を占める。低温地域では暖房費・鍋料理など温かい食品需要が増し、消費パターンが異なる可能性がある。
1 2 3 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 | df_rank = df_valid[['都道府県', '年平均気温', '地域']].sort_values( '年平均気温', ascending=True).reset_index(drop=True) fig1, ax1 = plt.subplots(figsize=(10, 10)) bar_colors = [region_colors.get(df_rank.loc[i, '地域'], '#888888') for i in df_rank.index] bars = ax1.barh(range(len(df_rank)), df_rank['年平均気温'], color=bar_colors, alpha=0.85, edgecolor='white', height=0.7) ax1.set_yticks(range(len(df_rank))) ax1.set_yticklabels(df_rank['都道府県'], fontsize=9) ax1.set_xlabel('年平均気温(℃)', fontsize=12) ax1.set_title('年平均気温の都道府県別ランキング(2022年)\n' '(出所:SSDSE-B-2026、気象庁)', fontsize=13, fontweight='bold') ax1.grid(axis='x', alpha=0.3) # 数値ラベル for i, (idx, row) in enumerate(df_rank.iterrows()): ax1.text(row['年平均気温'] + 0.1, i, f"{row['年平均気温']:.1f}℃", va='center', ha='left', fontsize=7.5) # 凡例 from matplotlib.patches import Patch legend_handles = [Patch(color=c, alpha=0.85, label=r) for r, c in region_colors.items()] ax1.legend(handles=legend_handles, fontsize=8, loc='lower right', title='地域', title_fontsize=9) plt.tight_layout() fig1.savefig(os.path.join(FIG_DIR, '2022_H5_3_fig1_temp_rank.png'), bbox_inches='tight', dpi=150) plt.close(fig1) print("\n図1保存: 2022_H5_3_fig1_temp_rank.png") |
図1保存: 2022_H5_3_fig1_temp_rank.png
import pandas as pd など — 必要なライブラリをまとめて呼び出します。as pd は短い別名(alias)。fig, ax = plt.subplots(...) — 図全体(fig)と軸(ax)を作る定番。以降は ax.bar(...) 等で操作。sort_values('列名', ascending=False) — 指定列で並べ替え(降順)。for _, row in df.iterrows() — DataFrameを1行ずつ取り出すループ。1点ずつ描画したいときに使用。.map() は「1対1の置き換え」、.apply() は「関数を当てる」。辞書なら .map()、ロジックなら .apply()。年平均気温と月間消費支出の関係を散布図で可視化する。各都道府県を地域ブロック別に色分けし、 回帰直線を重ね書きすることで全体的なトレンドを確認する。
| 気象変数 | vs 消費支出(r) | p値 | vs 食料費(r) | p値 |
|---|---|---|---|---|
| 年平均気温 | −0.097 | n.s. | −0.186 | n.s. |
| 最高気温 | +0.129 | n.s. | −0.128 | n.s. |
| 降水日数(年間) | −0.147 | n.s. | +0.047 | n.s. |
| 降水量(年間) | −0.076 | n.s. | +0.008 | n.s. |
気象変数は経済学・疫学でよく使われる「自然実験(natural experiment)」の道具である。 なぜなら、気温・降水量は人間の意思決定に支配されない「外生変数」だからだ。
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | fig2, ax2 = plt.subplots(figsize=(9, 6)) for reg, grp in df_valid.groupby('地域'): ax2.scatter(grp['年平均気温'], grp['消費支出_万円'], color=region_colors.get(reg, '#888888'), label=reg, s=70, alpha=0.85, zorder=3) # 都道府県名ラベル for _, row in df_valid.iterrows(): ax2.annotate(row['都道府県'][:2], (row['年平均気温'], row['消費支出_万円']), fontsize=6.5, alpha=0.75, xytext=(3, 3), textcoords='offset points') # 回帰直線 x2 = df_valid['年平均気温'].values y2 = df_valid['消費支出_万円'].values slope2, intercept2, r2, p2, _ = stats.linregress(x2, y2) xr2 = np.linspace(x2.min(), x2.max(), 100) ax2.plot(xr2, slope2 * xr2 + intercept2, 'k--', linewidth=1.5, label=f'回帰直線 (r={r2:.3f}, p={p2:.3f})') ax2.set_xlabel('年平均気温(℃)', fontsize=12) ax2.set_ylabel('消費支出(万円/月)', fontsize=12) ax2.set_title('年平均気温 vs 消費支出(二人以上の世帯, 2022年)\n' '(地域別色分け、都道府県ラベル付き)', fontsize=12, fontweight='bold') ax2.legend(fontsize=8, ncol=2, loc='upper right') ax2.grid(alpha=0.3) plt.tight_layout() fig2.savefig(os.path.join(FIG_DIR, '2022_H5_3_fig2_temp_consumption.png'), bbox_inches='tight', dpi=150) plt.close(fig2) print("図2保存: 2022_H5_3_fig2_temp_consumption.png") |
図2保存: 2022_H5_3_fig2_temp_consumption.png
df.groupby('列').apply(関数) — グループごとに関数を適用。時系列や地域別の集計でよく使います。fig, ax = plt.subplots(...) — 図全体(fig)と軸(ax)を作る定番。以降は ax.bar(...) 等で操作。stats.linregress(x, y) — 単回帰の傾き・切片・r値・p値・標準誤差を返します。使わない値は _ で受け取り。for _, row in df.iterrows() — DataFrameを1行ずつ取り出すループ。1点ずつ描画したいときに使用。[式 for x in リスト] はリスト内包表記。forループでappendする代わりに1行でリストを作れます。単純相関では有意な関係が見られなかったが、交絡変数(高齢化率・総人口)を加えた OLS重回帰分析を行う。気象変数の係数は「他の変数を一定に保ったときの純粋な効果」を示す。
| 変数 | 係数(標準化) | p値 | 95%CI(標準化) | 解釈 |
|---|---|---|---|---|
| 年平均気温 | −0.24 | 0.153 | 有意でない | 気温が高いと消費やや減少(非有意) |
| 降水量(年間) | −0.00 | 0.986 | 有意でない | ほぼ無関係 |
| 高齢化率 | −0.35 | 0.113 | 有意でない | 高齢化が進むと消費減少傾向 |
| 総人口 | +0.14 | 0.490 | 有意でない | 大都市ほど消費増加傾向 |
| モデル全体の適合度: R² = 0.204 | F(4,42) = 2.68, p = 0.044 | モデル全体は有意 | ||
単回帰(気温のみ)と重回帰(気温+社会経済変数)では、気温の係数が変化する。 この変化量(オミッテッドバリアブルバイアス)が交絡変数の影響を示す。
OLS回帰の仮定(誤差の正規性・等分散性)を確認するには残差プロットが有効。 残差に系統的なパターンが見られる場合は、モデルの再検討が必要。
61 62 63 64 65 66 | df_std = df_reg.copy() for col in df_std.columns: if df_std[col].std() > 0: df_std[col] = (df_std[col] - df_std[col].mean()) / df_std[col].std() X_std = sm.add_constant(df_std[xvars_names]) res_std = sm.OLS(df_std['消費支出_万円'], X_std).fit() |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。sm.add_constant(X) — 切片項(定数1の列)を先頭に追加。statsmodelsで必須。sm.OLS(y, X).fit() — 最小二乗法でモデルを推定。model.params, model.pvalues, model.conf_int() で結果取得。r, p = stats.pearsonr(...) — Pythonは複数戻り値を同時に受け取れる(タプルアンパック)。67 68 69 70 71 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 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | # プロット用ラベル label_map = { '年平均気温': '年平均気温(℃)', '降水量(年間)': '降水量・年間(mm)', '高齢化率': '高齢化率(%)', '総人口_万人': '総人口(万人)', } coefs_std = res_std.params.drop('const') ses_std = res_std.bse.drop('const') pvals_std = res_std.pvalues.drop('const') labels_std = [label_map.get(c, c) for c in coefs_std.index] colors_std = ['#C62828' if p < 0.01 else '#FF8F00' if p < 0.05 else '#9E9E9E' for p in pvals_std] fig3, ax3 = plt.subplots(figsize=(9, 5)) y_pos = np.arange(len(coefs_std)) ax3.barh(y_pos, coefs_std.values, color=colors_std, alpha=0.80, edgecolor='white', height=0.6) ax3.errorbar(coefs_std.values, y_pos, xerr=1.96 * ses_std.values, fmt='none', color='#333', capsize=4, linewidth=1.2) ax3.axvline(0, color='gray', linestyle='--', linewidth=1.0) ax3.set_yticks(y_pos) ax3.set_yticklabels(labels_std, fontsize=11) ax3.set_xlabel('標準化回帰係数(±1.96SE)', fontsize=11) ax3.set_title(f'消費支出の気象・社会要因 OLS重回帰(標準化係数)\n' f'R²={res_std.rsquared:.3f}, N={N}都道府県(2022年)', fontsize=12, fontweight='bold') ax3.invert_yaxis() ax3.grid(axis='x', alpha=0.3) # p値の星マーク for i, (coef, se, p) in enumerate(zip(coefs_std.values, ses_std.values, pvals_std)): sig = '***' if p < 0.001 else '**' if p < 0.01 else '*' if p < 0.05 else '' xpos = coef + 1.96 * se + 0.02 ax3.text(xpos, i, sig, va='center', ha='left', fontsize=11, color='#C62828') legend_handles = [ Patch(color='#C62828', alpha=0.80, label='p < 0.01'), Patch(color='#FF8F00', alpha=0.80, label='p < 0.05'), Patch(color='#9E9E9E', alpha=0.80, label='n.s.'), ] ax3.legend(handles=legend_handles, fontsize=9, loc='lower right') plt.tight_layout() fig3.savefig(os.path.join(FIG_DIR, '2022_H5_3_fig3_ols_coef.png'), bbox_inches='tight', dpi=150) plt.close(fig3) print("図3保存: 2022_H5_3_fig3_ols_coef.png") |
図3保存: 2022_H5_3_fig3_ols_coef.png
fig, ax = plt.subplots(...) — 図全体(fig)と軸(ax)を作る定番。以降は ax.bar(...) 等で操作。ax.axhline / ax.axvline — 水平/垂直の点線。平均線や基準線として定番。x if cond else y は三項演算子。リスト内包表記と組み合わせると、forとifを1行で書けます。降水量が多い地域では外出が減り、内食(自炊)消費が増加するという仮説を検証する。 食料費(二人以上の世帯の月次食料支出)を目的変数に、年間降水量との関係を散布図で確認する。
高知・宮崎など太平洋側の多雨地域では食料費が高い傾向が見られる。ただし、所得水準・物価水準の影響も複合的に働いている点に注意が必要。
東京・神奈川など大都市圏は降水量が少なくても食料費が高い。これは外食・デリバリー消費の都市部での高さを反映しており、「降水量→内食増加」仮説に反する事例。
気象が消費行動に影響するメカニズムは複数ある。高校生が想定した仮説と 実際のメカニズムを整理することが、統計分析の深化につながる。
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 | 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 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} のように書式も指定できます。131 132 133 134 135 136 137 138 139 | 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("=" * 65) print(f"■ 対象都道府県数: N={len(df)}(2022年度 SSDSE-B)") print("=" * 65) |
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ループ不要なのが強み。140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 | # ── 変数生成 ───────────────────────────────────────────────────── num_cols = [ '年平均気温', '最高気温(日最高気温の月平均の最高値)', '降水日数(年間)', '降水量(年間)', '消費支出(二人以上の世帯)', '食料費(二人以上の世帯)', '総人口', '65歳以上人口', ] for c in num_cols: df[c] = pd.to_numeric(df[c], errors='coerce') df['高齢化率'] = df['65歳以上人口'] / df['総人口'] * 100 df['総人口_万人'] = df['総人口'] / 10000 df['消費支出_万円'] = df['消費支出(二人以上の世帯)'] / 10000 df['食料費_万円'] = df['食料費(二人以上の世帯)'] / 10000 |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。.map() は「1対1の置き換え」、.apply() は「関数を当てる」。辞書なら .map()、ロジックなら .apply()。158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 | # 地域区分マップ region_map = { '北海道': '北海道・東北', '青森県': '北海道・東北', '岩手県': '北海道・東北', '宮城県': '北海道・東北', '秋田県': '北海道・東北', '山形県': '北海道・東北', '福島県': '北海道・東北', '茨城県': '関東', '栃木県': '関東', '群馬県': '関東', '埼玉県': '関東', '千葉県': '関東', '東京都': '関東', '神奈川県': '関東', '新潟県': '中部', '富山県': '中部', '石川県': '中部', '福井県': '中部', '山梨県': '中部', '長野県': '中部', '岐阜県': '中部', '静岡県': '中部', '愛知県': '中部', '三重県': '近畿', '滋賀県': '近畿', '京都府': '近畿', '大阪府': '近畿', '兵庫県': '近畿', '奈良県': '近畿', '和歌山県': '近畿', '鳥取県': '中国・四国', '島根県': '中国・四国', '岡山県': '中国・四国', '広島県': '中国・四国', '山口県': '中国・四国', '徳島県': '中国・四国', '香川県': '中国・四国', '愛媛県': '中国・四国', '高知県': '中国・四国', '福岡県': '九州・沖縄', '佐賀県': '九州・沖縄', '長崎県': '九州・沖縄', '熊本県': '九州・沖縄', '大分県': '九州・沖縄', '宮崎県': '九州・沖縄', '鹿児島県': '九州・沖縄', '沖縄県': '九州・沖縄', } region_colors = { '北海道・東北': '#4e9af1', '関東': '#e05c5c', '中部': '#f0a500', '近畿': '#5cb85c', '中国・四国': '#9b59b6', '九州・沖縄': '#f39c12', } df['地域'] = df['都道府県'].map(region_map) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。[式 for x in リスト] はリスト内包表記。forループでappendする代わりに1行でリストを作れます。185 186 187 188 189 190 191 192 193 194 | # 欠損除外 df_valid = df.dropna(subset=[ '年平均気温', '最高気温(日最高気温の月平均の最高値)', '降水日数(年間)', '降水量(年間)', '消費支出(二人以上の世帯)', '食料費(二人以上の世帯)', '高齢化率', '総人口_万人' ]).copy().reset_index(drop=True) N = len(df_valid) print(f"有効都道府県数(欠損除外後): N={N}") |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。r, p = stats.pearsonr(...) — Pythonは複数戻り値を同時に受け取れる(タプルアンパック)。195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 | # ── 基本統計量 ────────────────────────────────────────────────── print() print(df_valid[['年平均気温', '降水量(年間)', '消費支出_万円', '食料費_万円', '高齢化率', '総人口_万人']].describe().round(2)) # ── 相関分析 ─────────────────────────────────────────────────── print("\n" + "=" * 65) print("■ 相関分析(気象変数 × 消費支出・食料費)") print("=" * 65) weather_vars = ['年平均気温', '最高気温(日最高気温の月平均の最高値)', '降水日数(年間)', '降水量(年間)'] target_vars = ['消費支出_万円', '食料費_万円'] print(f"\n {'変数':<30} {'vs 消費支出':>12} {'vs 食料費':>12}") print(" " + "-" * 58) for wv in weather_vars: r1, p1 = stats.pearsonr(df_valid[wv], df_valid['消費支出_万円']) r2, p2 = stats.pearsonr(df_valid[wv], df_valid['食料費_万円']) s1 = '***' if p1 < 0.001 else '**' if p1 < 0.01 else '*' if p1 < 0.05 else 'n.s.' s2 = '***' if p2 < 0.001 else '**' if p2 < 0.01 else '*' if p2 < 0.05 else 'n.s.' print(f" {wv:<30} r={r1:+.3f}{s1:>4} r={r2:+.3f}{s2:>4}") |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。.describe() — 件数・平均・標準偏差・四分位・最大/最小を一括計算。データの素性チェックに必須。stats.pearsonr(x, y) — Pearson相関係数 r と p値を同時に返します。x if cond else y は三項演算子。リスト内包表記と組み合わせると、forとifを1行で書けます。215 216 217 218 219 220 221 222 223 | # ── OLS重回帰分析(消費支出) ───────────────────────────────── print("\n" + "=" * 65) print("■ OLS重回帰分析(目的変数: 消費支出)") print("=" * 65) xvars_names = ['年平均気温', '降水量(年間)', '高齢化率', '総人口_万人'] df_reg = df_valid[['消費支出_万円'] + xvars_names].dropna() X_reg = sm.add_constant(df_reg[xvars_names]) res_ols = sm.OLS(df_reg['消費支出_万円'], X_reg).fit() print(res_ols.summary()) |
=================================================================
■ 対象都道府県数: N=47(2022年度 SSDSE-B)
=================================================================
有効都道府県数(欠損除外後): N=47
年平均気温 降水量(年間) 消費支出_万円 食料費_万円 高齢化率 総人口_万人
count 47.00 47.00 47.00 47.00 47.00 47.00
mean 16.07 1544.27 28.96 7.66 31.35 265.84
std 2.29 551.31 1.92 0.56 3.27 279.35
min 10.20 667.50 24.51 6.79 22.81 54.40
25% 15.25 1169.00 27.68 7.23 29.85 104.65
50% 16.40 1408.00 28.78 7.57 31.42 156.30
75% 17.35 1732.00 30.23 8.09 33.72 265.50
max 23.70 2996.50 32.48 8.80 38.60 1403.80
=================================================================
■ 相関分析(気象変数 × 消費支出・食料費)
=================================================================
変数 vs 消費支出 vs 食料費
----------------------------------------------------------
年平均気温 r=-0.097n.s. r=-0.186n.s.
最高気温(日最高気温の月平均の最高値) r=+0.129n.s. r=-0.128n.s.
降水日数(年間) r=-0.147n.s. r=+0.047n.s.
降水量(年間) r=-0.076n.s. r=+0.008n.s.
=================================================================
■ OLS重回帰分析(目的変数: 消費支出)
=================================================================
OLS Regression Results
==============================================================================
Dep. Variable: 消費支出_万円 R-squared: 0.204
Model: OLS Adj. R-squared: 0.128
Method: Least Squares F-statistic: 2.684
Date: Mon, 18 May 2026 Prob (F-statistic): 0.0443
Time: 11:24:08 Log-Likelihood: -91.462
No. Observations: 47 AIC: 192.9
Df Residuals: 42 BIC: 202.2
Df Model: 4
Covariance Type: nonrobust
==============================================================================
coef std err t P>|t| [0.025 0.975]
------------------------------------------------------------------------------
const 38.4125 5.599 6.861 0.000 27.113 49.712
年平均気温 -0.1996 0.137 -1.456 0.153 -0.476 0.077
降水量(年間) -8.987e-06 0.001 -0.018 0.986 -0.001 0.001
高齢化率 -0.2069 0.128 -1.617 0.113 -0.465 0.051
総人口_万人 0.0010 0.001 0.696 0.490 -0.002 0.004
==============================================================================
Omnibus: 2.229 Durbin-Watson: 1.547
Prob(Omnibus): 0.328 Jarque-Bera (JB): 1.559
Skew: -0.440 Prob(JB): 0.459
Kurtosis: 3.149 Cond. No. 3.55e+04
==============================================================================
Notes:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
[2] The condition number is large, 3.55e+04. 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() で結果取得。df[col](1列)と df[[col1, col2]](複数列)でカッコの数が違います。リストを渡していると覚えるとミスを減らせます。224 225 226 227 228 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 | fig4, ax4 = plt.subplots(figsize=(9, 6)) for reg, grp in df_valid.groupby('地域'): ax4.scatter(grp['降水量(年間)'], grp['食料費_万円'], color=region_colors.get(reg, '#888888'), label=reg, s=70, alpha=0.85, zorder=3) for _, row in df_valid.iterrows(): ax4.annotate(row['都道府県'][:2], (row['降水量(年間)'], row['食料費_万円']), fontsize=6.5, alpha=0.75, xytext=(3, 3), textcoords='offset points') x4 = df_valid['降水量(年間)'].values y4 = df_valid['食料費_万円'].values slope4, intercept4, r4, p4, _ = stats.linregress(x4, y4) xr4 = np.linspace(x4.min(), x4.max(), 100) ax4.plot(xr4, slope4 * xr4 + intercept4, 'k--', linewidth=1.5, label=f'回帰直線 (r={r4:.3f}, p={p4:.3f})') ax4.set_xlabel('降水量・年間(mm)', fontsize=12) ax4.set_ylabel('食料費(万円/月)', fontsize=12) ax4.set_title('降水量(年間)vs 食料費(二人以上の世帯, 2022年)\n' '(地域別色分け)', fontsize=12, fontweight='bold') ax4.legend(fontsize=8, ncol=2, loc='upper right') ax4.grid(alpha=0.3) plt.tight_layout() fig4.savefig(os.path.join(FIG_DIR, '2022_H5_3_fig4_precip_food.png'), bbox_inches='tight', dpi=150) plt.close(fig4) print("図4保存: 2022_H5_3_fig4_precip_food.png") print("\n全図の生成完了(4枚)") print(" fig1: 2022_H5_3_fig1_temp_rank.png — 年平均気温ランキング棒グラフ") print(" fig2: 2022_H5_3_fig2_temp_consumption.png — 気温 vs 消費支出 散布図") print(" fig3: 2022_H5_3_fig3_ols_coef.png — OLS回帰係数プロット") print(" fig4: 2022_H5_3_fig4_precip_food.png — 降水量 vs 食料費 散布図") |
図4保存: 2022_H5_3_fig4_precip_food.png 全図の生成完了(4枚) fig1: 2022_H5_3_fig1_temp_rank.png — 年平均気温ランキング棒グラフ fig2: 2022_H5_3_fig2_temp_consumption.png — 気温 vs 消費支出 散布図 fig3: 2022_H5_3_fig3_ols_coef.png — OLS回帰係数プロット fig4: 2022_H5_3_fig4_precip_food.png — 降水量 vs 食料費 散布図
df.groupby('列').apply(関数) — グループごとに関数を適用。時系列や地域別の集計でよく使います。fig, ax = plt.subplots(...) — 図全体(fig)と軸(ax)を作る定番。以降は ax.bar(...) 等で操作。stats.linregress(x, y) — 単回帰の傾き・切片・r値・p値・標準誤差を返します。使わない値は _ で受け取り。for _, row in df.iterrows() — DataFrameを1行ずつ取り出すループ。1点ずつ描画したいときに使用。x if cond else y は三項演算子。リスト内包表記と組み合わせると、forとifを1行で書けます。SSDSE-B の47都道府県・2022年度データを用いて、気象条件(気温・降水量)と 消費行動(消費支出・食料費)の関係を相関分析・OLS重回帰で検証した。
| 項目 | 内容 |
|---|---|
| 使用データ | SSDSE-B-2026.csv(都道府県別データ, 2022年度, N=47) |
| データ出典 | 統計数理研究所 SSDSE(社会・人口統計体系) |
| 気象データ出典 | 気象庁 都道府県別気象統計(SSDSE-Bに収録) |
| 家計データ出典 | 総務省統計局 家計調査(SSDSE-Bに収録) |
| 分析ライブラリ | pandas, numpy, statsmodels, scipy, matplotlib |
| 生成図 | fig1_temp_rank.png(気温ランキング)、 fig2_temp_consumption.png(気温 vs 消費支出)、 fig3_ols_coef.png(OLS係数)、 fig4_precip_food.png(降水量 vs 食料費) |
本スクリプトは実公的データ(SSDSE-B-2026.csv)のみを使用。合成データ・乱数生成は一切行っていない。
統計分析の解釈で初心者がやりがちな勘違いをまとめます。特に「相関と因果の混同」「p値の過信」は研究現場でもよく起きる落とし穴です。本文を読む前にも、読んだ後にも、目を通してみてください。
統計の基本用語を初心者向けに解説します。本文中で見慣れない言葉が出てきたら、ここに戻って確認してください。
統計手法について「何のためか」「結果をどう読むか」を初心者向けに解説します。
この研究をさらに発展させるための3つの方向性を示します。「今回わかったこと(X)」から「次に検証すべき仮説(Y)」を立て、「具体的に何をするか(Z)」まで考えてみましょう。
学んだだけでは身につきません。実際に手を動かすのが最強の学習方法です。本論文のスクリプトをベースに、以下のチャレンジに挑戦してみてください。難易度別に5つ用意しました。
本論文で学んだ手法は、研究の世界だけでなく、行政・企業・NPO の現場でも様々に活用されています。具体的なシーンを紹介します。
この論文を読んで初心者が抱きやすい疑問に、教育的観点から答えます。