この教材は、原論文が使ったデータそのものを使えていません。そこで代わりのデータで同じ問いを追いかけ、結論の向き(増える/減る、強い/弱い)が原論文と一致するかを確かめます。「同じ数値が出る」ことは目標にしていません。
| 原論文が使ったデータ | SSDSE-D・社会生活基本調査 分析単位:個人 |
|---|---|
| この教材が使うデータ |
|
| 原論文(PDF) | 高校生におけるヤングケアラーに対する認識について 審査員奨励賞/後藤 颯太、島野 真緒、村川 莉奈(岡山県立倉敷青陵高等学校) |
原論文と同じ粒度のデータは、この教材にも同梱しています。これを読み込めば、原論文と同じ細かさで分析をやり直せます(下の「🐍 ブラウザで動かす」でコードを書き換えて試せます)。ただし原論文が使った項目がすべて収録されているとは限りません。足りない項目は、上の「できないこと」に書いた出典から取ってくる必要があります。
▶ ここに書いてある分析は、ページ下部の「🐍 ブラウザで動かす」でそのまま実行できます(インストール不要)。動かしているのは code/2022_H5_3_shorei.py(352 行)そのものです。
※ このページの後半には、原論文とは別に教材用に作成した「気象×消費」のSSDSE-B再現・演習分析(再現値)を補足として収録しています(詳細はこちら)。
このセクションでは、受賞論文「高校生におけるヤングケアラーに対する認識について」(後藤颯太・島野真緒・村川莉奈、岡山県立倉敷青陵高校)が 実際に報告している目的・方法・結果・結論を、原論文の言葉と数値でまとめる。 以下の数値はすべて「原論文の報告値」であり、本ページ後半の教材補足(SSDSE-B-2026による再現値)とは区別すること。
近年問題視されているヤングケアラーは、家庭の事情であることから周囲からの発見が困難であると言われている。 2021年のデータでは岡山県の人々は全国に比べ学習者率が高く学習時間も多く(原論文 図1、SSDSE_Dの「学業(在学者平日)」から作成した箱ひげ図。◇が岡山、十が平均値)、 勉強のために家にいる時間が多いと考えられる。さらに新型コロナウイルス流行下の自粛推奨も、ヤングケアラーの発見を困難にする要因の1つである。 また、女子のヤングケアラーが男子より多いというデータ(原論文 表1)から、著者らは「性別役割分業意識」が関係していると考察し、 ヤングケアラーに対する認識の程度を複数の観点から調査した。
ヤングケアラーに影響を及ぼしているのは「内容」「時間」「年齢」「分業意識」に関する4つの認識であると考えて仮説を立て、
倉敷青陵高校の生徒233人にアンケートを実施した。また、回答には岡山県に住んでいることの影響も一定程度認められると考え、
SSDSE(教育用標準データセット)のSSDSE_Dと平成28年社会生活基本調査(総務省統計局)を用いて岡山県民の特徴を考察した。
このとき、10歳以上と15歳以上の推定人口・行動者率から「10歳以上15歳未満」の行動者率を統計分析ソフトウェア「R」の自作関数
(原論文 スクリプト1:TenToFifteen)で算出している。
| 観点 | 主な結果(233件の回答) | 仮説との対応 |
|---|---|---|
| 内容(グラフ1・複数回答) | 障がいや病気のある家族の看病・世話 80.3%(187)、家事 74.7%(174)、幼いきょうだいの世話 70.8%(165)、家計を支える労働 60.9%(142)、見守り・声掛け 55.4%(129)、依存症等への対応 51.1%(119)、通訳 29.6%(69) | 予想通り「ケア」想起の内容が高い一方、通訳は30%未満 |
| 年齢(グラフ2) | 18歳以下 69.1%、15歳以下 26.2%、12歳以下ほか少数 | おおむね予想通りだが「15歳以下」が約26%と予想以上 |
| 時間(グラフ3) | 2時間以上4時間未満 52.8%、4時間以上6時間未満 31.3%、6時間以上 7.7%、2時間未満 7.3% | 予想に反して「2〜4時間」が最多 |
| 分業意識(グラフ4) | 反対 54.9%、やや反対 31.3%(計 約86%)、やや賛成 9% など | 予想通り反対側が圧倒的多数 |
| 男女差(グラフ6・7) | 男性:反対 50.4%・やや反対 30.3%・やや賛成 10.9%・賛成 5.9% 女性:反対 59.8%・やや反対 33.0%・やや賛成 6.3%・賛成 0% |
「反対」が約9%異なり、女性では「賛成」の回答なし |
岡山県民全体では、SSDSE_Dの行動者率のうち全国平均を2ポイント以上上回った項目として 「学習・自己啓発・訓練の総数」「園芸・庭いじり・ガーデニング」「趣味としての読書」「ボランティア活動の総数」 「まちづくりのための活動」「旅行・行楽の総数」「行楽(日帰り)」を挙げ(原論文 図2〜8の箱ひげ図)、 社会参画の意識が高いと解釈している。 10〜15歳の岡山県民では全国平均との差が小さくなるなかで、差が+0.04を超えた 「ソフトボール」と「子供を対象とした活動」を特徴とした(原論文 グラフ8、図9・10)。
教材補足(気象×消費の演習分析)を自分で再現するには、以下の手順でデータを準備してください。コードの編集は不要です。
data/raw/ フォルダに入れます。html/figures/ に自動保存されます。
気象条件は農業生産や観光需要にとどまらず、家計の日常的な消費行動にも影響を及ぼす可能性がある。 この補足分析では、都道府県別の気温・降水量などの気象データと、二人以上世帯の消費支出・食料費データを用いて、 その統計的関係を検証する。
この論文が挑んだ問いは「高校生はヤングケアラーを「内容」「時間」「年齢」「分業意識」の4つの観点でどう認識しているか。女子のヤングケアラーが男子より多い背景に「性別役割分業意識」が関わっていないか」(テーマ:介護・福祉・ジェンダー)。 著者はアンケート調査・記述統計・クロス集計を軸にこの問いへ定量的に答えを出した。 本ページではその分析の流れを実データで再現しながら、使われた統計手法を一つずつ学んでいく。
「気象は誰もコントロールできない」という外生性(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行で書けます。降水量が多い地域では外出が減り、内食(自炊)消費が増加するという仮説を検証する。 食料費(二人以上の世帯の月次食料支出)を目的変数に、年間降水量との関係を散布図で確認する。
多雨地域のうち静岡・石川・富山は食料費が高い(約8.3万円/月)一方、宮崎・鹿児島・沖縄は低い(約6.8〜7.0万円/月)。「多雨→内食増→食料費増」という単純な図式は成り立たない。
埼玉・東京・神奈川は降水量が全国平均(1,544mm)並みか下回るのに、食料費は全国最上位(約8.5〜8.8万円/月)。都市部の物価水準や外食・中食の多さを反映しており、「降水量→内食増加」仮説とは別の要因が支配的な事例。
気象が消費行動に影響するメカニズムは複数ある。分析前に想定した仮説と 実際のメカニズムを整理することが、統計分析の深化につながる。
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 出力は、後続の「OLS重回帰分析」ステップの実行結果にまとめて表示しています。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 出力は、後続の「OLS重回帰分析」ステップの実行結果にまとめて表示しています。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 出力は、後続の「OLS重回帰分析」ステップの実行結果にまとめて表示しています。.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重回帰で検証した。
以下は教材補足(気象×消費の演習分析)の再現用スクリプトとデータである。原論文自体は独自アンケート(233人)と SSDSE_D・社会生活基本調査を用い、加工にはR(原論文 スクリプト1)を使用している。
| 項目 | 内容 |
|---|---|
| 使用データ | 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 の現場でも様々に活用されています。具体的なシーンを紹介します。
この論文を読んで初心者が抱きやすい疑問に、教育的観点から答えます。
この論文を理解できたか、クリックで確認しましょう。間違えても解説が出ます。
このページの分析は、この画面の中でそのまま実行できます。
Python をインストールする必要も、CSV をダウンロードする必要もありません。
下のセルの 「▶ ブラウザで実行」 を上から順に押すか、
「▶ 最初から全部実行」 で一気に流してください。
表示されるのは、本文の図表とまったく同じ計算の結果です
(動かしているのは再現スクリプト code/2022_H5_3_shorei.py そのもの)。
コードは書き換えられます。「✏️ 書き換える」で数字や変数を変えて ▶ を押すと、 結果がどう変わるかをその場で確かめられます(元に戻すボタンつき)。 ページを開いた時点で裏で実行環境の準備が始まっているので、待ち時間はほとんどありません。 初回だけ実行環境の取得にインターネット接続が必要です。