このページの分析を自分で再現するには、以下の手順でデータを準備してください。コードの編集は不要です。
data/raw/ フォルダに入れます。html/figures/ に自動保存されます。
2022年のロシアによるウクライナ侵攻に端を発するエネルギー価格の高騰は、日本においても電力・ガス代の急上昇として家計に直撃した。一方で、日本は2050年カーボンニュートラルを国家目標に掲げ、電力需要の構造的変化(省エネ・再エネ普及)が求められている。
まず「日本の電力需要量の影響調査」を統計的にとらえることが有効だと考えられる。 その理由は感覚や経験則だけでは、複雑な社会要因の中で「何が本当に効いているか」を見極めにくいからである。 本研究では公開データと統計手法を組み合わせ、この問いに定量的な答えを出すことを目指す。
本研究は、家計の電力消費に影響を与える要因を統計的に明らかにすることを目的とする。直接的な電力消費量データは都道府県別に整備されていないため、家計調査の光熱・水道費を電力需要の代理変数として活用する。
SSDSE-B 代理変数 OLS重回帰 相関分析 エネルギー政策
都道府県別の電力消費量は直接公表されていない(工業・業務用含む総量のみ)。本研究では、家計調査に収録される「光熱・水道費(二人以上の世帯)」を消費支出で割った「光熱費割合」を、家計レベルの電力需要を捉える代理変数とする。
| 説明変数 | 想定される効果 | 根拠 |
|---|---|---|
| 年平均気温(℃) | 負(低温→暖房増) | 寒冷地ほど暖房需要が高い |
| 総人口 | 規模要因 | 人口規模が電力需要の基礎 |
| 消費支出(円) | 正(所得水準) | 生活水準が高いほど消費電力増 |
| 高齢化率(%) | 正(在宅時間増) | 高齢者は在宅が長く暖冷房使用増 |
| 住宅地価格(円/m²) | 都市度の代理 | 都市部は省エネ住宅が普及している場合も |
代理変数は「測定困難な変数」を「測定可能な関連変数」で置き換える手法。重要なのは代替妥当性(construct validity)の確認:光熱費は電力・ガス・水道を合計するため、エネルギーミックス(電力 vs ガス)の違いを吸収できない点に注意が必要。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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() # 数値変換 num_cols = [ '光熱・水道費(二人以上の世帯)', '消費支出(二人以上の世帯)', '年平均気温', '最高気温(日最高気温の月平均の最高値)', '最低気温(日最低気温の月平均の最低値)', '総人口', '65歳以上人口', '標準価格(平均価格)(住宅地)', ] for c in num_cols: df_b[c] = pd.to_numeric(df_b[c], errors='coerce') |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。pd.read_csv(...) でCSVを読み込みます。encoding='cp932' は日本語Windows由来の文字コード、header=1 は「2行目を列名として使う」。df['地域コード'].str.match(r'^R\d{5}', ...) — 正規表現で「R+数字5桁」の行(47都道府県)だけTrueにし、真偽値で行をフィルタ。df['A'] / df['B'] — pandasの列同士の四則演算は要素ごと(element-wise)。forループ不要なのが強み。17 18 19 20 21 22 23 24 25 | # 派生変数 df_b['光熱費割合'] = df_b['光熱・水道費(二人以上の世帯)'] / df_b['消費支出(二人以上の世帯)'] * 100 df_b['高齢化率'] = df_b['65歳以上人口'] / df_b['総人口'] * 100 print("=" * 60) print("■ SSDSE-B 読み込み完了") print(f" 全レコード数: {len(df_b)}(都道府県×年度)") print(f" 年度範囲: {df_b['年度'].min()}〜{df_b['年度'].max()}") print("=" * 60) |
============================================================ ■ SSDSE-B 読み込み完了 全レコード数: 564(都道府県×年度) 年度範囲: 2012〜2023 ============================================================
.map() は「1対1の置き換え」、.apply() は「関数を当てる」。辞書なら .map()、ロジックなら .apply()。SSDSE-B の都道府県パネルデータを用いて、2012〜2023年の全国平均光熱費割合を集計した。陰影は都道府県間の±1標準偏差(ばらつき)を示す。
本分析は「年次データ(年度単位)」を用いているため、月次データで問題となる季節性(夏の冷房・冬の暖房)は自動的に平均化される。季節調整(X-13-ARIMA など)は月次・四半期データに対して適用するものであり、年次集計済みデータには不要。
27 28 29 30 31 32 33 34 35 36 | fig1, ax1 = plt.subplots(figsize=(9, 5)) years = ts['年度'].values means = ts['光熱費割合_mean'].values stds = ts['光熱費割合_std'].values ax1.fill_between(years, means - stds, means + stds, alpha=0.18, color='#1565C0', label='±1SD(都道府県間ばらつき)') ax1.plot(years, means, 'o-', color='#1565C0', linewidth=2.2, markersize=7, markerfacecolor='white', markeredgewidth=2, label='全国平均') |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。fig, ax = plt.subplots(...) — 図全体(fig)と軸(ax)を作る定番。以降は ax.bar(...) 等で操作。ax.fill_between(...) — 2つの曲線で囲まれた領域を塗りつぶし。Lorenz曲線の格差面積などを可視化。r, p = stats.pearsonr(...) — Pythonは複数戻り値を同時に受け取れる(タプルアンパック)。37 38 39 40 41 42 43 44 | # 2020年(コロナ禍)にアノテーション if 2020 in years: idx20 = list(years).index(2020) ax1.annotate('2020年\n(コロナ禍)', xy=(2020, means[idx20]), xytext=(2020 - 1.0, means[idx20] + 0.4), arrowprops=dict(arrowstyle='->', color='#C62828'), fontsize=9, color='#C62828') |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。x if cond else y は三項演算子。リスト内包表記と組み合わせると、forとifを1行で書けます。45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | # 2022年(エネルギー価格高騰) if 2022 in years: idx22 = list(years).index(2022) ax1.annotate('2022年\n(エネルギー高騰)', xy=(2022, means[idx22]), xytext=(2021.0, means[idx22] + 0.5), arrowprops=dict(arrowstyle='->', color='#E65100'), fontsize=9, color='#E65100') ax1.set_xlabel('年度', fontsize=12) ax1.set_ylabel('光熱費割合(光熱・水道費 / 消費支出 × 100, %)', fontsize=11) ax1.set_title('光熱・水道費割合の時系列推移(全国平均)\n2012〜2023年 都道府県データ(SSDSE-B)', fontsize=12, fontweight='bold') ax1.legend(fontsize=10) ax1.grid(True, alpha=0.3) ax1.set_xticks(years) plt.tight_layout() fig1.savefig(os.path.join(FIG_DIR, '2022_U5_5_fig1_ts.png'), bbox_inches='tight', dpi=150) plt.close(fig1) print("\n図1保存: 2022_U5_5_fig1_ts.png") |
図1保存: 2022_U5_5_fig1_ts.png
df[col](1列)と df[[col1, col2]](複数列)でカッコの数が違います。リストを渡していると覚えるとミスを減らせます。2022年度の47都道府県のデータを用い、光熱費割合と各説明変数間のピアソン相関係数を算出した。ヒートマップは変数間の相関構造を一覧する。
| 変数 | 相関方向の予測 | 解釈 |
|---|---|---|
| 年平均気温(℃) | 負(強) | 寒冷な都道府県ほど光熱費割合が高い(暖房需要) |
| 高齢化率(%) | 正 | 高齢者が多い地域ほど光熱費割合が高い(在宅時間増) |
| 消費支出(円) | 弱または混合 | 光熱費割合の分母でもあるため解釈注意 |
| 住宅地価格(円/m²) | 負 | 都市部(地価高)は省エネ住宅・集合住宅が多い傾向 |
| 総人口 | 弱 | 人口規模より地域特性が支配的 |
66 67 68 69 70 71 72 73 74 75 76 77 78 | corr_plot_cols = [YVAR] + VARNAMES_EN corr_labels = ['光熱費割合'] + VARNAMES_JP C = df_ols[corr_plot_cols].corr().values fig2, ax2 = plt.subplots(figsize=(8, 7)) n = len(corr_labels) im = ax2.imshow(C, cmap='RdBu_r', vmin=-1, vmax=1, aspect='auto') plt.colorbar(im, ax=ax2, shrink=0.8, label='ピアソン相関係数') ax2.set_xticks(range(n)) ax2.set_xticklabels(corr_labels, rotation=30, ha='right', fontsize=10) ax2.set_yticks(range(n)) ax2.set_yticklabels(corr_labels, fontsize=10) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。fig, ax = plt.subplots(...) — 図全体(fig)と軸(ax)を作る定番。以降は ax.bar(...) 等で操作。x if cond else y は三項演算子。リスト内包表記と組み合わせると、forとifを1行で書けます。79 80 81 82 83 84 85 86 87 88 89 90 91 92 | # セル内に相関係数を表示 for i in range(n): for j in range(n): val = C[i, j] color = 'white' if abs(val) > 0.6 else 'black' ax2.text(j, i, f'{val:.2f}', ha='center', va='center', fontsize=9, color=color, fontweight='bold') ax2.set_title('相関ヒートマップ:光熱費割合と各説明変数\n(2022年度, N=47都道府県)', fontsize=12, fontweight='bold') plt.tight_layout() fig2.savefig(os.path.join(FIG_DIR, '2022_U5_5_fig2_corr.png'), bbox_inches='tight', dpi=150) plt.close(fig2) print("図2保存: 2022_U5_5_fig2_corr.png") |
図2保存: 2022_U5_5_fig2_corr.png
df[col](1列)と df[[col1, col2]](複数列)でカッコの数が違います。リストを渡していると覚えるとミスを減らせます。5変数を全て投入したOLS重回帰(N=47都道府県、2022年度)を実施。説明変数を標準化(平均0・標準偏差1)したうえで推定することで、単位の異なる変数の相対的な重要度を比較する。
| 変数 | VIF目安 | 判定基準 |
|---|---|---|
| 年平均気温(℃) | 計算値を参照 | VIF < 5:問題なし |
| 総人口 | 計算値を参照 | 5 ≤ VIF < 10:要注意 |
| 消費支出(円) | 計算値を参照 | VIF ≥ 10:深刻な多重共線性 |
| 高齢化率(%) | 計算値を参照 | VIF < 5:問題なし |
| 住宅地価格(円/m²) | 計算値を参照 | VIF < 5:問題なし |
標準化係数(ベータ係数)は「他の変数を固定したとき、X が1SD変化すると Y が何SD変化するか」を示す。単位が統一されるため変数間の重要度比較が可能。ただし多重共線性(変数間の強い相関)があると係数が不安定になるため、VIF < 5 の確認が前提となる。
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 | betas = np.asarray(model_std.params[1:]) ses = np.asarray(model_std.bse[1:]) pvals = np.asarray(model_std.pvalues[1:]) fig3, ax3 = plt.subplots(figsize=(9, 5)) y_pos = np.arange(len(VARNAMES_JP)) colors3 = ['#C62828' if p < 0.01 else '#FF8F00' if p < 0.05 else '#9E9E9E' for p in pvals] ax3.barh(y_pos, betas, color=colors3, alpha=0.78, edgecolor='white', height=0.55) ax3.errorbar(betas, y_pos, xerr=1.96 * ses, fmt='none', color='#333', capsize=4, linewidth=1.3) ax3.axvline(0, color='gray', linestyle='--', linewidth=1.0) ax3.set_yticks(y_pos) ax3.set_yticklabels(VARNAMES_JP, fontsize=11) ax3.set_xlabel('標準化偏回帰係数(±1.96SE)', fontsize=11) ax3.set_title( f'OLS重回帰:標準化偏回帰係数\n' f'R²={model_std.rsquared:.3f}, Adj.R²={model_std.rsquared_adj:.3f}, N={N}都道府県', fontsize=12, fontweight='bold') ax3.invert_yaxis() ax3.grid(axis='x', alpha=0.3) from matplotlib.patches import Patch ax3.legend(handles=[ Patch(color='#C62828', alpha=0.78, label='p < 0.01'), Patch(color='#FF8F00', alpha=0.78, label='p < 0.05'), Patch(color='#9E9E9E', alpha=0.78, label='n.s.') ], fontsize=9, loc='lower right') |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。import pandas as pd など — 必要なライブラリをまとめて呼び出します。as pd は短い別名(alias)。fig, ax = plt.subplots(...) — 図全体(fig)と軸(ax)を作る定番。以降は ax.bar(...) 等で操作。ax.axhline / ax.axvline — 水平/垂直の点線。平均線や基準線として定番。df[col](1列)と df[[col1, col2]](複数列)でカッコの数が違います。リストを渡していると覚えるとミスを減らせます。122 123 124 125 126 127 128 129 130 131 132 | # 係数値をバーに付記 for i, (b, p) in enumerate(zip(betas, pvals)): sig = '***' if p < 0.001 else '**' if p < 0.01 else '*' if p < 0.05 else '' ha = 'left' if b >= 0 else 'right' ax3.text(b + (0.01 if b >= 0 else -0.01), i, f' {b:.3f}{sig}', va='center', ha=ha, fontsize=8.5) plt.tight_layout() fig3.savefig(os.path.join(FIG_DIR, '2022_U5_5_fig3_coef.png'), bbox_inches='tight', dpi=150) plt.close(fig3) print("図3保存: 2022_U5_5_fig3_coef.png") |
図3保存: 2022_U5_5_fig3_coef.png
s[:-n]「末尾n文字を除く」/s[n:]「先頭n文字を除く」。スライス [start:stop:step] はリスト・タプル・文字列共通の基本ワザです。気温と光熱費割合の関係を都道府県別の散布図で可視化する。北海道・東北など寒冷地と沖縄など温暖地の対比が明確に現れ、気温が電力需要の主要な規定因であることを示す。
気温と光熱費の関係は「低温→暖房増(正の効果)、高温→冷房増(暑い地域でも上昇)」というU字型(二次関数)になると考えられる。線形OLSは中間温度帯での関係を捉えるが、極端な気温域では非線形項(気温²)の導入が有効。気候変動(平均気温上昇)はU字の右側を押し上げ、将来の電力需要増を示唆する。
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | 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 from statsmodels.stats.outliers_influence import variance_inflation_factor 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} のように書式も指定できます。153 154 155 156 157 158 159 160 161 162 163 164 | df_2022 = df_b[df_b['年度'] == 2022].copy() # 説明変数リスト XVARS = { '年平均気温(℃)' : '年平均気温', '総人口(万人)' : '総人口', '消費支出(円)' : '消費支出(二人以上の世帯)', '高齢化率(%)' : '高齢化率', '住宅地価格(円/m²)' : '標準価格(平均価格)(住宅地)', } # 目的変数 YVAR = '光熱費割合' |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。.map() は「1対1の置き換え」、.apply() は「関数を当てる」。辞書なら .map()、ロジックなら .apply()。165 166 167 168 169 170 171 172 173 174 175 176 | # 分析用データフレーム作成 cols_use = [YVAR, '年平均気温', '総人口', '消費支出(二人以上の世帯)', '高齢化率', '標準価格(平均価格)(住宅地)', '都道府県'] df_ols = df_2022[cols_use].dropna().copy().reset_index(drop=True) N = len(df_ols) # 変数名マッピング(表示用) VARNAMES_JP = list(XVARS.keys()) VARNAMES_EN = list(XVARS.values()) print(f"\n■ 2022年度 有効データ: N={N}都道府県") print(df_ols[[YVAR] + VARNAMES_EN].describe().round(2)) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。.describe() — 件数・平均・標準偏差・四分位・最大/最小を一括計算。データの素性チェックに必須。[式 for x in リスト] はリスト内包表記。forループでappendする代わりに1行でリストを作れます。177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 | # ── OLS 標準化係数 ───────────────────────────────────────────── X_raw = df_ols[VARNAMES_EN].values.astype(float) y_raw = df_ols[YVAR].values.astype(float) # 標準化 X_std = (X_raw - X_raw.mean(axis=0)) / X_raw.std(axis=0, ddof=1) y_std = (y_raw - y_raw.mean()) / y_raw.std(ddof=1) model_std = sm.OLS(y_std, sm.add_constant(X_std)).fit() model_raw = sm.OLS(y_raw, sm.add_constant(X_raw)).fit() print("\n" + "=" * 60) print("■ OLS 重回帰(標準化)") print("=" * 60) print(f" N={N}, R²={model_std.rsquared:.4f}, Adj.R²={model_std.rsquared_adj:.4f}") print(f"\n {'変数':<22} {'標準化β':>8} {'p値':>10} {'有意':>6}") print(" " + "-" * 50) for name, b, p in zip(VARNAMES_JP, model_std.params[1:], model_std.pvalues[1:]): sig = '***' if p < 0.001 else '**' if p < 0.01 else '*' if p < 0.05 else 'n.s.' print(f" {name:<22} {b:>8.4f} {p:>10.4f} {sig:>6}") |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。sm.add_constant(X) — 切片項(定数1の列)を先頭に追加。statsmodelsで必須。sm.OLS(y, X).fit() — 最小二乗法でモデルを推定。model.params, model.pvalues, model.conf_int() で結果取得。r, p = stats.pearsonr(...) — Pythonは複数戻り値を同時に受け取れる(タプルアンパック)。199 200 201 202 203 204 205 206 207 208 209 | # ── VIF 計算 ──────────────────────────────────────────────── print("\n" + "=" * 60) print("■ VIF(多重共線性診断)") print("=" * 60) X_vif = sm.add_constant(X_raw) vifs = [variance_inflation_factor(X_vif, i + 1) for i in range(X_raw.shape[1])] print(f"\n {'変数':<22} {'VIF':>8}") print(" " + "-" * 32) for name, v in zip(VARNAMES_JP, vifs): flag = ' ← 注意(>5)' if v > 5 else '' print(f" {name:<22} {v:>8.2f}{flag}") |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。sm.add_constant(X) — 切片項(定数1の列)を先頭に追加。statsmodelsで必須。x if cond else y は三項演算子。リスト内包表記と組み合わせると、forとifを1行で書けます。210 211 212 213 214 215 216 | # ── 相関行列 ──────────────────────────────────────────────── print("\n" + "=" * 60) print("■ 相関行列(ピアソン)") print("=" * 60) corr_cols = [YVAR] + VARNAMES_EN corr_matrix = df_ols[corr_cols].corr() print(corr_matrix.round(3)) |
■ 2022年度 有効データ: N=47都道府県
光熱費割合 年平均気温 総人口 消費支出(二人以上の世帯) 高齢化率 標準価格(平均価格)(住宅地)
count 47.00 47.00 47.00 47.00 47.00 47.00
mean 8.71 16.07 2658425.53 289630.36 31.35 53372.34
std 1.31 2.29 2793536.00 19186.91 3.27 61991.62
min 6.00 10.20 544000.00 245054.00 22.81 13200.00
25% 7.93 15.25 1046500.00 276834.50 29.85 25300.00
50% 8.45 16.40 1563000.00 287781.00 31.42 30800.00
75% 9.20 17.35 2655000.00 302255.00 33.72 55500.00
max 12.96 23.70 14038000.00 324793.00 38.60 389100.00
============================================================
■ OLS 重回帰(標準化)
============================================================
N=47, R²=0.7286, Adj.R²=0.6955
変数 標準化β p値 有意
--------------------------------------------------
年平均気温(℃) -0.7747 0.0000 ***
総人口(万人) -0.3882 0.0618 n.s.
消費支出(円) -0.4313 0.0000 ***
高齢化率(%) -0.1242 0.3560 n.s.
住宅地価格(円/m²) 0.1458 0.4536 n.s.
============================================================
■ VIF(多重共線性診断)
============================================================
変数 VIF
--------------------------------
年平均気温(℃) 1.44
総人口(万人) 6.17 ← 注意(>5)
消費支出(円) 1.26
高齢化率(%) 2.67
住宅地価格(円/m²) 5.61 ← 注意(>5)
============================================================
■ 相関行列(ピアソン)
============================================================
光熱費割合 年平均気温 総人口 消費支出(二人以上の世帯) 高齢化率 標準価格(平均価格)(住宅地)
光熱費割合 1.000 -0.682 -0.379 -0.405 0.494 -0.414
年平均気温 -0.682 1.000 0.061 -0.097 -0.378 0.189
総人口 -0.379 0.061 1.000 0.374 -0.699 0.895
消費支出(二人以上の世帯) -0.405 -0.097 0.374 1.000 -0.361 0.351
高齢化率 0.494 -0.378 -0.699 -0.361 1.000 -0.694
標準価格(平均価格)(住宅地) -0.414 0.189 0.895 0.351 -0.694 1.000df[col](1列)と df[[col1, col2]](複数列)でカッコの数が違います。リストを渡していると覚えるとミスを減らせます。217 218 219 220 221 222 223 | ts = df_b.groupby('年度').agg( 光熱費割合_mean=('光熱費割合', 'mean'), 光熱費割合_std =('光熱費割合', 'std'), ).reset_index() print("\n■ 光熱費割合 全国平均(年度別)") print(ts.round(3)) |
■ 光熱費割合 全国平均(年度別)
年度 光熱費割合_mean 光熱費割合_std
0 2012 8.029 0.966
1 2013 8.119 1.022
2 2014 8.275 1.145
3 2015 8.138 1.060
4 2016 7.542 0.964
5 2017 7.724 1.042
6 2018 7.902 1.010
7 2019 7.733 1.087
8 2020 7.938 1.049
9 2021 7.893 1.144
10 2022 8.707 1.314
11 2023 8.193 1.101df.groupby('列').apply(関数) — グループごとに関数を適用。時系列や地域別の集計でよく使います。[式 for x in リスト] はリスト内包表記。forループでappendする代わりに1行でリストを作れます。224 225 226 227 228 229 230 231 232 233 | x4 = df_ols['年平均気温'].values.astype(float) y4 = df_ols[YVAR].values.astype(float) pref = df_ols['都道府県'].values fig4, ax4 = plt.subplots(figsize=(9, 6)) # 散布図 scatter = ax4.scatter(x4, y4, c=y4, cmap='RdYlBu_r', s=80, edgecolors='gray', linewidths=0.5, alpha=0.85, zorder=3) plt.colorbar(scatter, ax=ax4, label='光熱費割合(%)', shrink=0.8) |
print はしません。データや図が裏で更新されただけ。次のステップへ進みましょう。fig, ax = plt.subplots(...) — 図全体(fig)と軸(ax)を作る定番。以降は ax.bar(...) 等で操作。s[:-n]「末尾n文字を除く」/s[n:]「先頭n文字を除く」。スライス [start:stop:step] はリスト・タプル・文字列共通の基本ワザです。234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 | # 回帰直線 z4 = np.polyfit(x4, y4, 1) xs4 = np.linspace(x4.min() - 0.5, x4.max() + 0.5, 100) ax4.plot(xs4, np.poly1d(z4)(xs4), 'r--', linewidth=1.8, alpha=0.8, label='線形回帰') r4, p4 = stats.pearsonr(x4, y4) # 主要都道府県にラベル label_prefs = ['北海道', '沖縄県', '東京都', '大阪府', '秋田県', '鹿児島県', '長野県'] for i, pname in enumerate(pref): if any(lp in pname for lp in label_prefs): ax4.annotate(pname, (x4[i], y4[i]), textcoords='offset points', xytext=(6, 3), fontsize=8.5, color='#333') ax4.set_xlabel('年平均気温(℃)', fontsize=12) ax4.set_ylabel('光熱費割合(光熱・水道費 / 消費支出 × 100, %)', fontsize=11) ax4.set_title( f'年平均気温と光熱費割合の関係(2022年度, N={N}都道府県)\n' f'r = {r4:.3f}(p = {p4:.4f})', fontsize=12, fontweight='bold') ax4.legend(fontsize=10) ax4.grid(True, alpha=0.3) plt.tight_layout() fig4.savefig(os.path.join(FIG_DIR, '2022_U5_5_fig4_scatter.png'), bbox_inches='tight', dpi=150) plt.close(fig4) print("図4保存: 2022_U5_5_fig4_scatter.png") print("\n" + "=" * 60) print("全図の生成完了(4枚)") print(" fig1_ts.png : 光熱費割合の時系列(全国平均 2012-2023)") print(" fig2_corr.png : 相関ヒートマップ(光熱費と説明変数)") print(" fig3_coef.png : OLS標準化係数プロット") print(" fig4_scatter.png : 年平均気温 vs 光熱費割合 散布図") print("=" * 60) |
図4保存: 2022_U5_5_fig4_scatter.png ============================================================ 全図の生成完了(4枚) fig1_ts.png : 光熱費割合の時系列(全国平均 2012-2023) fig2_corr.png : 相関ヒートマップ(光熱費と説明変数) fig3_coef.png : OLS標準化係数プロット fig4_scatter.png : 年平均気温 vs 光熱費割合 散布図 ============================================================
stats.pearsonr(x, y) — Pearson相関係数 r と p値を同時に返します。np.cumsum(arr) は累積和、np.linspace(a, b, n) は「aからbを等間隔でn個」。NumPyの定石です。SSDSE-B の都道府県パネルデータ(2012〜2023年)を用い、光熱・水道費割合を電力需要の代理変数として分析した結果:
| データ | 出典 |
|---|---|
| SSDSE-B-2026.csv(都道府県パネルデータ 2012〜2023年) | 統計数理研究所 SSDSE(社会・人口統計体系) |
| 光熱・水道費(二人以上の世帯)、消費支出 | 家計調査(総務省統計局) |
| 年平均気温 | 気象庁 気候統計情報 |
| 住宅地価格(標準価格・平均) | 国土交通省 地価公示 |
実公的データ(SSDSE-B)のみ使用。合成データ・乱数データは使用していない。
統計分析の解釈で初心者がやりがちな勘違いをまとめます。特に「相関と因果の混同」「p値の過信」は研究現場でもよく起きる落とし穴です。本文を読む前にも、読んだ後にも、目を通してみてください。
統計の基本用語を初心者向けに解説します。本文中で見慣れない言葉が出てきたら、ここに戻って確認してください。
統計手法について「何のためか」「結果をどう読むか」を初心者向けに解説します。
この研究をさらに発展させるための3つの方向性を示します。「今回わかったこと(X)」から「次に検証すべき仮説(Y)」を立て、「具体的に何をするか(Z)」まで考えてみましょう。
学んだだけでは身につきません。実際に手を動かすのが最強の学習方法です。本論文のスクリプトをベースに、以下のチャレンジに挑戦してみてください。難易度別に5つ用意しました。
本論文で学んだ手法は、研究の世界だけでなく、行政・企業・NPO の現場でも様々に活用されています。具体的なシーンを紹介します。
この論文を読んで初心者が抱きやすい疑問に、教育的観点から答えます。