このページの分析を自分で再現するには、以下の手順でデータを準備してください。コードの編集は不要です。
data/raw/ フォルダに入れます。html/figures/ に自動保存されます。
廃棄物問題は地球規模の課題として注目されており、SDGs目標12「つくる責任つかう責任」の達成には、ごみ排出量の削減とリサイクル率の向上が欠かせない。日本では一般廃棄物(ごみ)の排出量が年々減少傾向にあるが、都道府県間には依然として大きな格差が存在する。
まず「都道府県別ごみ排出量・環境負荷と経済発展の関係」を統計的にとらえることが有効だと考えられる。 その理由は感覚や経験則だけでは、複雑な社会要因の中で「何が本当に効いているか」を見極めにくいからである。 本研究では公開データと統計手法を組み合わせ、この問いに定量的な答えを出すことを目指す。
相関分析 重回帰分析 時系列分析 EKC仮説 SSDSE-B
政府統計の総合窓口(e-Stat)が提供する「社会・人口統計体系」都道府県別データセット(SSDSE-B)から、2012〜2023年の47都道府県データを使用。断面分析は2022年を基準年とした。
| カテゴリ | 変数名(SSDSE-B) | 単位 | 役割 |
|---|---|---|---|
| 環境負荷 | 1人1日当たりの排出量 | g/人/日 | 目的変数(主) |
| ごみのリサイクル率 | % | 目的変数(副) | |
| 経済・生活水準 | 消費支出(二人以上の世帯) | 円/月 | 所得代理変数 |
| 食料費(二人以上の世帯) | 円/月 | 生活パターン | |
| 光熱・水道費(二人以上の世帯) | 円/月 | 気候・省エネ代理 | |
| 都市規模 | 総人口 | 万人 | 都市化の代理 |
EKC仮説は国際比較(途上国〜先進国)で提唱された概念だが、一国内の都道府県間データでも「所得水準と環境意識・政策の差」を代理することで類似の関係が検証できる。重要なのは、相関の方向・強さだけでなく、なぜそのような関係が生じるかの経済的・社会的メカニズムを考察することにある。
| 変数 | 平均 | 標準偏差 | 最小 | 最大 |
|---|---|---|---|---|
| 1人1日当たりごみ排出量(g) | 906.1 | 61.5 | 770 | 1,021 |
| ごみリサイクル率(%) | 18.2 | 3.8 | 12.4 | 28.3 |
| 消費支出(万円/月) | 28.96 | 1.92 | 24.51 | 32.48 |
| 光熱・水道費(万円/月) | 2.51 | 0.34 | 1.79 | 3.32 |
全国および6地域(北海道・東北 / 関東 / 中部 / 近畿 / 中国・四国 / 九州・沖縄)の1人1日当たりごみ排出量の推移を2012年から2023年の12年間で追った。
| 年度 | 全国平均(g) | 前年比変化 | 主なトピック |
|---|---|---|---|
| 2012 | 961.4 | — | 基準年 |
| 2015 | 947.6 | −13.8 | 廃棄物処理法改正 |
| 2018 | 936.5 | −11.1 | プラスチック問題浮上 |
| 2020 | 922.5 | −15.4 | COVID-19(在宅増加) |
| 2022 | 906.1 | −8.1 | 物価高騰・節約志向 |
| 2023 | 878.1 | −28.0 | 最新データ・減少加速 |
環境指標を時系列で見る際には、①長期トレンド(系統的減少か?)、②構造変化(法改正・外部ショック)、③地域間格差の変化(収束か発散か)の3点に着目する。2020年のCOVID-19のような外部ショックは「自然実験」として作用し、生活行動変化とごみ排出量の因果関係を観察する貴重な機会を提供した。
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 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | # ── データ読み込み ────────────────────────────────────────────────────────────── 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) # 地域マップ region_map = { '北海道': '北海道・東北', '青森県': '北海道・東北', '岩手県': '北海道・東北', '宮城県': '北海道・東北', '秋田県': '北海道・東北', '山形県': '北海道・東北', '福島県': '北海道・東北', '茨城県': '関東', '栃木県': '関東', '群馬県': '関東', '埼玉県': '関東', '千葉県': '関東', '東京都': '関東', '神奈川県': '関東', '新潟県': '中部', '富山県': '中部', '石川県': '中部', '福井県': '中部', '山梨県': '中部', '長野県': '中部', '岐阜県': '中部', '静岡県': '中部', '愛知県': '中部', '三重県': '近畿', '滋賀県': '近畿', '京都府': '近畿', '大阪府': '近畿', '兵庫県': '近畿', '奈良県': '近畿', '和歌山県': '近畿', '鳥取県': '中国・四国', '島根県': '中国・四国', '岡山県': '中国・四国', '広島県': '中国・四国', '山口県': '中国・四国', '徳島県': '中国・四国', '香川県': '中国・四国', '愛媛県': '中国・四国', '高知県': '中国・四国', '福岡県': '九州・沖縄', '佐賀県': '九州・沖縄', '長崎県': '九州・沖縄', '熊本県': '九州・沖縄', '大分県': '九州・沖縄', '宮崎県': '九州・沖縄', '鹿児島県': '九州・沖縄', '沖縄県': '九州・沖縄' } region_colors = { '北海道・東北': '#4e9af1', '関東': '#e05c5c', '中部': '#f0a500', '近畿': '#5cb85c', '中国・四国': '#9b59b6', '九州・沖縄': '#f39c12' } |
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ループ不要なのが強み。43 44 45 46 47 48 49 | # 全データに地域列を追加 df_b['地域'] = df_b['都道府県'].map(region_map) # ── 2022年断面データ ──────────────────────────────────────────────────────────── df22 = df_b[df_b['年度'] == 2022].copy() df22 = df22.dropna(subset=['1人1日当たりの排出量', 'ごみのリサイクル率', '消費支出(二人以上の世帯)', '光熱・水道費(二人以上の世帯)']) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。.map() は「1対1の置き換え」、.apply() は「関数を当てる」。辞書なら .map()、ロジックなら .apply()。50 51 52 53 54 55 56 | # ── 基本統計の出力 ─────────────────────────────────────────────────────────────── print("=" * 60) print("2022年断面データ 基本統計(47都道府県)") print("=" * 60) cols_show = ['1人1日当たりの排出量', 'ごみのリサイクル率', '消費支出(二人以上の世帯)', '光熱・水道費(二人以上の世帯)'] print(df22[cols_show].describe().round(2)) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。.describe() — 件数・平均・標準偏差・四分位・最大/最小を一括計算。データの素性チェックに必須。[式 for x in リスト] はリスト内包表記。forループでappendする代わりに1行でリストを作れます。57 58 59 60 61 62 63 64 65 66 67 68 69 70 | # ── EKC仮説: 消費支出 × ごみ排出量 相関 ──────────────────────────────────────── x_ekc = df22['消費支出(二人以上の世帯)'].values y_ekc = df22['1人1日当たりの排出量'].values r_ekc, p_ekc = stats.pearsonr(x_ekc, y_ekc) print(f"\n消費支出 vs ごみ排出量: r = {r_ekc:.3f}, p = {p_ekc:.4f}") # ── 重回帰分析 ────────────────────────────────────────────────────────────────── # 目的変数: 1人1日当たりごみ排出量 # 説明変数: 消費支出, 光熱・水道費(温暖さの代理), 食料費, 総人口(都市規模) reg_df = df22[['1人1日当たりの排出量', '消費支出(二人以上の世帯)', '光熱・水道費(二人以上の世帯)', '食料費(二人以上の世帯)', '総人口']].dropna().copy() |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。stats.pearsonr(x, y) — Pearson相関係数 r と p値を同時に返します。r, p = stats.pearsonr(...) — Pythonは複数戻り値を同時に受け取れる(タプルアンパック)。71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | # 標準化(Zスコア) reg_z = (reg_df - reg_df.mean()) / reg_df.std() y_reg = reg_z['1人1日当たりの排出量'].values X_reg = reg_z[['消費支出(二人以上の世帯)', '光熱・水道費(二人以上の世帯)', '食料費(二人以上の世帯)', '総人口']].values X_reg_sm = sm.add_constant(X_reg) ols_model = sm.OLS(y_reg, X_reg_sm).fit() print("\n" + "=" * 60) print("重回帰分析 OLS結果(標準化係数)") print("=" * 60) print(ols_model.summary()) coef_names = ['消費支出', '光熱・水道費', '食料費', '総人口'] coefs = ols_model.params[1:] pvals = ols_model.pvalues[1:] conf_arr = ols_model.conf_int() conf = pd.DataFrame(conf_arr, columns=['lo', 'hi']).iloc[1:].reset_index(drop=True) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。sm.add_constant(X) — 切片項(定数1の列)を先頭に追加。statsmodelsで必須。sm.OLS(y, X).fit() — 最小二乗法でモデルを推定。model.params, model.pvalues, model.conf_int() で結果取得。x if cond else y は三項演算子。リスト内包表記と組み合わせると、forとifを1行で書けます。91 92 93 94 95 96 97 98 99 100 | # 出力保存用変数 r2 = ols_model.rsquared adj_r2 = ols_model.rsquared_adj f_stat = ols_model.fvalue f_pval = ols_model.f_pvalue n_obs = int(ols_model.nobs) print(f"\nR² = {r2:.3f}, Adj.R² = {adj_r2:.3f}") print(f"F統計量 = {f_stat:.2f}, p = {f_pval:.4f}") print(f"サンプル数 = {n_obs}") |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。df[col](1列)と df[[col1, col2]](複数列)でカッコの数が違います。リストを渡していると覚えるとミスを減らせます。101 102 103 104 105 106 107 108 109 | # 係数テーブル coef_table = pd.DataFrame({ '変数': coef_names, '標準化係数': coefs.round(3), 'p値': pvals.round(4), '下限95%CI': conf['lo'].round(3), '上限95%CI': conf['hi'].round(3) }) print(coef_table.to_string(index=False)) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。s[:-n]「末尾n文字を除く」/s[n:]「先頭n文字を除く」。スライス [start:stop:step] はリスト・タプル・文字列共通の基本ワザです。110 111 112 113 114 115 116 117 118 119 | # ── リサイクル率: トップ/ボトム確認 ──────────────────────────────────────────── print("\n" + "=" * 60) print("リサイクル率ランキング(2022年)") print("=" * 60) rec_rank = df22[['都道府県', 'ごみのリサイクル率', '地域']].sort_values( 'ごみのリサイクル率', ascending=False) print(rec_rank.to_string(index=False)) print(f"\n平均リサイクル率: {df22['ごみのリサイクル率'].mean():.1f}%") print(f"最高: {df22['ごみのリサイクル率'].max():.1f}% ({df22.loc[df22['ごみのリサイクル率'].idxmax(), '都道府県']})") print(f"最低: {df22['ごみのリサイクル率'].min():.1f}% ({df22.loc[df22['ごみのリサイクル率'].idxmin(), '都道府県']})") |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。sort_values('列名', ascending=False) — 指定列で並べ替え(降順)。np.cumsum(arr) は累積和、np.linspace(a, b, n) は「aからbを等間隔でn個」。NumPyの定石です。120 121 122 123 124 125 126 127 128 129 130 131 | # ── 時系列データ ──────────────────────────────────────────────────────────────── ts_years = list(range(2012, 2024)) df_ts = df_b[df_b['年度'].isin(ts_years)].copy() ts_region = df_ts.groupby(['年度', '地域'])['1人1日当たりの排出量'].mean().reset_index() ts_all = df_ts.groupby('年度')['1人1日当たりの排出量'].mean() print("\n" + "=" * 60) print("時系列: 全国平均ごみ排出量(2012〜2023年)") print("=" * 60) print(ts_all.round(1)) print(f"\n変化量: {ts_all[2023] - ts_all[2012]:.1f}g/人/日") print(f"変化率: {(ts_all[2023] / ts_all[2012] - 1) * 100:.1f}%") |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。df.groupby('列').apply(関数) — グループごとに関数を適用。時系列や地域別の集計でよく使います。{値:.2f}(小数2桁)、{値:,}(3桁区切り)、{値:>10}(右寄せ10桁)など、覚えると出力が一気に整います。132 133 134 135 136 137 138 139 140 141 | # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ fig1, ax1 = plt.subplots(figsize=(10, 6)) region_order = ['北海道・東北', '関東', '中部', '近畿', '中国・四国', '九州・沖縄'] for reg in region_order: sub = ts_region[ts_region['地域'] == reg].sort_values('年度') ax1.plot(sub['年度'], sub['1人1日当たりの排出量'], color=region_colors[reg], linewidth=2.2, marker='o', markersize=5, label=reg, zorder=3) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。fig, ax = plt.subplots(...) — 図全体(fig)と軸(ax)を作る定番。以降は ax.bar(...) 等で操作。sort_values('列名', ascending=False) — 指定列で並べ替え(降順)。plt.subplots(figsize=(W, H)) で図サイズ指定、fig.savefig(..., bbox_inches='tight') で余白を自動で詰めて保存。142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 | # 全国平均 ts_all_plot = ts_all.reset_index() ax1.plot(ts_all_plot['年度'], ts_all_plot['1人1日当たりの排出量'], color='#333333', linewidth=2.5, linestyle='--', marker='s', markersize=4, label='全国平均', zorder=4) # 2020年(コロナ禍)の縦線 ax1.axvline(x=2020, color='#aaaaaa', linestyle=':', linewidth=1.5, alpha=0.8) ax1.text(2020.1, ax1.get_ylim()[0] + 5, 'COVID-19', fontsize=9, color='#888888') ax1.set_xlabel('年度', fontsize=12) ax1.set_ylabel('1人1日当たりごみ排出量(g)', fontsize=12) ax1.set_title('図1: 地域別ごみ排出量の時系列推移(2012〜2023年)', fontsize=13, fontweight='bold') ax1.set_xlim(2011.5, 2023.5) ax1.set_xticks(ts_years) ax1.set_xticklabels([str(y) for y in ts_years], fontsize=9, rotation=45) ax1.legend(loc='upper right', fontsize=10, ncol=2) ax1.grid(axis='y', alpha=0.4, linewidth=0.8) ax1.grid(axis='x', alpha=0.2, linewidth=0.5) ax1.spines['top'].set_visible(False) ax1.spines['right'].set_visible(False) fig1.tight_layout() fig1.savefig(os.path.join(FIG_DIR, '2020_H5_4_fig1.png'), dpi=150, bbox_inches='tight') plt.close(fig1) print("\n[FIG1] 保存完了: 2020_H5_4_fig1.png") |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。ax.axhline / ax.axvline — 水平/垂直の点線。平均線や基準線として定番。.dropna() は欠損行を除去、.copy() は独立したコピーを作る。pandasで警告を防ぐ定石。168 | # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
============================================================
2022年断面データ 基本統計(47都道府県)
============================================================
1人1日当たりの排出量 ごみのリサイクル率 消費支出(二人以上の世帯) 光熱・水道費(二人以上の世帯)
count 47.00 47.00 47.00 47.00
mean 906.09 18.21 289630.36 25119.47
std 61.51 3.83 19186.91 3377.69
min 770.00 12.40 245054.00 17897.00
25% 863.50 15.30 276834.50 22709.00
50% 911.00 16.90 287781.00 24556.00
75% 951.50 21.25 302255.00 27403.50
max 1021.00 28.30 324793.00 33197.00
消費支出 vs ごみ排出量: r = -0.292, p = 0.0463
============================================================
重回帰分析 OLS結果(標準化係数)
============================================================
OLS Regression Results
==============================================================================
Dep. Variable: y R-squared: 0.289
Model: OLS Adj. R-squared: 0.222
Method: Least Squares F-statistic: 4.278
Date: Mon, 18 May 2026 Prob (F-statistic): 0.00541
Time: 11:23:39 Log-Likelihood: -58.154
No. Observations: 47 AIC: 126.3
Df Residuals: 42 BIC: 135.6
Df Model: 4
Covariance Type: nonrobust
==============================================================================
coef std err t P>|t| [0.025 0.975]
------------------------------------------------------------------------------
const -8.847e-16 0.129 -6.88e-15 1.000 -0.260 0.260
x1 -0.0340 0.190 -0.179 0.859 -0.417 0.349
x2 0.3269 0.145 2.250 0.030 0.034 0.620
x3 -0.3070 0.231 -1.332 0.190 -0.772 0.158
x4 -0.1429 0.179 -0.801 0.428 -0.503 0.217
==============================================================================
Omnibus: 0.456 Durbin-Watson: 1.979
Prob(Omnibus): 0.796 Jarque-Bera (JB): 0.601
Skew: -0.185 Prob(JB): 0.741
Kurtosis: 2.587 Cond. No. 3.32
==============================================================================
Notes:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
R² = 0.289, Adj.R² = 0.222
F統計量 = 4.28, p = 0.0054
サンプル数 = 47
変数 標準化係数 p値 下限95%CI 上限95%CI
消費支出 -0.034 0.8587 -0.417 0.349
光熱・水道費 0.327 0.0297 0.034 0.620
食料費 -0.307 0.1901 -0.772 0.158
総人口 -0.143 0.4279 -0.503 0.217
============================================================
リサイクル率ランキング(2022年)
============================================================
都道府県 ごみのリサイクル率 地域
鳥取県 28.3 中国・四国
神奈川県 24.4 関東
埼玉県 24.4 関東
東京都 23.9 関東
岡山県 23.5 中国・四国
北海道 22.9 北海道・東北
山口県 22.7 中国・四国
千葉県 22.6 関東
愛知県 22.2 中部
長野県 22.0 中部
福岡県 21.8 九州・沖縄
富山県 21.5 中部
茨城県 21.0 関東
広島県 20.5 中国・四国
高知県 20.1 中国・四国
新潟県 19.9 中部
熊本県 19.8 九州・沖縄
島根県 19.8 中国・四国
三重
…(長いため省略)f"...{x}..." はf-string。文字列の中に {変数} と書くだけで埋め込めて、{x:.2f} のように書式も指定できます。まず消費支出(所得の代理変数)とごみ排出量の2変量の関係を2022年の断面データで確認した。
| 説明変数 | 標準化係数(β) | p値 | 95% CI(下限) | 95% CI(上限) | 判定 |
|---|---|---|---|---|---|
| 消費支出 | −0.034 | 0.859 | −0.417 | 0.349 | n.s. |
| 光熱・水道費 | +0.327 | 0.030 | +0.034 | +0.620 | * p<0.05 |
| 食料費 | −0.307 | 0.190 | −0.772 | 0.158 | n.s. |
| 総人口 | −0.143 | 0.428 | −0.503 | 0.217 | n.s. |
モデル適合度: R² = 0.289, 調整済み R² = 0.222, F(4, 42) = 4.278, p = 0.005, n = 47都道府県(2022年)
消費支出(円/月)と総人口(人)は単位が全く異なるため、生の偏回帰係数を直接比べることはできない。Zスコア標準化してから OLS を実行すると、各変数の係数(標準化偏回帰係数 β)が「1標準偏差の変化に対するごみ排出量の変化」を標準化した単位で示し、変数間の相対的な重要度を比較できる。
170 171 172 173 174 175 176 177 178 179 180 181 182 183 | fig2, ax2 = plt.subplots(figsize=(10, 8)) for _, row in df22.iterrows(): reg = row['地域'] col = region_colors.get(reg, '#999999') ax2.scatter(row['消費支出(二人以上の世帯)'] / 10000, row['1人1日当たりの排出量'], color=col, s=80, alpha=0.85, zorder=3, edgecolors='white', linewidth=0.5) # 都道府県名ラベル(小さめ) ax2.annotate(row['都道府県'].replace('県', '').replace('府', '').replace('都', '').replace('道', ''), (row['消費支出(二人以上の世帯)'] / 10000, row['1人1日当たりの排出量']), fontsize=7, ha='center', va='bottom', xytext=(0, 4), textcoords='offset points', color='#444444') |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。fig, ax = plt.subplots(...) — 図全体(fig)と軸(ax)を作る定番。以降は ax.bar(...) 等で操作。for _, row in df.iterrows() — DataFrameを1行ずつ取り出すループ。1点ずつ描画したいときに使用。df['A'] / df['B'] — pandasの列同士の四則演算は要素ごと(element-wise)。forループ不要なのが強み。184 185 186 187 188 189 190 | # 線形回帰フィット x_fit = df22['消費支出(二人以上の世帯)'].values / 10000 y_fit = df22['1人1日当たりの排出量'].values slope, intercept, r_val, p_val, se = stats.linregress(x_fit, y_fit) x_line = np.linspace(x_fit.min(), x_fit.max(), 100) ax2.plot(x_line, intercept + slope * x_line, color='#333333', linewidth=1.8, linestyle='--', alpha=0.7, label=f'回帰直線 (r={r_val:.3f})') |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。stats.linregress(x, y) — 単回帰の傾き・切片・r値・p値・標準誤差を返します。使わない値は _ で受け取り。.map() は「1対1の置き換え」、.apply() は「関数を当てる」。辞書なら .map()、ロジックなら .apply()。191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 | # 凡例(地域) from matplotlib.lines import Line2D handles = [Line2D([0], [0], marker='o', color='w', markerfacecolor=region_colors[r], markersize=9, label=r) for r in region_order] handles.append(Line2D([0], [0], color='#333333', linewidth=1.8, linestyle='--', label=f'回帰直線 (r={r_val:.3f}, p={p_val:.3f})')) ax2.legend(handles=handles, loc='upper left', fontsize=9, framealpha=0.9) ax2.set_xlabel('消費支出(万円/月・世帯)', fontsize=12) ax2.set_ylabel('1人1日当たりごみ排出量(g)', fontsize=12) ax2.set_title('図2: 消費支出とごみ排出量の関係(2022年・47都道府県)\n' '─ EKC仮説(環境クズネッツ曲線)の検証 ─', fontsize=12, fontweight='bold') ax2.grid(alpha=0.3, linewidth=0.8) ax2.spines['top'].set_visible(False) ax2.spines['right'].set_visible(False) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。import pandas as pd など — 必要なライブラリをまとめて呼び出します。as pd は短い別名(alias)。[式 for x in リスト] はリスト内包表記。forループでappendする代わりに1行でリストを作れます。206 207 208 209 210 211 212 213 214 215 | # 注釈: EKC ax2.text(0.97, 0.05, f'Pearson r = {r_val:.3f}\np = {p_val:.3f}\nn = 47都道府県', transform=ax2.transAxes, fontsize=10, ha='right', va='bottom', bbox=dict(boxstyle='round,pad=0.5', facecolor='#FFF9C4', alpha=0.9)) fig2.tight_layout() fig2.savefig(os.path.join(FIG_DIR, '2020_H5_4_fig2.png'), dpi=150, bbox_inches='tight') plt.close(fig2) print("[FIG2] 保存完了: 2020_H5_4_fig2.png") |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。r, p = stats.pearsonr(...) — Pythonは複数戻り値を同時に受け取れる(タプルアンパック)。216 | # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
[FIG2] 保存完了: 2020_H5_4_fig2.png
x if cond else y は三項演算子。リスト内包表記と組み合わせると、forとifを1行で書けます。ごみ排出量の削減だけでなく、リサイクル率(ごみのうち資源として再利用される割合)も重要な環境指標である。47都道府県のリサイクル率を比較し、地域差を可視化した。
リサイクル率は「廃棄物政策の成果」を示す指標だが、高さが必ずしも「良い」とは言えない。例えば、そもそも排出量が少ない都道府県はリサイクル率が低くても環境負荷が小さい場合がある。政策評価では「ごみ排出量(排出抑制)」と「リサイクル率(再資源化)」を組み合わせた複合指標で評価することが重要で、単一指標への過度な依存は意思決定を誤らせる。
218 219 220 221 222 223 224 225 226 227 228 | rec_sorted = df22.sort_values('ごみのリサイクル率', ascending=True).reset_index(drop=True) colors_bar = [region_colors.get(r, '#999999') for r in rec_sorted['地域']] labels_bar = [p.replace('県', '').replace('府', '').replace('都', '').replace('道', '') for p in rec_sorted['都道府県']] fig3, ax3 = plt.subplots(figsize=(9, 12)) bars = ax3.barh(range(len(rec_sorted)), rec_sorted['ごみのリサイクル率'], color=colors_bar, edgecolor='white', linewidth=0.5, height=0.8) ax3.set_yticks(range(len(rec_sorted))) ax3.set_yticklabels(labels_bar, fontsize=9) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。fig, ax = plt.subplots(...) — 図全体(fig)と軸(ax)を作る定番。以降は ax.bar(...) 等で操作。sort_values('列名', ascending=False) — 指定列で並べ替え(降順)。.map() は「1対1の置き換え」、.apply() は「関数を当てる」。辞書なら .map()、ロジックなら .apply()。229 230 231 232 233 234 235 236 237 | # 値ラベル for i, (val, bar) in enumerate(zip(rec_sorted['ごみのリサイクル率'], bars)): ax3.text(val + 0.2, i, f'{val:.1f}%', va='center', fontsize=8, color='#333333') # 全国平均線 mean_rec = df22['ごみのリサイクル率'].mean() ax3.axvline(x=mean_rec, color='#333333', linewidth=1.5, linestyle='--', alpha=0.8) ax3.text(mean_rec + 0.3, len(rec_sorted) - 0.5, f'全国平均\n{mean_rec:.1f}%', fontsize=9, color='#333333', va='top') |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。ax.axhline / ax.axvline — 水平/垂直の点線。平均線や基準線として定番。[式 for x in リスト] はリスト内包表記。forループでappendする代わりに1行でリストを作れます。238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 | # 地域凡例 from matplotlib.patches import Patch legend_patches = [Patch(color=region_colors[r], label=r) for r in region_order] ax3.legend(handles=legend_patches, loc='lower right', fontsize=9, framealpha=0.9) ax3.set_xlabel('ごみリサイクル率(%)', fontsize=12) ax3.set_title('図3: 都道府県別ごみリサイクル率ランキング(2022年)', fontsize=13, fontweight='bold') ax3.set_xlim(0, rec_sorted['ごみのリサイクル率'].max() + 4) ax3.grid(axis='x', alpha=0.4, linewidth=0.8) ax3.spines['top'].set_visible(False) ax3.spines['right'].set_visible(False) fig3.tight_layout() fig3.savefig(os.path.join(FIG_DIR, '2020_H5_4_fig3.png'), dpi=150, bbox_inches='tight') plt.close(fig3) print("[FIG3] 保存完了: 2020_H5_4_fig3.png") |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。import pandas as pd など — 必要なライブラリをまとめて呼び出します。as pd は短い別名(alias)。r, p = stats.pearsonr(...) — Pythonは複数戻り値を同時に受け取れる(タプルアンパック)。254 | # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
[FIG3] 保存完了: 2020_H5_4_fig3.png
x if cond else y は三項演算子。リスト内包表記と組み合わせると、forとifを1行で書けます。分析結果をもとに、ごみ排出量の削減とリサイクル率向上に向けた政策提言を以下に示す。
光熱・水道費が高い(寒冷地)都道府県でごみ排出量が多い傾向が統計的に確認された。北海道・東北地方では、生活スタイルや暖房・包装材の使用量に配慮した廃棄物削減の啓発と、省エネ・ごみ減量の統合的アプローチが有効と考えられる。
鳥取県(28.3%)や神奈川県(24.4%)など高リサイクル率都道府県の施策(詳細な分別体制・資源回収拠点の整備・住民教育)を分析し、低リサイクル率地域(特に近畿)への水平展開を推進する。
ごみ排出量の少なさとリサイクル率の高さを同時に評価する都道府県別スコアリングシステムを構築し、総合的な廃棄物政策の効果を可視化・比較することで、行政の説明責任を高める。
日本は既にEKC曲線の「峠」を越え、経済成長とごみ削減が両立する段階にある。今後は消費行動の変革(フードロス削減・シェアリングエコノミー・デジタル化による包装材削減)を政策的に後押しし、2030年目標の達成を目指す。
256 257 258 259 260 261 262 263 264 | fig4, ax4 = plt.subplots(figsize=(8, 5)) y_pos = range(len(coef_names)) bar_colors = ['#e05c5c' if c > 0 else '#4e9af1' for c in coefs] ax4.barh(y_pos, coefs, color=bar_colors, edgecolor='white', height=0.55, alpha=0.85) # 信頼区間 for i, (lo, hi) in enumerate(zip(conf['lo'], conf['hi'])): ax4.plot([lo, hi], [i, i], color='#333333', linewidth=2.5, solid_capstyle='round') |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。fig, ax = plt.subplots(...) — 図全体(fig)と軸(ax)を作る定番。以降は ax.bar(...) 等で操作。[式 for x in リスト] はリスト内包表記。forループでappendする代わりに1行でリストを作れます。265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 | # 有意性マーク for i, (c, p) in enumerate(zip(coefs, pvals)): mark = '**' if p < 0.01 else ('*' if p < 0.05 else '') sign = '†' if p < 0.10 else '' label = mark if mark else sign if label: ax4.text(c + (0.02 if c >= 0 else -0.02), i, label, ha='left' if c >= 0 else 'right', va='center', fontsize=12, fontweight='bold', color='#C62828') ax4.axvline(x=0, color='#333333', linewidth=1.2, linestyle='-') ax4.set_yticks(y_pos) ax4.set_yticklabels(coef_names, fontsize=11) ax4.set_xlabel('標準化偏回帰係数(β)', fontsize=12) ax4.set_title('図4: ごみ排出量の重回帰分析 — 標準化偏回帰係数\n' f'(R² = {r2:.3f}, n = {n_obs}都道府県, 2022年)', fontsize=12, fontweight='bold') ax4.text(0.97, 0.05, '** p<0.01 * p<0.05 † p<0.10\n横棒: 95%信頼区間', transform=ax4.transAxes, fontsize=9, ha='right', va='bottom', bbox=dict(boxstyle='round,pad=0.4', facecolor='#F8F9FA', alpha=0.9)) ax4.grid(axis='x', alpha=0.4, linewidth=0.8) ax4.spines['top'].set_visible(False) ax4.spines['right'].set_visible(False) fig4.tight_layout() fig4.savefig(os.path.join(FIG_DIR, '2020_H5_4_fig4.png'), dpi=150, bbox_inches='tight') plt.close(fig4) print("[FIG4] 保存完了: 2020_H5_4_fig4.png") print("\n" + "=" * 60) print("全図の生成が完了しました。") print(f" 図の保存先: {os.path.abspath(FIG_DIR)}") print("=" * 60) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。ax.axhline / ax.axvline — 水平/垂直の点線。平均線や基準線として定番。r, p = stats.pearsonr(...) — Pythonは複数戻り値を同時に受け取れる(タプルアンパック)。301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 | # ── HTML用の統計値まとめ出力 ───────────────────────────────────────────────── print("\n[HTML用統計値]") print(f"全国平均ごみ排出量(2022年): {df22['1人1日当たりの排出量'].mean():.1f} g/人/日") print(f"全国平均ごみ排出量(2012年): {ts_all[2012]:.1f} g/人/日") print(f"全国平均ごみ排出量(2023年): {ts_all[2023]:.1f} g/人/日") print(f"10年間減少量: {ts_all[2012] - ts_all[2023]:.1f} g") print(f"減少率: {(1 - ts_all[2023]/ts_all[2012]) * 100:.1f}%") print(f"全国平均リサイクル率(2022年): {df22['ごみのリサイクル率'].mean():.1f}%") print(f"リサイクル率最高: {df22['ごみのリサイクル率'].max():.1f}% - {df22.loc[df22['ごみのリサイクル率'].idxmax(), '都道府県']}") print(f"リサイクル率最低: {df22['ごみのリサイクル率'].min():.1f}% - {df22.loc[df22['ごみのリサイクル率'].idxmin(), '都道府県']}") print(f"消費支出 vs ごみ排出量: r = {r_ekc:.3f}, p = {p_ekc:.4f}") print(f"重回帰 R² = {r2:.3f}, F = {f_stat:.2f}, p = {f_pval:.4f}") for name, c, p in zip(coef_names, coefs, pvals): sig = '**' if p < 0.01 else ('*' if p < 0.05 else ('†' if p < 0.10 else 'ns')) print(f" {name}: β = {c:.3f}, p = {p:.4f} [{sig}]") |
[FIG4] 保存完了: 2020_H5_4_fig4.png ============================================================ 全図の生成が完了しました。 図の保存先: /Users/shimpei/Dropbox/Works_Researches/2026 統計・データ解析コンペ/html/figures ============================================================ [HTML用統計値] 全国平均ごみ排出量(2022年): 906.1 g/人/日 全国平均ごみ排出量(2012年): 961.4 g/人/日 全国平均ごみ排出量(2023年): 878.1 g/人/日 10年間減少量: 83.2 g 減少率: 8.7% 全国平均リサイクル率(2022年): 18.2% リサイクル率最高: 28.3% - 鳥取県 リサイクル率最低: 12.4% - 和歌山県 消費支出 vs ごみ排出量: r = -0.292, p = 0.0463 重回帰 R² = 0.289, F = 4.28, p = 0.0054 消費支出: β = -0.034, p = 0.8587 [ns] 光熱・水道費: β = 0.327, p = 0.0297 [*] 食料費: β = -0.307, p = 0.1901 [ns] 総人口: β = -0.143, p = 0.4279 [ns]
x if cond else y は三項演算子。リスト内包表記と組み合わせると、forとifを1行で書けます。本分析は SSDSE-B-2026(政府統計の総合窓口)の実データを使用した。Python スクリプトは 2020_H5_4_shorei.py を参照。
| ファイル | 内容 |
|---|---|
| SSDSE-B-2026.csv | 47都道府県 × 2012〜2023年 × 112変数(政府統計・e-Stat) |
| 2020_H5_4_shorei.py | 本分析の Python スクリプト(再現可能) |
| 2020_H5_4_fig1〜4.png | 本ページの4図 |
統計分析の解釈で初心者がやりがちな勘違いをまとめます。特に「相関と因果の混同」「p値の過信」は研究現場でもよく起きる落とし穴です。本文を読む前にも、読んだ後にも、目を通してみてください。
統計の基本用語を初心者向けに解説します。本文中で見慣れない言葉が出てきたら、ここに戻って確認してください。
統計手法について「何のためか」「結果をどう読むか」を初心者向けに解説します。
この研究をさらに発展させるための3つの方向性を示します。「今回わかったこと(X)」から「次に検証すべき仮説(Y)」を立て、「具体的に何をするか(Z)」まで考えてみましょう。
学んだだけでは身につきません。実際に手を動かすのが最強の学習方法です。本論文のスクリプトをベースに、以下のチャレンジに挑戦してみてください。難易度別に5つ用意しました。
本論文で学んだ手法は、研究の世界だけでなく、行政・企業・NPO の現場でも様々に活用されています。具体的なシーンを紹介します。
この論文を読んで初心者が抱きやすい疑問に、教育的観点から答えます。