このページの分析を自分で再現するには、以下の手順でデータを準備してください。コードの編集は不要です。
data/raw/ フォルダに入れます。html/figures/ に自動保存されます。
日本では家庭ごみの削減とリサイクル率の向上が長年の環境政策課題となっている。しかし「なぜある都道府県は他より排出量が少ないのか」「リサイクル率の地域格差はどう説明できるか」という問いには、単純な人口規模だけでは答えられない。本論文では SSDSE-B の47都道府県パネルデータを用い、高齢化率・消費支出水準・観光地密度がごみ排出量とリサイクル率にどう影響するかを統計的に分析した。
まず「ごみ排出量とリサイクル率の社会経済的要因:都道府県別パネル分析」を統計的にとらえることが有効だと考えられる。 その理由は感覚や経験則だけでは、複雑な社会要因の中で「何が本当に効いているか」を見極めにくいからである。 本研究では公開データと統計手法を組み合わせ、この問いに定量的な答えを出すことを目指す。
SSDSE-B(都道府県) パネルデータ OLS回帰 環境統計
SSDSE(社会・人口統計体系データセット)-B は都道府県レベルの社会経済統計を年度別にまとめたパネルデータである。本分析では2012〜2023年度(12年間)×47都道府県 = 564件のデータを使用した。
| 変数名 | 定義・計算方法 | SSDSEコード | 単位 |
|---|---|---|---|
| ごみ排出量(目的変数) | 1人1日当たりの排出量 | H5610 | g/人/日 |
| リサイクル率(目的変数) | ごみのリサイクル率 | H5614 | % |
| 高齢化率 | 65歳以上人口 ÷ 総人口 × 100 | A1303 / A1101 | % |
| 消費支出_log | log(消費支出:二人以上の世帯) | L3221 | log(円/月) |
| 旅館密度 | 旅館営業施設数 ÷(総人口/10,000) | C3801 / A1101 | 施設/万人 |
「ごみ総排出量」を都道府県間で比較するには、人口規模の違いを除去する必要がある。1人1日あたり排出量(g/人/日)は最も直感的な標準化指標だが、さらに統計分析のために変数を「標準化(z-score化)」すると、係数の大きさで変数の影響力を直接比較できる。
まず2012〜2023年度の全国平均(47都道府県の単純平均)でごみ排出量とリサイクル率がどのように推移したかを確認する。2つの指標を同時に示すために2軸グラフ(twinx)を使用した。
単位や数値範囲が異なる2つの指標を同じグラフで比較するには、matplotlib の twinx() を使う。ただし「2軸グラフは読み手を誤解させやすい」という批判もある。右軸のスケール設定により見かけ上の相関が変わるため、凡例の色分けと軸ラベルの明示が必須。
1 2 3 4 5 6 7 8 9 10 11 12 13 | import os import warnings import numpy as np import pandas as pd import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt import matplotlib.patches as mpatches from matplotlib import rcParams import statsmodels.api as sm from scipy import stats warnings.filterwarnings('ignore') |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。import pandas as pd など — 必要なライブラリをまとめて呼び出します。as pd は短い別名(alias)。matplotlib.use('Agg') — グラフを画面表示せずファイルに保存するためのおまじない。f"...{x}..." はf-string。文字列の中に {変数} と書くだけで埋め込めて、{x:.2f} のように書式も指定できます。14 15 16 17 18 19 20 21 22 23 24 | # ── パス設定 ───────────────────────────────────────────────────────────────── FIG_DIR = 'html/figures' DATA_B = 'data/raw/SSDSE-B-2026.csv' os.makedirs(FIG_DIR, exist_ok=True) # ── フォント設定 ─────────────────────────────────────────────────────────────── rcParams['font.family'] = ['Hiragino Sans', 'Hiragino Kaku Gothic ProN', 'AppleGothic', 'Noto Sans CJK JP', 'sans-serif'] rcParams['axes.unicode_minus'] = False DPI = 150 |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。os.makedirs('html/figures', exist_ok=True) — 図の保存先フォルダを作る(既にあってもOK)。df['A'] / df['B'] — pandasの列同士の四則演算は要素ごと(element-wise)。forループ不要なのが強み。25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | # ── データ読み込み ───────────────────────────────────────────────────────────── df_raw = pd.read_csv(DATA_B, encoding='cp932', header=None) col_names = df_raw.iloc[1].tolist() df = df_raw.iloc[2:].reset_index(drop=True) df.columns = col_names # 数値変換 numeric_cols = [ '年度', '総人口', '65歳以上人口', 'ごみ総排出量(総量)', '1人1日当たりの排出量', 'ごみのリサイクル率', '旅館営業施設数(ホテルを含む)', '消費支出(二人以上の世帯)', ] for c in numeric_cols: df[c] = pd.to_numeric(df[c], errors='coerce') df = df.dropna(subset=['1人1日当たりの排出量', 'ごみのリサイクル率']) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。pd.read_csv(...) でCSVを読み込みます。encoding='cp932' は日本語Windows由来の文字コード、header=1 は「2行目を列名として使う」。.map() は「1対1の置き換え」、.apply() は「関数を当てる」。辞書なら .map()、ロジックなら .apply()。41 42 43 44 45 46 | # ── 派生変数の作成 ───────────────────────────────────────────────────────────── # 高齢化率(%) df['高齢化率'] = df['65歳以上人口'] / df['総人口'] * 100 # 消費支出の対数(円 → log(円)) df['消費支出_log'] = np.log(df['消費支出(二人以上の世帯)']) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。[式 for x in リスト] はリスト内包表記。forループでappendする代わりに1行でリストを作れます。47 48 49 50 51 52 | # 旅館密度(1万人あたり施設数) df['旅館密度'] = df['旅館営業施設数(ホテルを含む)'] / (df['総人口'] / 10000) # 変数名を分析用に短縮 df['ごみ排出量_g'] = df['1人1日当たりの排出量'] # g/人/日 df['リサイクル率'] = df['ごみのリサイクル率'] # % |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。r, p = stats.pearsonr(...) — Pythonは複数戻り値を同時に受け取れる(タプルアンパック)。53 54 55 56 57 58 59 60 61 62 63 64 65 66 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 112 113 114 115 116 117 118 119 120 121 122 123 | # ── 地域ブロック定義 ─────────────────────────────────────────────────────────── REGION_MAP = { '北海道': '北海道・東北', '青森県': '北海道・東北', '岩手県': '北海道・東北', '宮城県': '北海道・東北', '秋田県': '北海道・東北', '山形県': '北海道・東北', '福島県': '北海道・東北', '茨城県': '関東', '栃木県': '関東', '群馬県': '関東', '埼玉県': '関東', '千葉県': '関東', '東京都': '関東', '神奈川県': '関東', '新潟県': '中部', '富山県': '中部', '石川県': '中部', '福井県': '中部', '山梨県': '中部', '長野県': '中部', '岐阜県': '中部', '静岡県': '中部', '愛知県': '中部', '三重県': '近畿', '滋賀県': '近畿', '京都府': '近畿', '大阪府': '近畿', '兵庫県': '近畿', '奈良県': '近畿', '和歌山県': '近畿', '鳥取県': '中国・四国', '島根県': '中国・四国', '岡山県': '中国・四国', '広島県': '中国・四国', '山口県': '中国・四国', '徳島県': '中国・四国', '香川県': '中国・四国', '愛媛県': '中国・四国', '高知県': '中国・四国', '福岡県': '九州・沖縄', '佐賀県': '九州・沖縄', '長崎県': '九州・沖縄', '熊本県': '九州・沖縄', '大分県': '九州・沖縄', '宮崎県': '九州・沖縄', '鹿児島県': '九州・沖縄', '沖縄県': '九州・沖縄', } REGION_COLORS = { '北海道・東北': '#1565C0', '関東': '#C62828', '中部': '#F9A825', '近畿': '#2E7D32', '中国・四国': '#6A1B9A', '九州・沖縄': '#00838F', } df['地域'] = df['都道府県'].map(REGION_MAP).fillna('その他') print("データ読み込み完了") print(f" 年度: {sorted(df['年度'].dropna().astype(int).unique())}") print(f" 都道府県数(2022年): {len(df[df['年度']==2022])}") print("\n[Fig1] 時系列推移(twinx)...") ts = (df.groupby('年度')[['ごみ排出量_g', 'リサイクル率']] .mean() .reset_index() .sort_values('年度')) fig, ax1 = plt.subplots(figsize=(9, 5), dpi=DPI) ax2 = ax1.twinx() color1 = '#1565C0' color2 = '#C62828' l1, = ax1.plot(ts['年度'], ts['ごみ排出量_g'], color=color1, linewidth=2.5, marker='o', markersize=7, label='1人1日当たりごみ排出量(g)') ax1.set_xlabel('年度', fontsize=12) ax1.set_ylabel('1人1日当たりごみ排出量(g/人/日)', color=color1, fontsize=11) ax1.tick_params(axis='y', labelcolor=color1) ax1.set_ylim(820, 1020) l2, = ax2.plot(ts['年度'], ts['リサイクル率'], color=color2, linewidth=2.5, marker='s', markersize=7, linestyle='--', label='ごみのリサイクル率(%)') ax2.set_ylabel('ごみのリサイクル率(%)', color=color2, fontsize=11) ax2.tick_params(axis='y', labelcolor=color2) ax2.set_ylim(16, 24) ax1.set_title('ごみ排出量とリサイクル率の時系列推移(全国47都道府県平均)\n2012〜2023年度', fontsize=13, fontweight='bold', pad=14) ax1.set_xticks(ts['年度']) ax1.set_xticklabels([str(int(y)) for y in ts['年度']], rotation=45, ha='right') ax1.grid(axis='y', linestyle='--', alpha=0.4) lines = [l1, l2] labels = [l.get_label() for l in lines] ax1.legend(lines, labels, loc='upper right', fontsize=10, framealpha=0.9, edgecolor='#ccc') |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。.astype(int) — 列を整数に変換(年度などを数値比較するため)。df.groupby('列').apply(関数) — グループごとに関数を適用。時系列や地域別の集計でよく使います。fig, ax = plt.subplots(...) — 図全体(fig)と軸(ax)を作る定番。以降は ax.bar(...) 等で操作。sort_values('列名', ascending=False) — 指定列で並べ替え(降順)。x if cond else y は三項演算子。リスト内包表記と組み合わせると、forとifを1行で書けます。124 125 126 127 128 129 130 131 132 133 134 135 | # 注釈 ax1.annotate('ごみ排出量は\n一貫して減少傾向', xy=(2017, ts.loc[ts['年度']==2017, 'ごみ排出量_g'].values[0]), xytext=(2014, 875), fontsize=9, color=color1, arrowprops=dict(arrowstyle='->', color=color1, lw=1.2)) plt.tight_layout() out1 = os.path.join(FIG_DIR, '2022_H5_16_fig1_timeseries.png') plt.savefig(out1, dpi=DPI, bbox_inches='tight') plt.close() print(f" 保存: {out1}") |
データ読み込み完了 年度: [np.int64(2012), np.int64(2013), np.int64(2014), np.int64(2015), np.int64(2016), np.int64(2017), np.int64(2018), np.int64(2019), np.int64(2020), np.int64(2021), np.int64(2022), np.int64(2023)] 都道府県数(2022年): 47 [Fig1] 時系列推移(twinx)... findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic P …(長いため省略)
fig.savefig(..., bbox_inches='tight') — 余白を自動で詰めて保存。plt.close() でメモリ解放。df[col](1列)と df[[col1, col2]](複数列)でカッコの数が違います。リストを渡していると覚えるとミスを減らせます。消費水準とごみ排出量の関係を2022年度データで確認する。横軸に消費支出(対数変換)、縦軸にごみ排出量をとり、各点は都道府県を表す。地域ブロックによって色分けし、外れ値となる都道府県の識別も行った。
| 指標 | 値 | 解釈 |
|---|---|---|
| ピアソン相関係数 r | −0.285 | 弱い負の相関:消費が高いほどやや排出量少 |
| p値 | 0.052 | 有意水準5%でぎりぎり非有意(境界例) |
| 観測数 N | 47 | 都道府県数(標本小さく統計力が限定的) |
EKCは「経済成長の初期段階では環境負荷が増大するが、所得水準が十分高くなると環境改善が起きる」という仮説。都道府県間の所得格差が小さい日本では逆U字の「右側(下降部分)」のみ観察される可能性がある。二次曲線で検定するには消費支出の二乗項を追加する。
137 138 139 140 141 142 143 144 145 146 147 | print("\n[Fig2] 散布図(消費支出 vs ごみ排出量)...") df22 = df[df['年度'] == 2022].dropna(subset=['消費支出_log', 'ごみ排出量_g', '地域']).copy() fig, ax = plt.subplots(figsize=(11, 8), dpi=DPI) for region, grp in df22.groupby('地域'): color = REGION_COLORS.get(region, '#999') ax.scatter(grp['消費支出_log'], grp['ごみ排出量_g'], color=color, s=80, alpha=0.85, zorder=3, label=region, edgecolors='white', linewidths=0.6) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。df.groupby('列').apply(関数) — グループごとに関数を適用。時系列や地域別の集計でよく使います。fig, ax = plt.subplots(...) — 図全体(fig)と軸(ax)を作る定番。以降は ax.bar(...) 等で操作。df['A'] / df['B'] — pandasの列同士の四則演算は要素ごと(element-wise)。forループ不要なのが強み。148 149 150 151 152 153 154 155 156 157 158 159 160 | # 都道府県ラベル(省略形) LABEL_MAP = { '北海道': '北海道', '東京都': '東京', '大阪府': '大阪', '愛知県': '愛知', '神奈川県': '神奈川', '沖縄県': '沖縄', '高知県': '高知', '秋田県': '秋田', '富山県': '富山', '山形県': '山形', '福井県': '福井', '徳島県': '徳島', } for _, row in df22.iterrows(): pref = row['都道府県'] short = LABEL_MAP.get(pref, pref.replace('県', '').replace('府', '').replace('都', '')) ax.annotate(short, xy=(row['消費支出_log'], row['ごみ排出量_g']), xytext=(3, 3), textcoords='offset points', fontsize=7.5, color='#333', alpha=0.9) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。for _, row in df.iterrows() — DataFrameを1行ずつ取り出すループ。1点ずつ描画したいときに使用。.map() は「1対1の置き換え」、.apply() は「関数を当てる」。辞書なら .map()、ロジックなら .apply()。161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 | # 回帰直線 x_vals = df22['消費支出_log'].dropna() y_vals = df22['ごみ排出量_g'].dropna() idx = df22[['消費支出_log', 'ごみ排出量_g']].dropna().index xv = df22.loc[idx, '消費支出_log'] yv = df22.loc[idx, 'ごみ排出量_g'] slope, intercept, r_val, p_val, _ = stats.linregress(xv, yv) x_line = np.linspace(xv.min(), xv.max(), 100) y_line = slope * x_line + intercept ax.plot(x_line, y_line, '--', color='#555', linewidth=1.5, alpha=0.7, label=f'回帰直線 (r={r_val:.3f}, p={p_val:.3f})') ax.set_xlabel('log(消費支出:二人以上の世帯, 円)', fontsize=12) ax.set_ylabel('1人1日当たりごみ排出量(g/人/日)', fontsize=12) ax.set_title('消費支出とごみ排出量の関係(2022年度・47都道府県)', fontsize=13, fontweight='bold', pad=12) ax.legend(loc='upper left', fontsize=9, framealpha=0.9, edgecolor='#ccc') ax.grid(linestyle='--', alpha=0.35) plt.tight_layout() out2 = os.path.join(FIG_DIR, '2022_H5_16_fig2_scatter.png') plt.savefig(out2, dpi=DPI, bbox_inches='tight') plt.close() print(f" 保存: {out2}") print(f" 相関: r={r_val:.3f}, p={p_val:.4f}") |
[Fig2] 散布図(消費支出 vs ごみ排出量)... findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Goth …(長いため省略)
stats.linregress(x, y) — 単回帰の傾き・切片・r値・p値・標準誤差を返します。使わない値は _ で受け取り。fig.savefig(..., bbox_inches='tight') — 余白を自動で詰めて保存。plt.close() でメモリ解放。[式 for x in リスト] はリスト内包表記。forループでappendする代わりに1行でリストを作れます。ごみ排出量(g/人/日)を目的変数として、高齢化率・消費支出(log)・旅館密度を説明変数とするOLS重回帰分析を2022年度データで実施した。各説明変数は標準化(z-score変換)し、係数の大きさを直接比較できるようにした。
| 変数 | 標準化係数 β | p値 | 有意性 | 解釈 |
|---|---|---|---|---|
| 高齢化率(%) | +32.7 | 0.000 | *** | 高齢化率が高い県ほどごみが多い(予想に反して正) |
| log消費支出(円) | −4.3 | 0.618 | n.s. | 消費支出との関係は統計的に有意ではない |
| 旅館密度(1万人対) | +6.0 | 0.457 | n.s. | 観光地仮説も有意な支持が得られなかった |
| モデル全体:F検定 | 0.0005 | *** | モデル全体は有意(R²=0.336) | |
リサイクル率の向上は「廃棄物処理政策」と「住民の分別行動」の両方が絡む複雑な問題。統計分析で政策効果を評価する際には、「政策変数」(例:分別区分の数、収集頻度)を追加した分析や、政策変更前後の差分(difference-in-differences)が有効。都道府県レベルではリサイクル率の決定要因として「分別品目数」「焼却炉の有無」「住民教育の充実度」が先行研究で報告されている。
186 187 188 189 190 191 | print("\n[Fig3] OLS回帰係数プロット...") # 2022年データで回帰分析 reg_df = df[df['年度'] == 2022].dropna( subset=['ごみ排出量_g', '高齢化率', '消費支出_log', '旅館密度', 'リサイクル率'] ).copy() |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。.map() は「1対1の置き換え」、.apply() は「関数を当てる」。辞書なら .map()、ロジックなら .apply()。192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 | # 説明変数の標準化(係数の比較のため) VARS = { '高齢化率(%)': '高齢化率', 'log消費支出(円)': '消費支出_log', '旅館密度(1万人対)': '旅館密度', } X_data = {} for label, col in VARS.items(): X_data[label] = (reg_df[col] - reg_df[col].mean()) / reg_df[col].std() X_mat = pd.DataFrame(X_data) y_vec = reg_df['ごみ排出量_g'] X_sm = sm.add_constant(X_mat) model = sm.OLS(y_vec, X_sm).fit() print(model.summary()) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。sm.add_constant(X) — 切片項(定数1の列)を先頭に追加。statsmodelsで必須。sm.OLS(y, X).fit() — 最小二乗法でモデルを推定。model.params, model.pvalues, model.conf_int() で結果取得。[式 for x in リスト] はリスト内包表記。forループでappendする代わりに1行でリストを作れます。210 211 212 213 214 215 216 217 218 219 220 221 222 223 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 | # 係数・信頼区間・p値 var_labels = list(VARS.keys()) coefs = model.params[1:].values conf = model.conf_int().iloc[1:].values # [lower, upper] pvals = model.pvalues[1:].values fig, ax = plt.subplots(figsize=(9, 5), dpi=DPI) colors = ['#C62828' if p < 0.05 else '#9E9E9E' for p in pvals] y_pos = range(len(var_labels)) for i, (label, coef, ci, p, col) in enumerate( zip(var_labels, coefs, conf, pvals, colors)): ax.barh(i, coef, color=col, alpha=0.8, height=0.55, zorder=3) ax.errorbar(coef, i, xerr=[[coef - ci[0]], [ci[1] - coef]], fmt='none', color='#333', capsize=5, linewidth=1.5, zorder=4) sig = '***' if p < 0.001 else ('**' if p < 0.01 else ('*' if p < 0.05 else 'n.s.')) ax.text(coef + (2 if coef >= 0 else -2), i, f'{sig} p={p:.3f}', va='center', fontsize=9, color='#333', ha='left' if coef >= 0 else 'right') ax.axvline(0, color='#555', linewidth=1.2, linestyle='--') ax.set_yticks(list(y_pos)) ax.set_yticklabels(var_labels, fontsize=11) ax.set_xlabel('標準化回帰係数(95%CI)', fontsize=11) ax.set_title(f'ごみ排出量の決定要因(OLS回帰, 2022年度, N={len(reg_df)}都道府県)\n' f'R²={model.rsquared:.3f}', fontsize=12, fontweight='bold', pad=12) ax.grid(axis='x', linestyle='--', alpha=0.35) sig_patch = mpatches.Patch(color='#C62828', alpha=0.8, label='有意(p<0.05)') ns_patch = mpatches.Patch(color='#9E9E9E', alpha=0.8, label='非有意(p≥0.05)') ax.legend(handles=[sig_patch, ns_patch], loc='lower right', fontsize=10) plt.tight_layout() out3 = os.path.join(FIG_DIR, '2022_H5_16_fig3_coef.png') plt.savefig(out3, dpi=DPI, bbox_inches='tight') plt.close() print(f" 保存: {out3}") |
[Fig3] OLS回帰係数プロット...
OLS Regression Results
==============================================================================
Dep. Variable: ごみ排出量_g R-squared: 0.336
Model: OLS Adj. R-squared: 0.289
Method: Least Squares F-statistic: 7.240
Date: Mon, 18 May 2026 Prob (F-statistic): 0.000489
Time: 11:24:07 Log-Likelihood: -250.18
No. Observations: 47 AIC: 508.4
Df Residuals: 43 BIC: 515.8
Df Model: 3
Covariance Type: nonrobust
==============================================================================
coef std err t P>|t| [0.025 0.975]
------------------------------------------------------------------------------
const 906.0851 7.564 119.792 0.000 890.831 921.339
高齢化率(%) 32.6678 8.158 4.005 0.000 16.216 49.119
log消費支出(円) -4.2952 8.554 -0.502 0.618 -21.546 12.955
旅館密度(1万人対) 6.0402 8.049 0.750 0.457 -10.192 22.273
==============================================================================
Omnibus: 0.475 Durbin-Watson: 1.917
Prob(Omnibus): 0.789 Jarque-Bera (JB): 0.113
Skew: -0.107 Prob(JB): 0.945
Kurtosis: 3.110 Cond. No. 1.62
==============================================================================
Notes:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
findfont: Font family 'Hiragino Kaku Gothic ProN' not found.
findfont: Font family 'Noto Sans CJK JP' not found.
findfont: Font family 'Hiragino Kaku Gothic ProN' not found.
findfont: Font family 'Noto Sans CJK JP' not found.
findfont: Font family 'Hiragino Kaku Gothic ProN' not found.
findfont: Font family 'Noto Sans CJK JP' not found.
findfont: Font family 'Hiragino Kaku Gothic ProN' not found.
findfont: Font family 'Noto Sans CJK JP' not found.
findfont: Font family 'Hiragino Kaku Gothic ProN' not found.
findfont: Font family 'Noto Sans CJK JP' not found.
findfont: Font family 'Hiragino Kaku Gothic ProN' not found.
findfont: Font family 'Noto Sans CJK JP' not found.
findfont: Font family 'Hiragino Kaku Gothic ProN' not found.
findfont: Font family 'Noto Sans CJK JP' not found.
findfont: Font family 'Hiragino Kaku Gothic ProN' not found.
findfont: Font family 'Noto Sans CJK JP' not found.
findfont: Font family 'Hiragino Kaku Gothic ProN' not found.
findfont: Font family 'Noto Sans CJK JP' not found.
findfont: Font family 'Hiragino Kaku Gothic ProN' not found.
findfont: Font family 'Noto Sans CJK JP' not found.
findfont: Font family 'Hiragino Kaku Gothic ProN' not found.
findfont: Font family 'Noto Sans CJK JP' not found.
findfont: Font family 'Hiragino Kaku Gothic ProN' not found.
findfont: Font family 'Noto Sans CJK JP' not found.
findfont: Font family 'Hiragino Kaku Gothic ProN' not found.
findfont: Font family 'Noto Sans CJK JP' not found.
findfont: Font family 'Hiragino Kaku Gothic ProN' not found.
findfont: Font family 'Noto Sans CJK JP' not found.
findfont: Font family 'Hiragino Kaku Gothic ProN' not found.
findfont: Font family 'Noto Sans CJK JP' not found.
findfont: Font family 'Hiragino Kaku Gothic ProN' not found.
findfont: Font family 'No
…(長いため省略)fig, ax = plt.subplots(...) — 図全体(fig)と軸(ax)を作る定番。以降は ax.bar(...) 等で操作。ax.axhline / ax.axvline — 水平/垂直の点線。平均線や基準線として定番。fig.savefig(..., bbox_inches='tight') — 余白を自動で詰めて保存。plt.close() でメモリ解放。r, p = stats.pearsonr(...) — Pythonは複数戻り値を同時に受け取れる(タプルアンパック)。2022年度のリサイクル率を都道府県別にランキング化し、地域ブロックごとに色分けして表示した。全国平均(18.2%)を基準線として、各都道府県の位置を視覚化する。
| 順位 | 都道府県 | リサイクル率 | 特徴 |
|---|---|---|---|
| 1位(最高) | 鳥取県 | 28.3% | 中国地方:小規模・農村部でリサイクル意識が高い |
| 2〜3位 | 福岡県・鹿児島県周辺 | 25%前後 | 九州地方に高率の県が集中する傾向 |
| 全国平均 | 18.2% | 47都道府県の単純平均 | |
| 最低 | 和歌山県 | 12.4% | 近畿地方:リサイクル体制の整備状況が課題 |
250 251 252 253 254 255 256 257 258 | print("\n[Fig4] リサイクル率都道府県別ランキング...") df22_sorted = df22.dropna(subset=['リサイクル率']).sort_values('リサイクル率', ascending=True).reset_index(drop=True) fig, ax = plt.subplots(figsize=(10, 13), dpi=DPI) bar_colors = [REGION_COLORS.get(r, '#999') for r in df22_sorted['地域']] bars = ax.barh(range(len(df22_sorted)), df22_sorted['リサイクル率'], color=bar_colors, alpha=0.85, height=0.7, zorder=3) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。fig, ax = plt.subplots(...) — 図全体(fig)と軸(ax)を作る定番。以降は ax.bar(...) 等で操作。sort_values('列名', ascending=False) — 指定列で並べ替え(降順)。[式 for x in リスト] はリスト内包表記。forループでappendする代わりに1行でリストを作れます。259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 | # 都道府県ラベル for i, (_, row) in enumerate(df22_sorted.iterrows()): pref = row['都道府県'].replace('県', '').replace('府', '').replace('都', '').replace('道', '') ax.text(row['リサイクル率'] + 0.3, i, f"{pref} {row['リサイクル率']:.1f}%", va='center', fontsize=8.5, color='#333') ax.set_yticks(range(len(df22_sorted))) ax.set_yticklabels( [row['都道府県'].replace('県', '').replace('府', '').replace('都', '').replace('道', '') for _, row in df22_sorted.iterrows()], fontsize=8 ) ax.set_xlabel('ごみのリサイクル率(%)', fontsize=11) ax.set_title('都道府県別ごみのリサイクル率ランキング(2022年度)', fontsize=13, fontweight='bold', pad=12) ax.axvline(df22_sorted['リサイクル率'].mean(), color='#F9A825', linewidth=2, linestyle='--', label=f"全国平均 {df22_sorted['リサイクル率'].mean():.1f}%") ax.grid(axis='x', linestyle='--', alpha=0.35) ax.set_xlim(0, df22_sorted['リサイクル率'].max() * 1.18) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。ax.axhline / ax.axvline — 水平/垂直の点線。平均線や基準線として定番。for _, row in df.iterrows() — DataFrameを1行ずつ取り出すループ。1点ずつ描画したいときに使用。r, p = stats.pearsonr(...) — Pythonは複数戻り値を同時に受け取れる(タプルアンパック)。277 278 279 280 281 282 283 284 285 286 287 288 | # 凡例(地域) handles = [mpatches.Patch(color=col, label=region, alpha=0.85) for region, col in REGION_COLORS.items()] handles.append(mpatches.Patch(color='#F9A825', label='全国平均', alpha=0.9)) ax.legend(handles=handles, loc='lower right', fontsize=8.5, framealpha=0.9, edgecolor='#ccc') plt.tight_layout() out4 = os.path.join(FIG_DIR, '2022_H5_16_fig4_ranking.png') plt.savefig(out4, dpi=DPI, bbox_inches='tight') plt.close() print(f" 保存: {out4}") |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。fig.savefig(..., bbox_inches='tight') — 余白を自動で詰めて保存。plt.close() でメモリ解放。x if cond else y は三項演算子。リスト内包表記と組み合わせると、forとifを1行で書けます。289 290 291 292 293 294 295 296 | # ── サマリー出力 ─────────────────────────────────────────────────────────────── print("\n===== 分析サマリー(2022年度) =====") print(f" ごみ排出量(平均): {df22['ごみ排出量_g'].mean():.1f} g/人/日") print(f" リサイクル率(平均): {df22['リサイクル率'].mean():.1f} %") print(f" リサイクル率 最高: {df22.loc[df22['リサイクル率'].idxmax(), '都道府県']} " f"({df22['リサイクル率'].max():.1f}%)") print(f" リサイクル率 最低: {df22.loc[df22['リサイクル率'].idxmin(), '都道府県']} " f"({df22['リサイクル率'].min():.1f}%)") |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。df[col](1列)と df[[col1, col2]](複数列)でカッコの数が違います。リストを渡していると覚えるとミスを減らせます。297 298 299 300 301 302 303 304 305 306 | # 相関分析 corr_vars = ['高齢化率', '消費支出_log', '旅館密度'] print("\n ごみ排出量との相関係数:") for v in corr_vars: sub = df22.dropna(subset=[v, 'ごみ排出量_g']) r, p = stats.pearsonr(sub[v], sub['ごみ排出量_g']) print(f" {v}: r={r:.3f}, p={p:.4f}") print("\n全図の生成が完了しました。") print(f"保存先: {os.path.abspath(FIG_DIR)}") |
[Fig4] リサイクル率都道府県別ランキング... findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic ProN' not found. findfont: Font family 'Noto Sans CJK JP' not found. findfont: Font family 'Hiragino Kaku Gothic …(長いため省略)
stats.pearsonr(x, y) — Pearson相関係数 r と p値を同時に返します。s[:-n]「末尾n文字を除く」/s[n:]「先頭n文字を除く」。スライス [start:stop:step] はリスト・タプル・文字列共通の基本ワザです。| データ | 出典 | 変数 |
|---|---|---|
| SSDSE-B-2026(都道府県別社会経済統計) | 統計数理研究所 | H5609, H5610, H5614, A1101, A1303, L3221, C3801 |
| ごみ総排出量(総量) | 環境省 一般廃棄物処理実態調査(SSDSE-B 経由) | H5609(トン/年) |
| 1人1日当たりの排出量 | 環境省(SSDSE-B 経由) | H5610(g/人/日) |
| ごみのリサイクル率 | 環境省(SSDSE-B 経由) | H5614(%) |
| 消費支出(二人以上の世帯) | 総務省 家計調査(SSDSE-B 経由) | L3221(円/月) |
本教材は実データ(SSDSE-B-2026)のみを使用。合成データ(np.random等)は一切使用していない。
分析環境:Python 3.x, pandas, numpy, matplotlib, statsmodels, scipy
統計分析の解釈で初心者がやりがちな勘違いをまとめます。特に「相関と因果の混同」「p値の過信」は研究現場でもよく起きる落とし穴です。本文を読む前にも、読んだ後にも、目を通してみてください。
統計の基本用語を初心者向けに解説します。本文中で見慣れない言葉が出てきたら、ここに戻って確認してください。
統計手法について「何のためか」「結果をどう読むか」を初心者向けに解説します。
この研究をさらに発展させるための3つの方向性を示します。「今回わかったこと(X)」から「次に検証すべき仮説(Y)」を立て、「具体的に何をするか(Z)」まで考えてみましょう。
学んだだけでは身につきません。実際に手を動かすのが最強の学習方法です。本論文のスクリプトをベースに、以下のチャレンジに挑戦してみてください。難易度別に5つ用意しました。
本論文で学んだ手法は、研究の世界だけでなく、行政・企業・NPO の現場でも様々に活用されています。具体的なシーンを紹介します。
この論文を読んで初心者が抱きやすい疑問に、教育的観点から答えます。