このページの分析を自分で再現するには、以下の手順でデータを準備してください。コードの編集は不要です。
data/raw/ フォルダに入れます。html/figures/ に自動保存されます。
「豊かさ」は経済指標だけでは測れない。近年、GDPや所得に加えて、環境の質・文化的充実・将来世代への持続可能性が「生活の質(Quality of Life)」の重要な構成要素として認識されるようになっている。 日本においても、環境省の「環境白書」や地方自治体の「環境基本計画」において、環境保全と住民生活の向上を一体的に進める政策が推進されている。
まず「都道府県別環境指標と住民生活の質の関係分析」を統計的にとらえることが有効だと考えられる。 その理由は感覚や経験則だけでは、複雑な社会要因の中で「何が本当に効いているか」を見極めにくいからである。 本研究では公開データと統計手法を組み合わせ、この問いに定量的な答えを出すことを目指す。
環境指標 生活の質 重回帰分析 地域比較
SSDSE(社会・人口統計体系データセット)-B(2026年版)の都道府県別データを使用した。
地域コードが R\d{5} の47都道府県行を抽出し、2022年断面データ(N=47)を分析に用いた。
欠損値は存在せず、全47都道府県で分析可能であった。
| カテゴリ | 変数名(SSDSE-B) | 役割 | 2022年全国平均 |
|---|---|---|---|
| 環境指標(説明変数) | 1人1日あたりのごみ排出量(g) | 環境負荷の指標 | 906.1 g |
| ごみのリサイクル率(%) | 環境意識・インフラの指標 | 18.2 % | |
| 気候条件(説明変数) | 年平均気温(℃) | 居住環境の快適性 | 16.1 ℃ |
| 年間降水量(mm) | 自然環境の代理 | 1,544 mm | |
| 余暇・文化(説明変数) | 教養娯楽費(円/月) | 文化的豊かさの代理 | 25,974 円 |
| 将来の生活の質(説明変数) | 合計特殊出生率 | 長期的生活満足度の代理 | 1.358 |
| 目的変数 | 消費支出(円/月、二人以上の世帯) | 生活の質の総合指標 | 289,630 円 |
まず、都道府県別のごみ排出量(環境負荷の基本指標)の地域分布を確認する。 ごみ排出量は都市化の程度、廃棄物処理インフラ、住民のライフスタイルを反映する総合的な環境指標である。
| 地域 | 都道府県数 | 平均ごみ排出量(g/人/日) | 特徴 |
|---|---|---|---|
| 北海道・東北 | 7 | 960.3 | 全国最多。寒冷地・灯油缶等の廃棄増 |
| 中国・四国 | 9 | 917.7 | 農山漁村部が多く処理の効率化課題 |
| 九州・沖縄 | 8 | 911.5 | 観光廃棄物・島嶼部の制約 |
| 中部 | 9 | 906.6 | 全国平均水準 |
| 近畿 | 7 | 861.9 | 大都市圏のインフラ整備・分別意識 |
| 関東 | 7 | 874.4 | 大都市圏で比較的低水準 |
都道府県データは47という小さいサンプルサイズのため、地域ごとのまとまりが統計的にも重要。地域をカテゴリ変数として回帰に加える「地域固定効果モデル」は過学習リスクがあるが、地域ダミーを入れずに分析する際は「地域差」が残差に含まれることに留意する。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | import os 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 plt.rcParams['font.family'] = 'Hiragino Sans' plt.rcParams['axes.unicode_minus'] = False plt.rcParams['figure.dpi'] = 150 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} のように書式も指定できます。17 18 19 20 21 22 23 24 | # ── データ読み込み ────────────────────────────────────────────── 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(f"2022年データ: {len(df)}都道府県") |
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ループ不要なのが強み。25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | # ── 地域区分マップ ────────────────────────────────────────────── region_map = { '北海道': '北海道・東北', '青森県': '北海道・東北', '岩手県': '北海道・東北', '宮城県': '北海道・東北', '秋田県': '北海道・東北', '山形県': '北海道・東北', '福島県': '北海道・東北', '茨城県': '関東', '栃木県': '関東', '群馬県': '関東', '埼玉県': '関東', '千葉県': '関東', '東京都': '関東', '神奈川県': '関東', '新潟県': '中部', '富山県': '中部', '石川県': '中部', '福井県': '中部', '山梨県': '中部', '長野県': '中部', '岐阜県': '中部', '静岡県': '中部', '愛知県': '中部', '三重県': '近畿', '滋賀県': '近畿', '京都府': '近畿', '大阪府': '近畿', '兵庫県': '近畿', '奈良県': '近畿', '和歌山県': '近畿', '鳥取県': '中国・四国', '島根県': '中国・四国', '岡山県': '中国・四国', '広島県': '中国・四国', '山口県': '中国・四国', '徳島県': '中国・四国', '香川県': '中国・四国', '愛媛県': '中国・四国', '高知県': '中国・四国', '福岡県': '九州・沖縄', '佐賀県': '九州・沖縄', '長崎県': '九州・沖縄', '熊本県': '九州・沖縄', '大分県': '九州・沖縄', '宮崎県': '九州・沖縄', '鹿児島県': '九州・沖縄', '沖縄県': '九州・沖縄' } region_colors = { '北海道・東北': '#4e9af1', '関東': '#e05c5c', '中部': '#f0a500', '近畿': '#5cb85c', '中国・四国': '#9b59b6', '九州・沖縄': '#f39c12' } df['地域'] = df['都道府県'].map(region_map) df['地域色'] = df['地域'].map(region_colors) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。.map() は「1対1の置き換え」、.apply() は「関数を当てる」。辞書なら .map()、ロジックなら .apply()。49 50 51 52 53 54 55 56 57 58 59 60 61 62 | # ── 変数の数値変換 ────────────────────────────────────────────── COLS = { 'ごみ排出量': '1人1日当たりの排出量', 'リサイクル率': 'ごみのリサイクル率', '消費支出': '消費支出(二人以上の世帯)', '教養娯楽費': '教養娯楽費(二人以上の世帯)', '出生率': '合計特殊出生率', '気温': '年平均気温', '降水量': '降水量(年間)', '病院数': '一般病院数', } for key, col in COLS.items(): df[key] = pd.to_numeric(df[col], errors='coerce') |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。[式 for x in リスト] はリスト内包表記。forループでappendする代わりに1行でリストを作れます。63 64 65 66 67 68 69 70 71 72 | # 人口1万人あたり病院数 df['人口'] = pd.to_numeric(df['総人口'], errors='coerce') df['病院数_per10k'] = df['病院数'] / df['人口'] * 10000 # 分析用データ(欠損除去) ENV_VARS = ['ごみ排出量', 'リサイクル率', '気温', '降水量'] LIFE_VARS = ['消費支出', '教養娯楽費', '出生率'] ALL_VARS = ENV_VARS + LIFE_VARS df_ana = df[['都道府県', '地域', '地域色'] + ALL_VARS].dropna().copy() print(f"分析対象: {len(df_ana)}都道府県") |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。r, p = stats.pearsonr(...) — Pythonは複数戻り値を同時に受け取れる(タプルアンパック)。73 74 75 76 77 78 | # ── 統計サマリー出力 ──────────────────────────────────────────── print("\n=== 基本統計量(2022年) ===") for v in ALL_VARS: s = df_ana[v] print(f" {v}: 平均={s.mean():.2f}, 標準偏差={s.std():.2f}, " f"最小={s.min():.2f}, 最大={s.max():.2f}") |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。x if cond else y は三項演算子。リスト内包表記と組み合わせると、forとifを1行で書けます。79 80 81 82 83 84 | # ── 相関分析 ──────────────────────────────────────────────────── print("\n=== 消費支出との相関(Pearson r)===") for v in ENV_VARS + ['教養娯楽費', '出生率']: r, p = stats.pearsonr(df_ana[v], df_ana['消費支出']) sig = '**' if p < 0.01 else ('*' if p < 0.05 else 'ns') print(f" {v}: r={r:.4f}, p={p:.4f} {sig}") |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。stats.pearsonr(x, y) — Pearson相関係数 r と p値を同時に返します。df[col](1列)と df[[col1, col2]](複数列)でカッコの数が違います。リストを渡していると覚えるとミスを減らせます。85 86 87 88 89 90 | # ── OLS重回帰 ─────────────────────────────────────────────────── X_cols = ['ごみ排出量', 'リサイクル率', '気温', '降水量', '教養娯楽費', '出生率'] y_col = '消費支出' X_raw = df_ana[X_cols].copy() y_raw = df_ana[y_col].copy() |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。s[:-n]「末尾n文字を除く」/s[n:]「先頭n文字を除く」。スライス [start:stop:step] はリスト・タプル・文字列共通の基本ワザです。91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | # 標準化 X_std = (X_raw - X_raw.mean()) / X_raw.std() y_std = (y_raw - y_raw.mean()) / y_raw.std() X_ols = sm.add_constant(X_std) model = sm.OLS(y_std, X_ols).fit() print("\n=== OLS重回帰結果(標準化係数)===") print(f" R² = {model.rsquared:.4f}") print(f" Adj. R² = {model.rsquared_adj:.4f}") print(f" F-stat = {model.fvalue:.4f}, p = {model.f_pvalue:.4f}") for name, coef, pval in zip(X_cols, model.params[1:], model.pvalues[1:]): sig = '**' if pval < 0.01 else ('*' if pval < 0.05 else 'ns') print(f" {name}: β={coef:.4f}, p={pval:.4f} {sig}") r2_val = model.rsquared adj_r2_val = model.rsquared_adj f_val = model.fvalue f_pval = model.f_pvalue coef_dict = dict(zip(X_cols, model.params[1:])) pval_dict = dict(zip(X_cols, model.pvalues[1:])) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。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の定石です。111 112 113 114 115 116 | # ── 地域別ごみ排出量統計 ──────────────────────────────────────── print("\n=== 地域別ごみ排出量(1人1日あたり g)===") for region in region_colors: sub = df_ana[df_ana['地域'] == region]['ごみ排出量'] if len(sub) > 0: print(f" {region}: 平均={sub.mean():.1f}g, n={len(sub)}") |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。{値:.2f}(小数2桁)、{値:,}(3桁区切り)、{値:>10}(右寄せ10桁)など、覚えると出力が一気に整います。117 118 119 120 121 122 123 124 125 | # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ fig, ax = plt.subplots(figsize=(10, 7)) for region, color in region_colors.items(): mask = df_ana['地域'] == region sub = df_ana[mask] ax.scatter(sub['ごみ排出量'], sub['消費支出'] / 10000, color=color, label=region, s=60, zorder=3, alpha=0.85, edgecolors='white', linewidth=0.5) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。fig, ax = plt.subplots(...) — 図全体(fig)と軸(ax)を作る定番。以降は ax.bar(...) 等で操作。plt.subplots(figsize=(W, H)) で図サイズ指定、fig.savefig(..., bbox_inches='tight') で余白を自動で詰めて保存。126 127 128 129 130 131 | # 都道府県ラベル for _, row in df_ana.iterrows(): ax.annotate(row['都道府県'].replace('県', '').replace('府', '').replace('都', '').replace('道', ''), (row['ごみ排出量'], row['消費支出'] / 10000), fontsize=7, ha='left', va='bottom', xytext=(3, 2), textcoords='offset points', color='#333333') |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。for _, row in df.iterrows() — DataFrameを1行ずつ取り出すループ。1点ずつ描画したいときに使用。.dropna() は欠損行を除去、.copy() は独立したコピーを作る。pandasで警告を防ぐ定石。132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 | # 回帰線 x_plot = np.linspace(df_ana['ごみ排出量'].min(), df_ana['ごみ排出量'].max(), 100) slope, intercept, r_val, p_val_reg, _ = stats.linregress(df_ana['ごみ排出量'], df_ana['消費支出'] / 10000) ax.plot(x_plot, intercept + slope * x_plot, color='#333333', linewidth=1.5, linestyle='--', label=f'回帰線 r={r_val:.3f}', zorder=2) ax.set_xlabel('1人1日あたりごみ排出量(g)', fontsize=12) ax.set_ylabel('消費支出(万円/月、二人以上の世帯)', fontsize=12) ax.set_title('都道府県別:ごみ排出量と消費支出の関係(2022年)', fontsize=13, fontweight='bold') ax.legend(fontsize=9, loc='upper right', framealpha=0.9) ax.grid(True, linestyle=':', alpha=0.5) plt.tight_layout() fig.savefig(os.path.join(FIG_DIR, '2021_H5_6_fig1.png'), bbox_inches='tight') plt.close() print("\n図1保存完了") |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。stats.linregress(x, y) — 単回帰の傾き・切片・r値・p値・標準誤差を返します。使わない値は _ で受け取り。fig.savefig(..., bbox_inches='tight') — 余白を自動で詰めて保存。plt.close() でメモリ解放。f"...{x}..." はf-string。文字列の中に {変数} と書くだけで埋め込めて、{x:.2f} のように書式も指定できます。147 | # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
2022年データ: 47都道府県 分析対象: 47都道府県 === 基本統計量(2022年) === ごみ排出量: 平均=906.09, 標準偏差=61.51, 最小=770.00, 最大=1021.00 リサイクル率: 平均=18.21, 標準偏差=3.83, 最小=12.40, 最大=28.30 気温: 平均=16.07, 標準偏差=2.29, 最小=10.20, 最大=23.70 降水量: 平均=1544.27, 標準偏差=551.31, 最小=667.50, 最大=2996.50 消費支出: 平均=289630.36, 標準偏差=19186.91, 最小=245054.00, 最大=324793.00 教養娯楽費: 平均=25973.77, 標準偏差=3810.71, 最小=17601.00, 最大=35050.00 出生率: 平均=1.36, 標準偏差=0.15, 最小=1.04, 最大=1.70 === 消費支出との相関(Pearson r)=== ごみ排出量: r=-0.2922, p=0.0463 * リサイクル率: r=0.3693, p=0.0106 * 気温: r=-0.0971, p=0.5160 ns 降水量: r=-0.0761, p=0.6112 ns 教養娯楽費: r=0.7812, p=0.0000 ** 出生率: r=-0.3356, p=0.0211 * === OLS重回帰結果(標準化係数)=== R² = 0.6396 Adj. R² = 0.5855 F-stat = 11.8303, p = 0.0000 ごみ排出量: β=-0.0169, p=0.8811 ns リサイクル率: β=0.1423, p=0.1693 ns 気温: β=-0.0736, p=0.5691 ns 降水量: β=0.0443, p=0.6742 ns 教養娯楽費: β=0.7848, p=0.0000 ** 出生率: β=0.1037, p=0.4662 ns === 地域別ごみ排出量(1人1日あたり g)=== 北海道・東北: 平均=960.3g, n=7 関東: 平均=874.4g, n=7 中部: 平均=906.6g, n=9 近畿: 平均=861.9g, n=7 中国・四国: 平均=917.7g, n=9 九州・沖縄: 平均=911.5g, n=8 図1保存完了
df['A'] / df['B'] — pandasの列同士の四則演算は要素ごと(element-wise)。forループ不要なのが強み。目的変数(消費支出)と各説明変数の Pearson 相関係数をまず確認し、次に OLS 重回帰(標準化)によって偏回帰係数を推定した。 標準化係数(β)は単位の異なる変数間で「どの変数が消費支出の変動をより強く説明するか」を比較するために用いる。
| 変数 | 消費支出との r | p値 | 有意性 | 解釈 |
|---|---|---|---|---|
| ごみ排出量 | −0.292 | 0.0463 | * | 排出量が多い県ほど消費支出が低い傾向 |
| リサイクル率 | +0.369 | 0.0106 | * | リサイクル意識が高い県ほど消費支出も高い |
| 年平均気温 | −0.097 | 0.516 | ns | 有意な相関なし |
| 年間降水量 | −0.076 | 0.611 | ns | 有意な相関なし |
| 教養娯楽費 | +0.781 | <0.001 | ** | 余暇支出と消費全体は強く連動 |
| 合計特殊出生率 | −0.336 | 0.0211 | * | 都市部の低出生率と高消費支出の逆相関 |
リサイクル率と消費支出の正の相関は「リサイクルが消費を増やす」という因果を意味しない。 都市化度(人口密度・所得水準)という「交絡変数」が両者を同時に押し上げている可能性が高い。 因果推論には操作変数法(IV)やパネルデータの固定効果モデルが必要。
| 変数 | 標準化係数(β) | p値 | 有意性 | 解釈 |
|---|---|---|---|---|
| ごみ排出量 | −0.017 | 0.881 | ns | 他変数制御後は非有意 |
| リサイクル率 | +0.142 | 0.169 | ns | 他変数制御後は非有意 |
| 年平均気温 | −0.074 | 0.569 | ns | 非有意 |
| 年間降水量 | +0.044 | 0.674 | ns | 非有意 |
| 教養娯楽費 | +0.785 | <0.001 | ** | 唯一の有意な説明変数 |
| 合計特殊出生率 | +0.104 | 0.466 | ns | 非有意 |
ごみ排出量は消費支出と単変量で r=−0.292(p=0.046)の有意な相関を持つが、 重回帰に投入すると β=−0.017(p=0.881)と非有意になる。これは「抑制効果」や「共変量による交絡除去」が起きているためである。 多変量回帰での偏相関は「他の変数を一定にしたときの純粋な効果」を示すので、解釈は慎重に行う必要がある。
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 174 175 176 177 178 179 180 181 182 183 | HM_VARS = ['ごみ排出量', 'リサイクル率', '気温', '降水量', '消費支出', '教養娯楽費', '出生率'] HM_LABELS = ['ごみ排出量', 'リサイクル率', '年平均気温', '年間降水量', '消費支出', '教養娯楽費', '合計特殊\n出生率'] corr_mat = df_ana[HM_VARS].corr() pval_mat = pd.DataFrame(np.ones((len(HM_VARS), len(HM_VARS))), index=HM_VARS, columns=HM_VARS) for i, c1 in enumerate(HM_VARS): for j, c2 in enumerate(HM_VARS): if i != j: _, p = stats.pearsonr(df_ana[c1], df_ana[c2]) pval_mat.loc[c1, c2] = p fig, ax = plt.subplots(figsize=(9, 7)) im = ax.imshow(corr_mat.values, cmap='RdBu_r', vmin=-1, vmax=1, aspect='auto') plt.colorbar(im, ax=ax, shrink=0.8, label='Pearson r') n = len(HM_VARS) ax.set_xticks(range(n)) ax.set_yticks(range(n)) ax.set_xticklabels(HM_LABELS, fontsize=9, rotation=35, ha='right') ax.set_yticklabels(HM_LABELS, fontsize=9) for i in range(n): for j in range(n): r_ij = corr_mat.values[i, j] p_ij = pval_mat.values[i, j] sig_str = '**' if p_ij < 0.01 else ('*' if p_ij < 0.05 else '') txt = f'{r_ij:.2f}{sig_str}' ax.text(j, i, txt, ha='center', va='center', fontsize=8, color='white' if abs(r_ij) > 0.5 else 'black') ax.set_title('環境・生活変数の相関行列(2022年、47都道府県)\n* p<0.05, ** p<0.01', fontsize=12, fontweight='bold') plt.tight_layout() fig.savefig(os.path.join(FIG_DIR, '2021_H5_6_fig2.png'), bbox_inches='tight') plt.close() print("図2保存完了") |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。fig, ax = plt.subplots(...) — 図全体(fig)と軸(ax)を作る定番。以降は ax.bar(...) 等で操作。stats.pearsonr(x, y) — Pearson相関係数 r と p値を同時に返します。fig.savefig(..., bbox_inches='tight') — 余白を自動で詰めて保存。plt.close() でメモリ解放。df['A'] / df['B'] — pandasの列同士の四則演算は要素ごと(element-wise)。forループ不要なのが強み。184 | # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
図2保存完了
.map() は「1対1の置き換え」、.apply() は「関数を当てる」。辞書なら .map()、ロジックなら .apply()。相関・回帰分析で得られた知見を地域別の視点から検証する。大都市圏(関東・近畿)は消費支出が高くごみ排出量が少ない傾向にあり、環境配慮と生活水準の両立という仮説と整合する結果が得られた。
| 地域 | 平均消費支出 (円/月) |
平均ごみ排出量 (g/人/日) |
平均リサイクル率 (%) |
平均教養娯楽費 (円/月) |
|---|---|---|---|---|
| 北海道・東北 | 271,459 | 960.3 | 16.4 | 22,573 |
| 関東 | 315,528 | 874.4 | 19.4 | 30,671 |
| 中部 | 291,001 | 906.6 | 20.2 | 25,983 |
| 近畿 | 291,846 | 861.9 | 16.5 | 26,234 |
| 中国・四国 | 279,085 | 917.7 | 18.3 | 23,178 |
| 九州・沖縄 | 276,952 | 911.5 | 17.4 | 22,882 |
N=47 という小さなサンプルサイズでは、検出力(statistical power)が低い。 Cohen(1988)の基準では、N=47 で中程度の効果量(r=0.3)を検出するには有意水準 α=0.05 で検出力約 60% 程度しかない(理想は 80% 以上)。 また、都道府県データは独立同分布(i.i.d.)の仮定が成立しにくく、空間的自己相関(隣接県の類似性)が存在する可能性がある。
186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 | fig, ax = plt.subplots(figsize=(8, 5)) labels_jp = { 'ごみ排出量': 'ごみ排出量\n(環境負荷↑)', 'リサイクル率': 'リサイクル率\n(環境意識↑)', '気温': '年平均気温', '降水量': '年間降水量', '教養娯楽費': '教養娯楽費\n(余暇支出)', '出生率': '合計特殊出生率', } coefs = [coef_dict[v] for v in X_cols] pvals = [pval_dict[v] for v in X_cols] labels = [labels_jp[v] for v in X_cols] colors = ['#C62828' if c > 0 else '#1565C0' for c in coefs] alphas = [1.0 if p < 0.05 else 0.45 for p in pvals] bars = ax.barh(range(len(X_cols)), coefs, color=colors, alpha=0.75, height=0.6) for i, (bar, alpha) in enumerate(zip(bars, alphas)): bar.set_alpha(alpha) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。fig, ax = plt.subplots(...) — 図全体(fig)と軸(ax)を作る定番。以降は ax.bar(...) 等で操作。.map() は「1対1の置き換え」、.apply() は「関数を当てる」。辞書なら .map()、ロジックなら .apply()。206 207 208 209 210 211 212 213 | # 信頼区間(95%CI) ci = model.conf_int(alpha=0.05) ci_lo = ci.iloc[1:, 0].values ci_hi = ci.iloc[1:, 1].values for i in range(len(X_cols)): ax.plot([ci_lo[i], ci_hi[i]], [i, i], color='black', linewidth=1.5, zorder=5) ax.plot([ci_lo[i]], [i], '|', color='black', markersize=6) ax.plot([ci_hi[i]], [i], '|', color='black', markersize=6) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。[式 for x in リスト] はリスト内包表記。forループでappendする代わりに1行でリストを作れます。214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 | # p値注釈 for i, (c, p) in enumerate(zip(coefs, pvals)): sig_str = '**' if p < 0.01 else ('*' if p < 0.05 else 'ns') offset = 0.02 if c >= 0 else -0.02 ha = 'left' if c >= 0 else 'right' ax.text(c + offset, i, f' {sig_str}', ha=ha, va='center', fontsize=9, color='#C62828' if sig_str != 'ns' else '#888888') ax.set_yticks(range(len(X_cols))) ax.set_yticklabels(labels, fontsize=9) ax.axvline(0, color='black', linewidth=0.8) ax.set_xlabel('標準化偏回帰係数(β)', fontsize=11) ax.set_title(f'消費支出を目的変数とするOLS重回帰\n標準化偏回帰係数(R²={r2_val:.3f}、Adj.R²={adj_r2_val:.3f})\n* p<0.05, ** p<0.01, ns=非有意', fontsize=11, fontweight='bold') ax.grid(True, axis='x', linestyle=':', alpha=0.5) plt.tight_layout() fig.savefig(os.path.join(FIG_DIR, '2021_H5_6_fig3.png'), bbox_inches='tight') plt.close() print("図3保存完了") |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。ax.axhline / ax.axvline — 水平/垂直の点線。平均線や基準線として定番。fig.savefig(..., bbox_inches='tight') — 余白を自動で詰めて保存。plt.close() でメモリ解放。r, p = stats.pearsonr(...) — Pythonは複数戻り値を同時に受け取れる(タプルアンパック)。232 | # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
図3保存完了
x if cond else y は三項演算子。リスト内包表記と組み合わせると、forとifを1行で書けます。本分析の結果から、都道府県の「環境の質と生活水準」の関係について、以下の政策的示唆が得られた。 統計的な因果推論には慎重を要するが、相関分析・重回帰分析の結果は政策立案の参考となりうる。
234 235 236 237 238 239 240 241 242 | df_rank = df_ana[['都道府県', '地域', 'ごみ排出量']].sort_values('ごみ排出量', ascending=True).reset_index(drop=True) fig, ax = plt.subplots(figsize=(10, 12)) bar_colors = [region_colors[r] for r in df_rank['地域']] ax.barh(range(len(df_rank)), df_rank['ごみ排出量'], color=bar_colors, alpha=0.85, height=0.7, edgecolor='white', linewidth=0.3) ax.set_yticks(range(len(df_rank))) pref_labels = df_rank['都道府県'].str.replace('県', '').str.replace('府', '').str.replace('都', '').str.replace('道', '') ax.set_yticklabels(pref_labels, fontsize=8.5) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。fig, ax = plt.subplots(...) — 図全体(fig)と軸(ax)を作る定番。以降は ax.bar(...) 等で操作。sort_values('列名', ascending=False) — 指定列で並べ替え(降順)。[式 for x in リスト] はリスト内包表記。forループでappendする代わりに1行でリストを作れます。243 244 245 246 247 248 249 250 251 252 253 | # 全国平均線 avg_gomi = df_ana['ごみ排出量'].mean() ax.axvline(avg_gomi, color='#333333', linewidth=1.5, linestyle='--', label=f'全国平均 {avg_gomi:.0f}g') # 数値ラベル for i, val in enumerate(df_rank['ごみ排出量']): ax.text(val + 5, i, f'{val:.0f}', va='center', fontsize=7.5, color='#333') ax.set_xlabel('1人1日あたりごみ排出量(g)', fontsize=11) ax.set_title('都道府県別 1人1日あたりごみ排出量(2022年)\n(地域色分け)', fontsize=12, fontweight='bold') ax.legend(fontsize=9, loc='lower right') |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。ax.axhline / ax.axvline — 水平/垂直の点線。平均線や基準線として定番。r, p = stats.pearsonr(...) — Pythonは複数戻り値を同時に受け取れる(タプルアンパック)。254 255 256 257 258 259 260 261 262 263 | # 地域凡例 from matplotlib.patches import Patch legend_patches = [Patch(facecolor=c, label=r) for r, c in region_colors.items()] ax.legend(handles=legend_patches, fontsize=8.5, loc='lower right', framealpha=0.9, title='地域', title_fontsize=9) ax.grid(True, axis='x', linestyle=':', alpha=0.4) plt.tight_layout() fig.savefig(os.path.join(FIG_DIR, '2021_H5_6_fig4.png'), bbox_inches='tight') plt.close() print("図4保存完了") |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。import pandas as pd など — 必要なライブラリをまとめて呼び出します。as pd は短い別名(alias)。fig.savefig(..., bbox_inches='tight') — 余白を自動で詰めて保存。plt.close() でメモリ解放。x if cond else y は三項演算子。リスト内包表記と組み合わせると、forとifを1行で書けます。264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 | # ── 最終サマリー出力(HTML用) ────────────────────────────────── print("\n=== HTML記載用 統計値サマリー ===") gomi_r, gomi_p = stats.pearsonr(df_ana['ごみ排出量'], df_ana['消費支出']) recycl_r, recycl_p = stats.pearsonr(df_ana['リサイクル率'], df_ana['消費支出']) edu_r, edu_p = stats.pearsonr(df_ana['教養娯楽費'], df_ana['消費支出']) birth_r, birth_p = stats.pearsonr(df_ana['出生率'], df_ana['消費支出']) print(f" ごみ排出量 vs 消費支出: r={gomi_r:.3f}, p={gomi_p:.4f}") print(f" リサイクル率 vs 消費支出: r={recycl_r:.3f}, p={recycl_p:.4f}") print(f" 教養娯楽費 vs 消費支出: r={edu_r:.3f}, p={edu_p:.4f}") print(f" 出生率 vs 消費支出: r={birth_r:.3f}, p={birth_p:.4f}") print(f" OLS R²={r2_val:.3f}, Adj.R²={adj_r2_val:.3f}") print(f" F({model.df_model:.0f},{model.df_resid:.0f})={f_val:.2f}, p={f_pval:.4f}") print(f" 全国平均 ごみ排出量: {df_ana['ごみ排出量'].mean():.1f}g") print(f" 全国平均 消費支出: {df_ana['消費支出'].mean():.0f}円/月") print(f" 全国平均 合計特殊出生率: {df_ana['出生率'].mean():.3f}") # 最大・最小ごみ排出量都道府県 idx_max = df_ana['ごみ排出量'].idxmax() idx_min = df_ana['ごみ排出量'].idxmin() print(f" ごみ排出量 最大: {df_ana.loc[idx_max,'都道府県']} {df_ana.loc[idx_max,'ごみ排出量']:.0f}g") print(f" ごみ排出量 最小: {df_ana.loc[idx_min,'都道府県']} {df_ana.loc[idx_min,'ごみ排出量']:.0f}g") print("\n全ての図の生成が完了しました。") |
図4保存完了 === HTML記載用 統計値サマリー === ごみ排出量 vs 消費支出: r=-0.292, p=0.0463 リサイクル率 vs 消費支出: r=0.369, p=0.0106 教養娯楽費 vs 消費支出: r=0.781, p=0.0000 出生率 vs 消費支出: r=-0.336, p=0.0211 OLS R²=0.640, Adj.R²=0.586 F(6,40)=11.83, p=0.0000 全国平均 ごみ排出量: 906.1g 全国平均 消費支出: 289630円/月 全国平均 合計特殊出生率: 1.358 ごみ排出量 最大: 福島県 1021g ごみ排出量 最小: 京都府 770g 全ての図の生成が完了しました。
stats.pearsonr(x, y) — Pearson相関係数 r と p値を同時に返します。df[col](1列)と df[[col1, col2]](複数列)でカッコの数が違います。リストを渡していると覚えるとミスを減らせます。本研究では SSDSE-B の 47 都道府県データ(2022年)を用いて、環境指標(ごみ排出量・リサイクル率・気候条件)と住民生活の質(消費支出)の関係を相関分析・OLS 重回帰で分析した。
| データ | 出典 | 備考 |
|---|---|---|
| SSDSE-B 都道府県データ(2026年版) | 統計数理研究所 SSDSE(社会・人口統計体系) | 2022年断面、N=47 |
| ごみ排出量・リサイクル率 | 環境省「一般廃棄物処理事業実態調査」(SSDSE-B 収録) | 1人1日あたり(g) |
| 消費支出・教養娯楽費 | 総務省「家計調査」(SSDSE-B 収録) | 二人以上の世帯(円/月) |
| 合計特殊出生率 | 厚生労働省「人口動態統計」(SSDSE-B 収録) | 都道府県別 |
本教育用コードは実際の公的統計データ(SSDSE-B)のみを使用しています。合成データ・乱数シードは一切使用していません。
統計分析の解釈で初心者がやりがちな勘違いをまとめます。特に「相関と因果の混同」「p値の過信」は研究現場でもよく起きる落とし穴です。本文を読む前にも、読んだ後にも、目を通してみてください。
統計の基本用語を初心者向けに解説します。本文中で見慣れない言葉が出てきたら、ここに戻って確認してください。
統計手法について「何のためか」「結果をどう読むか」を初心者向けに解説します。
この研究をさらに発展させるための3つの方向性を示します。「今回わかったこと(X)」から「次に検証すべき仮説(Y)」を立て、「具体的に何をするか(Z)」まで考えてみましょう。
学んだだけでは身につきません。実際に手を動かすのが最強の学習方法です。本論文のスクリプトをベースに、以下のチャレンジに挑戦してみてください。難易度別に5つ用意しました。
本論文で学んだ手法は、研究の世界だけでなく、行政・企業・NPO の現場でも様々に活用されています。具体的なシーンを紹介します。
この論文を読んで初心者が抱きやすい疑問に、教育的観点から答えます。