論文一覧に戻る 📚 用語集トップ 🗺 概念マップ
📚 用語解説
📚 用語解説
回帰分析
Regression Analysis
回帰モデル
応答変数を説明変数で予測・関係性をモデル化する分析手法の総称
🔖 索引 💡 30秒 📍 文脈 🎨 直感 📐 数式 🔬 読み解き 🧮 実値 🐍 Python ⚠️ 落とし穴 🌐 関連手法 🔗 関連用語 📚 グループ

🔖 キーワード索引

このページの主要な見どころ。 気になる項目から読み始めてください。

30秒結論回帰の本質一般式 y=f(X)+ε係数 β の意味SSDSE-B 死亡率回帰Python 実装落とし穴GLM・派生応用事例FAQ歴史・由来関連用語

💡 30秒で分かる結論

回帰分析は「応答変数 y を説明変数 X で表現する関数 f を、データから推定する」分析手法の総称。

📍 あなたが今見ているもの

論文・実務レポート・公的統計の解説で、 こんな場面に出会ったはずです。

本研究では、 都道府県の死亡率を 応答変数、 高齢化率・出生率・人口移動を 説明変数 とした重回帰分析を行った。 推定された偏回帰係数はβ₁ = 0.86 (p<0.001), β₂ = −0.27 (p<0.05) ……

この「応答変数 = β₀ + β₁ × 説明変数₁ + … + ε」という形式と、 係数の符号・大きさ・有意性を読む文化が、 回帰分析の中核です。 ページでは「式」「推定」「解釈」「落とし穴」を順に整理します。

🎨 直感で掴む

回帰分析の発想は 「散布図に線を引くと何が見えるか」 から始まります。 SSDSE-B 2023 の 47 都道府県データで、横軸=高齢化率縦軸=人口千人あたり死亡率 を取ると、 点はほぼ右上がりの直線に並びます。 この「直線」を式で書いたものが回帰モデルです。

関数の形を 線形に限定すれば単回帰重回帰、 リンク関数を介して非線形にすればロジスティック回帰などになります。 共通するのは「残差の二乗和 (またはマイナス対数尤度) を最小化して、最良の係数を見つける」最適化問題だという点です。

つまり回帰分析は 「データに最もよくフィットする関数を、ある族 (family) の中から選ぶ」 手続きであり、 関数族と誤差分布の選び方で多様な手法へ枝分かれします。

3 つの典型ユースケース

用途目的SSDSE-B での例
予測 (prediction)新しい X から y を当てる高齢化率 40% の仮想県の死亡率を予測
説明 (inference)X の効果を解釈「高齢化率 1pp で死亡率は約 0.86 上昇」
因果 (causal)X→y の因果効果※ 観察データだけでは原則できない(IV・実験設計が必要)
📘 補足:当てはまる」ことと「原因である」ことは別物です。 当てはまっていても X→y の因果は別途検証が必要。 SSDSE-B のような観察データでは特に注意。

線形回帰の「直線」が決まる仕組み

OLS では、 候補となる直線群のうち 残差の二乗和を最小化する ものを選びます。 残差とは「データ点と直線の縦方向の差」。 これを各点で計算し、 二乗して足し合わせ、 その合計を最小化する係数 $\hat{\beta}_0, \hat{\beta}_1$ を求めるのが OLS のすべてです。

「なぜ二乗?」 → 残差の符号を消すため、 かつ大きい残差をより重く罰するため。 「なぜ和?」 → 全データに均等に責任を持たせるため。 数理的にも閉形式解が得られて扱いやすい、 という工学的な利点もあります。

📐 数式または定義

最も基本の 線形回帰モデル

$$y_i \;=\; \beta_0 \;+\; \beta_1 x_{i1} \;+\; \beta_2 x_{i2} \;+\; \cdots \;+\; \beta_p x_{ip} \;+\; \varepsilon_i, \quad i=1,\dots,n$$

行列形式:

$$\mathbf{y} \;=\; \mathbf{X}\boldsymbol{\beta} \;+\; \boldsymbol{\varepsilon}, \qquad \boldsymbol{\varepsilon} \sim \mathcal{N}(\mathbf{0}, \sigma^2 \mathbf{I})$$

最小二乗推定量 (OLS):

$$\hat{\boldsymbol{\beta}} \;=\; (\mathbf{X}^{\top}\mathbf{X})^{-1} \mathbf{X}^{\top}\mathbf{y}$$

一般化線形モデル (GLM) はリンク関数 $g$ を介して

$$g(\mathrm{E}[y_i \mid \mathbf{x}_i]) \;=\; \mathbf{x}_i^{\top}\boldsymbol{\beta}$$

と書ける拡張で、$g$=恒等→線形回帰、$g$=logit→ロジスティック回帰、$g$=log→ポアソン回帰となります。 当てはまりの指標は決定係数 $R^2$ と調整済み $R^2_{\text{adj}}$:

$$R^2 = 1 - \frac{\sum_i (y_i - \hat{y}_i)^2}{\sum_i (y_i - \bar{y})^2}, \quad R^2_{\text{adj}} = 1 - (1 - R^2)\frac{n-1}{n-p-1}$$

係数の標準誤差は

$$\mathrm{Var}(\hat{\boldsymbol{\beta}}) = \sigma^2 (\mathbf{X}^{\top}\mathbf{X})^{-1}, \qquad \hat{\sigma}^2 = \frac{\sum_i \hat{\varepsilon}_i^2}{n - p - 1}$$

個別係数の t 統計量:$t_j = \hat{\beta}_j / \mathrm{SE}(\hat{\beta}_j)$、 これが自由度 $n - p - 1$ の t 分布に従うことを利用して、 仮説 $H_0: \beta_j = 0$ を検定します。

🔬 数式を言葉で読み解く

記号意味SSDSE-B での例
$y_i$応答変数の i 番目の観測値i=秋田県 の死亡率 19.17
$x_{ij}$説明変数 j の i 番目の観測値i=秋田県, j=高齢化率 で 39.06
$\beta_0$切片。説明変数がすべて 0 のときの y の予測値解釈に意味があるかは要注意(外挿)
$\beta_j$偏回帰係数高齢化率が 1pp 上がると死亡率は 0.86 上昇
$\varepsilon_i$誤差項沖縄県のように特殊な県の残差は大きい
$\hat{y}_i$予測値i=秋田 の予測死亡率は 19.99
$r_i = y_i - \hat{y}_i$残差沖縄は予測より低めに出る
$R^2$決定係数高齢化率→死亡率では 0.944
$\mathrm{SE}(\hat{\beta}_j)$係数の標準誤差不確実性の大きさ
$t_j$係数の t 統計量OLS 出力の t-value 列

係数の大小」と「有意性 (p 値)」と「当てはまりの良さ ($R^2$)」は別物。 すべてセットで報告するのが原則です。

偏回帰係数の正確な解釈

$\beta_j$ は、 他の説明変数を固定したまま $x_j$ を 1 単位増やしたときの、 y の予測値の変化量」が教科書的な定義。 「他の説明変数を固定」というのが重要で、 重回帰では別の変数を取り除いた残差の上で計算される値(Frisch–Waugh–Lovell の定理)と一致します。

たとえば SSDSE-B で 「高齢化率と消費支出」 が同時に説明変数のとき、 高齢化率の偏回帰係数は「消費支出が同じ県同士で比べたとき、 高齢化率が 1pp 違うと死亡率がいくつ違うか」を表します。 純粋な「高齢化率 vs 死亡率」の散布図の傾きとは数値が一致しません。

🧮 実値で計算してみる(SSDSE-B 2023, n=47)

SSDSE-B 2023 の 47 都道府県で、応答変数 y = 死亡率(人口千人あたり)説明変数 x = 高齢化率(%)の単回帰を実行すると:

項目解釈
$\hat{\beta}_0$ (切片)−13.49高齢化率 0% の架空県の死亡率(外挿で意味薄)
$\hat{\beta}_1$ (傾き)+0.857高齢化率が 1pp 上がると死亡率は 0.86 上昇
標準誤差 SE(β₁)0.0312係数のばらつきの推定
t 統計量 (β₁)27.45圧倒的に大きい
p 値 (β₁)< 0.001「偶然 0」とは到底考えられない
$R^2$0.944死亡率の分散の 94.4% を説明
調整済み $R^2$0.943説明変数 1 個ではほぼ同じ
相関 r+0.972非常に強い正の相関

高齢化率 39.06% の秋田県」の死亡率予測値は $\hat{y} = -13.49 + 0.857 \times 39.06 \approx 19.99$ で、 実測 19.17 とほぼ一致。 残差は約 −0.82 と小さくなります。

重回帰モデルでの拡張

モデル説明変数$R^2$調整済み $R^2$
単回帰高齢化率のみ0.9440.943
重回帰 A高齢化率 + 出生率0.9510.949
重回帰 B高齢化率 + 出生率 + 合計特殊出生率0.9520.948
重回帰 C(4 変数)高齢化率 + 出生率 + 合計特殊出生率 + 転入超過率0.9540.948

説明変数を増やしても $R^2$ はわずかしか伸びず、 調整済み $R^2$ はモデル B 以降でかえって伸び悩み・低下。 「説明変数を盛れば必ず良くなる」わけではないことが、 実データできちんと再現できます。

残差が大きい県(モデル A)

順位都道府県実測死亡率予測死亡率残差
1沖縄県9.4511.81−2.36
2愛知県10.7412.99−2.25
3滋賀県10.9413.39−2.45

沖縄県の死亡率が「予測より低い」のは、 平均寿命の高さなど高齢化率では説明できない要因の存在を示唆しています。 これらの残差の県別パターンを見ることが、 次の研究テーマを発見する第一歩になります。

🐍 Python 実装

SSDSE-B 2023 データを使って単回帰と重回帰を実行:

▼ コード解説(SSDSE-B-2026 の読み込み)
🎯 解説: SSDSE-B-2026.csv を Shift_JIS で読み込み、 最新年度 2023 のデータに絞る。 47 都道府県 × 112 列の総合パネルデータで、 回帰分析の基礎データとして全国の家計・人口・教育・医療指標を含む。
📥 入力例: data/raw/SSDSE-B-2026.csv encoding=shift_jis, skiprows=1 全期間 5 年 × 47 県 = 235 行 2023 年度に絞り込み: 47 行
📤 実行例: df.shape → (47, 112) df['都道府県'].nunique() → 47 最初の 3 行 × 5 列: 北海道・青森・岩手の総人口・出生数・死亡数等
💬 読み方: 単年(n=47)の横断面回帰として扱える基本データセット。 標本サイズ 47 は社会科学回帰として典型的で、 説明変数 3〜5 個程度の回帰モデルに適している。
import pandas as pd

# SSDSE-B-2026 を読み込み(年度別 47 都道府県、 最新は 2023 年度)
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='shift_jis', skiprows=1)
df.columns = [c.strip() for c in df.columns]
df = df[df['年度'] == 2023].reset_index(drop=True)

print(df.shape)             # (47, 112)
print(df['都道府県'].nunique())  # 47
print(df.iloc[:3, :5])

応答変数と説明変数を作る:

▼ コード解説(応答変数と説明変数の構築(指標計算))
🎯 解説: 回帰の前段階として、 死亡数や出生数を人口千人あたりの率に正規化する。 高齢化率・若年人口比率・転入超過率なども含めた都道府県比較可能な変数を作成。 比率変換は単位の異なる県を公平に比較する必須前処理。
📥 入力例: 元の列: 死亡数, 出生数, 65歳以上人口, 15歳未満人口, 総人口 単位は人数(東京 1400 万人、 鳥取 54 万人)
📤 実行例: 高齢化率 平均 30.1%(秋田 39.1% 〜 沖縄 23.1%) 死亡率 平均 12.5 ‰、 出生率 平均 5.8 ‰ 転入超過率 平均 -0.5 ‰(東京 +5.2、 秋田 -8.1)
💬 読み方: 高齢化率と死亡率は相関 r≈0.97 と極めて高い(後述の単回帰で R²=0.94)。 一方、 出生率は地域差が小さく説明変数として弱い。
# 主要指標を計算
df['死亡率']   = df['死亡数'] / df['総人口'] * 1000          # 人口千人あたり
df['出生率']   = df['出生数'] / df['総人口'] * 1000
df['高齢化率'] = df['65歳以上人口'] / df['総人口'] * 100
df['若年人口比率'] = df['15歳未満人口'] / df['総人口'] * 100
df['転入超過率'] = (df['転入者数(日本人移動者)'] - df['転出者数(日本人移動者)']) / df['総人口'] * 1000

print(df[['都道府県','高齢化率','出生率','死亡率','転入超過率']].head())
print(df[['高齢化率','出生率','死亡率']].describe().round(2))

単回帰(statsmodels で詳細な統計量を取得):

▼ コード解説(単回帰 OLS(statsmodels で詳細出力))
🎯 解説: statsmodels の OLS で「死亡率 = α + β × 高齢化率」を推定。 summary() は係数・標準誤差・t 値・p 値・R²・AIC/BIC をすべて出力する詳細レポート。 sklearn より統計学的に詳しい結果が得られる。
📥 入力例: 説明変数 X: 高齢化率(47 都道府県) 応答変数 y: 死亡率(人口千人あたり) sm.add_constant で切片項を追加
📤 実行例: Intercept = -13.49, 高齢化率の係数 = 0.857 R² = 0.944, t = 27.4, p < 0.001 AIC ≈ 178, BIC ≈ 182 → 高齢化率が 1% 上がると死亡率が約 0.86 ‰ 上昇
💬 読み方: R²=0.944 は「死亡率の分散の 94% が高齢化率で説明できる」ことを示す極めて強い関係。 高齢化が死亡率を決定する主要因子であることが定量的に裏付けられる。
import statsmodels.api as sm

X = sm.add_constant(df['高齢化率'])
model = sm.OLS(df['死亡率'], X).fit()
print(model.summary())
# Intercept = -13.49, 高齢化率の係数 = 0.857
# R-squared = 0.944, t-value ≈ 27.4, p < 0.001

重回帰と多重共線性チェック:

▼ コード解説(重回帰 + VIF 多重共線性チェック)
🎯 解説: 高齢化率・出生率・合計特殊出生率の 3 変数で重回帰を実行。 variance_inflation_factor (VIF) で多重共線性を検査。 VIF > 10 は「他変数で説明できすぎ=独自情報が少ない」のサインで、 係数推定が不安定化する。
📥 入力例: X = ['高齢化率', '出生率', '合計特殊出生率'] + 定数 y = 死亡率 n = 47, p = 3
📤 実行例: 高齢化率 VIF ≈ 2.5(安全) 出生率 VIF ≈ 6.2(要注意) 合計特殊出生率 VIF ≈ 5.8(要注意) Adjusted R² ≈ 0.95(単回帰より微増)
💬 読み方: 出生率と合計特殊出生率は概念が近く相関が高い(VIF 6 前後)。 どちらか 1 つを除外するか、 主成分分析で集約する方が推定が安定する。
from statsmodels.stats.outliers_influence import variance_inflation_factor

X = df[['高齢化率', '出生率', '合計特殊出生率']]
X = sm.add_constant(X)
model = sm.OLS(df['死亡率'], X).fit()
print(model.summary())

# VIF(10 を超えると多重共線性の疑い)
for i, name in enumerate(X.columns):
    print(name, round(variance_inflation_factor(X.values, i), 2))

scikit-learn で予測・残差プロット:

▼ コード解説(scikit-learn での回帰と残差プロット)
🎯 解説: sklearn の LinearRegression で同じモデルを fit し、 予測値・残差を計算。 残差プロット(横軸: 予測値、 縦軸: 残差)で「ランダム散布か体系的パターンか」を視覚診断する。 パターンがあると線形性が崩れている。
📥 入力例: X = df[['高齢化率']].values(shape (47,1)) y = df['死亡率'].values(shape (47,))
📤 実行例: intercept: -13.49, coef: 0.857 R²: 0.944 秋田県(39.06%) の予測: 19.97 ‰(実測 19.7 に近い) residual_plot.png 保存
💬 読み方: 残差が 0 周りにランダムに散布していれば線形回帰の仮定が妥当。 沖縄県(残差 -2.45)が下方向に外れているのは「高齢化率では説明できない長寿要因」の存在を示唆。
from sklearn.linear_model import LinearRegression
import matplotlib.pyplot as plt

X = df[['高齢化率']].values
y = df['死亡率'].values

reg = LinearRegression().fit(X, y)
y_pred = reg.predict(X)
resid = y - y_pred

print('intercept:', round(reg.intercept_, 3), 'coef:', round(reg.coef_[0], 3))
print('R^2:', round(reg.score(X, y), 4))
print('秋田県(39.06%) の予測:', round(reg.predict([[39.06]])[0], 2))

# 残差プロット
fig, ax = plt.subplots(figsize=(6,4))
ax.scatter(y_pred, resid)
ax.axhline(0, color='gray', linestyle='--')
ax.set_xlabel('予測死亡率'); ax.set_ylabel('残差')
ax.set_title('残差プロット(SSDSE-B 2023, n=47)')
plt.tight_layout()
plt.savefig('residual_plot.png', dpi=120)

標準化偏回帰係数で「どの変数が効くか」を比較:

▼ コード解説(標準化偏回帰係数(変数の重要度比較))
🎯 解説: StandardScaler で説明変数と応答変数を平均 0・分散 1 に標準化してから回帰すると、 偏回帰係数の絶対値で「どの変数が最も効くか」を比較できる。 単位(円 vs %)の違いを排除した重要度ランキング。
📥 入力例: X_raw = [高齢化率(%), 出生率(‰), 合計特殊出生率] y = 死亡率(‰) scaler で各列を z-score 化
📤 実行例: 高齢化率: 標準化偏回帰係数 = +0.93 出生率: 標準化偏回帰係数 = -0.05 合計特殊出生率: 標準化偏回帰係数 = -0.02 → 高齢化率の効きが圧倒的
💬 読み方: 標準化係数は「説明変数を 1 標準偏差動かすと応答変数が何標準偏差動くか」。 高齢化率の 0.93 は他 2 変数の 20 倍効くことを示し、 死亡率の決定因子はほぼ高齢化率のみ。
from sklearn.preprocessing import StandardScaler

X_raw = df[['高齢化率', '出生率', '合計特殊出生率']].values
y = df['死亡率'].values

scaler = StandardScaler()
X_std = scaler.fit_transform(X_raw)

reg_std = LinearRegression(fit_intercept=False).fit(X_std, (y - y.mean()) / y.std())
for name, coef in zip(['高齢化率','出生率','合計特殊出生率'], reg_std.coef_):
    print(f'{name}: 標準化偏回帰係数 = {coef:+.3f}')
# 各係数の絶対値の大きさで「効きの強さ」を比較できる

係数の信頼区間と予測区間:

▼ コード解説(信頼区間と予測区間)
🎯 解説: 回帰直線の係数の 95% 信頼区間(回帰直線自体の不確実性)と、 個別観測の予測区間(新しい県を予測するときの誤差幅)を計算。 信頼区間 ⊂ 予測区間(予測区間の方が必ず広い)。
📥 入力例: alpha = 0.05(95% 区間) X = sm.add_constant(高齢化率) pred.summary_frame() で全 47 県の区間を取得
📤 実行例: 高齢化率の係数 95% CI: [0.793, 0.920] 予測値の 95% mean_ci: ±0.3 ‰ 個別観測の 95% obs_ci: ±1.3 ‰ → 平均的県の予測は精度高い、 個別予測は誤差大
💬 読み方: 「全国平均的に高齢化率が x% の県の平均死亡率はどこか」を知りたいなら mean_ci。 「ある特定の県の死亡率の幅」を知りたいなら obs_ci。 政策評価では mean_ci、 個別予測では obs_ci を使う。
X = sm.add_constant(df['高齢化率'])
model = sm.OLS(df['死亡率'], X).fit()
print('95% CI for coefficients:')
print(model.conf_int(0.05))

# 個別予測の 95% 区間
pred = model.get_prediction(X)
summary_frame = pred.summary_frame(alpha=0.05)
print(summary_frame.head())
# mean_ci_lower / upper: 回帰直線の信頼区間
# obs_ci_lower / upper: 個別観測の予測区間

SSDSE-B-2026 の読み込みと指標構築

回帰分析 を SSDSE-B 都道府県データで実演するため、 まず基礎指標を作ります。 47 都道府県 × 年度別の家計・人口・教育・医療指標が 100+ 含まれる総合データセットです。

▼ コード解説(SSDSE-B-2026 の再読込(基礎指標))
🎯 解説: 別の角度から回帰用データセットを準備。 同じ SSDSE-B-2026 を読み込み、 5 年分(2019-2023)をパネル形式で保持。 後段の年度別比較・横断面/時系列の対比に使う。
📥 入力例: data/raw/SSDSE-B-2026.csv(encoding=shift_jis) 全 235 行(5 年 × 47 県)
📤 実行例: df.shape → (235, 112) 年度ごとに 47 行ずつ 数値列の dtype 自動変換
💬 読み方: パネルデータ形式(年度×都道府県)で保持しておくと、 後で固定効果・ランダム効果・年度トレンドなど高度な分析にも転用できる。
import pandas as pd

# SSDSE-B-2026 を読み込み(年度別 47 都道府県、 最新は 2023 年度)
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='shift_jis', skiprows=1)
df.columns = [c.strip() for c in df.columns]
df = df[df['年度'] == 2023].reset_index(drop=True)

print(df.shape)             # (47, 112)
print(df['都道府県'].nunique())  # 47
print(df.iloc[:3, :5])

応答変数になりうる「人口千人あたり死亡率」「人口千人あたり出生率」「高齢化率」「若年比率」「転入超過率」などを派生:

▼ コード解説(主要指標の計算(再掲))
🎯 解説: 死亡率・出生率・高齢化率を計算。 比率変換は単位の異なる県を比較する基本前処理で、 回帰分析・相関分析・クラスタリングのすべてで共通の出発点。
📥 入力例: 死亡数、 出生数、 65歳以上人口、 総人口(5 年 × 47 県)
📤 実行例: 5 年間の高齢化率推移 秋田: 36.8 → 38.5 → 39.1(上昇) 沖縄: 22.4 → 22.8 → 23.1(緩やか)
💬 読み方: 高齢化率は全県で年々上昇するが、 上昇ペースは秋田・青森・高知で速く、 沖縄・東京で緩やか。 この傾向差が時系列回帰の重要な情報源になる。
# 主要指標を計算
df['死亡率']   = df['死亡数']   / df['総人口'] * 1000          # 人口千人あたり
df['出生率']   = df['出生数']   / df['総人口'] * 1000
df['高齢化率'] = df['65歳以上人口'] / df['総人口'] * 100
df['若年比率'] = df['15歳未満人口'] / df['総人口'] * 100
df['転入超過率'] = (df['転入者数(日本人移動者)'] - df['転出者数(日本人移動者)']) / df['総人口'] * 1000

print(df[['都道府県','高齢化率','出生率','死亡率','転入超過率']].head())
print(df[['高齢化率','出生率','死亡率']].describe().round(2))

続いて散布図で関係性の俯瞰:

▼ コード解説(散布図プロット(matplotlib))
🎯 解説: matplotlib で「高齢化率 vs 死亡率」の散布図を描画し、 回帰直線を重ねる。 視覚化により「直線関係か」「外れ値はあるか」を回帰前に診断できる。
📥 入力例: 高齢化率(x)と死亡率(y)の 47 点 単回帰の傾き 0.857、 切片 -13.49
📤 実行例: scatter_regression.png 出力 47 点がほぼ直線状に並ぶ 沖縄県のみ若干下方に外れる
💬 読み方: 散布図が直線状なら線形回帰の仮定が妥当。 曲線パターンなら多項式回帰や log 変換、 ヘテロな分散なら加重最小二乗を検討。
import matplotlib.pyplot as plt

fig, ax = plt.subplots(figsize=(7,5))
ax.scatter(df['高齢化率'], df['死亡率'], s=40, alpha=0.7)
for _, row in df.iterrows():
    ax.annotate(row['都道府県'], (row['高齢化率'], row['死亡率']),
                fontsize=8, alpha=0.6)
ax.set_xlabel('高齢化率 (%)')
ax.set_ylabel('死亡率(人口千人あたり)')
ax.set_title('SSDSE-B 2023: 高齢化率 × 死亡率(47 都道府県)')
plt.tight_layout()
plt.savefig('aging_vs_mortality.png', dpi=120)

📊 結果の可視化

回帰分析 の結果を読み解く際は、 単純な散布図とヒストグラムを必ず添えるのが鉄則です。 47 都道府県のような小サンプルでは、 平均だけでなく 分布の形状・外れ値の位置 を見せることで、 議論の透明性が大きく上がります。

▼ コード解説(seaborn での回帰可視化)
🎯 解説: seaborn.regplot は散布図と回帰直線・95% 信頼帯を一度に描画する。 lmplot を使うと層別回帰(地域別など)も簡単に可視化できる。
📥 入力例: df[['高齢化率', '死亡率']] の 47 行 ci=95 で信頼帯
📤 実行例: seaborn_regplot.png 青い直線と薄い帯(信頼区間)が表示 外れ値県は帯の外に
💬 読み方: 信頼帯が狭いほど回帰直線の推定精度が高い。 標本数 n=47 でも高齢化率と死亡率の関係は帯が極めて狭く、 関係の存在は強固。
import seaborn as sns
import matplotlib.pyplot as plt

fig, axes = plt.subplots(1, 3, figsize=(15, 4))

# 1) ヒストグラム
axes[0].hist(df['高齢化率'], bins=15, edgecolor='black')
axes[0].set_title('高齢化率の分布 (n=47)')
axes[0].set_xlabel('高齢化率 (%)')

# 2) 箱ひげ図
axes[1].boxplot([df['出生率'], df['死亡率']],
                 labels=['出生率', '死亡率'])
axes[1].set_title('出生率 vs 死亡率(人口千人)')

# 3) 散布図 + 回帰直線
sns.regplot(x='高齢化率', y='死亡率', data=df, ax=axes[2], ci=95)
axes[2].set_title('高齢化率 vs 死亡率(95% CI 付き)')

plt.tight_layout()
plt.savefig('eda_visuals.png', dpi=120)

これらの図に都道府県名のラベルを少なくとも 5 件ほど添えることで、 「どの県が外れ値か」を読み手と共有できます。 SSDSE-B 解析では 沖縄県・東京都・秋田県 が外れ値になりやすいので、 これら 3 県を最低限ラベリングすると親切です。

⚠️ よくある落とし穴

❌ 因果と相関の混同
回帰係数が大きく有意でも、それは「条件付き相関」。 X→Y の因果ではない。 反事実・無作為化を考えていない研究では「効く」とは言えない。
❌ 多重共線性
説明変数同士が強く相関すると係数の符号さえ反転することがある。 VIF > 10 を目安に変数を統合・除外する。SSDSE-B では人口・15-64 歳人口など同義変数を同時投入しないよう注意。
❌ 外挿の危険
学習データの説明変数範囲を外れた予測は信用できない。 高齢化率 22.8%〜39.1% で当てた式を、人口減少が極端な仮想県に適用しない。
❌ 残差の不均一分散
誤差項の分散が x によって変わると標準誤差が正しく推定できない。 残差プロット・Breusch–Pagan 検定を確認。
❌ 過学習
説明変数を増やせば R² は必ず上がる。 調整済み R² や交差検証・情報量規準で防ぐ。

SSDSE-B 固有の注意点

SSDSE-B は教育用に整備されたデータセット。 商用や公式統計のレポートに直接転用するときは、 原典の e-Stat へのリンクを必ず併記する文化があります。

📝 レポート・論文での書き方

レポートでの書き方テンプレート

論文・実務報告での書き方例:

「47 都道府県(SSDSE-B 2023 年度集計)を対象に、 △△ を応答変数とし、 ○○ を説明変数とした分析を行った。 推定された値は ×.×× (95% CI: ×.××, ×.××)であり、 期待される方向と一致していた。 ただし、 観察データのため、 因果関係としての解釈には限界がある。」

テンプレに従って、 (1) データ・サンプル数、 (2) 推定値・不確実性、 (3) 解釈の限界、 を必ず記載することが、 査読・レビューで通る最低ラインです。

🧭 SSDSE-B でのウォークスルー(共通)

SSDSE-B 2023(47 都道府県、 112 列)を題材に、 回帰分析 の関連分析でしばしば登場する処理を一通り辿ります。 ここはデータ前処理の典型パターンを覚える目的でもあります。

1) 年度の選択と単位の確認

SSDSE-B はパネルデータなので、 まず分析対象年度を絞ります。 多くの集計指標は実数(千人・件数)で記録されており、 比較のために 人口で割って比率 にすると、 県ごとの大小に左右されずに済みます。

▼ コード解説(年度ごとの行数と県数の確認)
🎯 解説: パネルデータの完備性チェック。 各年度に 47 県分そろっているかを groupby で確認する。 もし欠損年度があれば、 後段の固定効果回帰や階差分析で問題が起きる。
📥 入力例: df['年度'].value_counts() df.groupby('年度')['都道府県'].nunique()
📤 実行例: 2019: 47, 2020: 47, 2021: 47, 2022: 47, 2023: 47 全年度 47 県完備(バランスドパネル)
💬 読み方: バランスドパネル(全期間で全個体が観測)なら、 固定効果回帰がそのまま使える。 アンバランスなら欠損年度の補完か期間を絞る必要がある。
# 年度別の行数と県数
print(df.groupby('年度').size())
print(df.groupby('年度')['都道府県'].nunique())  # 各年 47 のはず

# 2023 年に絞り、 比率系を作る
df = df[df['年度'] == 2023].reset_index(drop=True)
df['食料費比率'] = df['食料費(二人以上の世帯)'] / df['消費支出(二人以上の世帯)']
df['住居費比率'] = df['住居費(二人以上の世帯)'] / df['消費支出(二人以上の世帯)']
df['教育費比率'] = df['教育費(二人以上の世帯)'] / df['消費支出(二人以上の世帯)']
print(df[['都道府県','食料費比率','住居費比率','教育費比率']].head())

2) 欠損値・型のチェック

▼ コード解説(欠損値のチェック)
🎯 解説: df.isna().sum() で各列の欠損数を一括確認。 欠損が多い列は回帰から外すか補完が必要。 isna 計上は前処理の必須ステップ。
📥 入力例: df 全体(235 行 × 112 列)
📤 実行例: ほぼすべての列で欠損 0 一部の福祉指標で 1-3 件の欠損あり → drop または interpolate で対処
💬 読み方: 公的データ SSDSE は欠損が極めて少なく、 ほぼそのまま分析可能。 ただし「平均寿命」など一部の指標は公表頻度が低く、 欠損が混入する場合がある。
# どの列に欠損があるか
nulls = df.isnull().sum()
print(nulls[nulls > 0])

# 数値列の型
print(df.select_dtypes(include='number').dtypes.head(10))

3) 集計と外れ値の俯瞰

▼ コード解説(上位・下位 5 県(食料費比率))
🎯 解説: 食料費比率(食料費 / 消費支出)の上位 5・下位 5 県を表示。 この比率は経済学で「エンゲル係数」と呼ばれ、 所得水準の代理指標。 高いほど低所得の地域。
📥 入力例: df['食料費比率'] = df['食料費'] / df['消費支出'] sort_values で上位・下位を抽出
📤 実行例: 上位 5: 沖縄 28%、 鹿児島 27%、 高知 26%, ... 下位 5: 東京 22%、 神奈川 22%、 埼玉 23%, ...
💬 読み方: 食料費比率が高い県は所得水準が相対的に低い傾向。 エンゲル係数は古典的な貧困指標で、 沖縄・地方圏で高く、 首都圏で低い。
# 食料費比率の上位/下位 5 県
print(df.nlargest(5, '食料費比率')[['都道府県','食料費比率']])
print(df.nsmallest(5, '食料費比率')[['都道府県','食料費比率']])

# 標準化スコアで外れ値検出
df['food_z'] = (df['食料費比率'] - df['食料費比率'].mean()) / df['食料費比率'].std()
print(df[df['food_z'].abs() > 2][['都道府県','食料費比率','food_z']])

4) 相関と散布図行列

▼ コード解説(相関行列の計算と表示)
🎯 解説: 主要指標 6 個の相関行列を計算し、 round(2) で見やすく表示。 多重共線性のチェックや変数選択の指針になる。 相関 0.9 を超えるペアは要警戒。
📥 入力例: vars_ = ['食料費比率','住居費比率','教育費比率','高齢化率','出生率','死亡率'] df[vars_].corr()
📤 実行例: 高齢化率 vs 死亡率: 0.97 出生率 vs 高齢化率: -0.62 食料費比率 vs 教育費比率: -0.45 → 高齢化率と死亡率は強相関
💬 読み方: 相関 0.97 は「ほぼ同じ情報」を意味し、 重回帰では片方のみ採用するのが原則。 一方、 教育費比率と食料費比率の負の相関は「家計内予算の代替関係」を示す。
vars_ = ['食料費比率','住居費比率','教育費比率','高齢化率','出生率','死亡率']
df['高齢化率'] = df['65歳以上人口'] / df['総人口'] * 100
df['出生率']   = df['出生数'] / df['総人口'] * 1000
df['死亡率']   = df['死亡数'] / df['総人口'] * 1000

print(df[vars_].corr().round(2))

# pairplot で散布図行列
import seaborn as sns
sns.pairplot(df[vars_])

5) 簡単な仮説検証

たとえば「食料費比率は高齢化率と正の相関がある」という仮説を、 ピアソン相関と簡単な回帰でチェックします:

▼ コード解説(scipy で相関係数と p 値)
🎯 解説: scipy.stats.pearsonr で相関係数と p 値を厳密に計算。 サンプルサイズが小さいときも p 値で「偶然か本物か」を判定できる。 n=47 では r=0.3 でも有意になる。
📥 入力例: x = df['高齢化率'], y = df['死亡率'] サンプルサイズ n=47
📤 実行例: r = 0.972, p = 1.2e-30 95% CI ≈ [0.951, 0.984] → 極めて強い正の相関、 偶然の確率はほぼゼロ
💬 読み方: p 値 < 0.001 で帰無仮説(無相関)を強く棄却。 SSDSE-B のような実データでは標本サイズが小さくても、 真の関係が強ければ統計的有意性は十分に得られる。
from scipy import stats
r, p = stats.pearsonr(df['食料費比率'], df['高齢化率'])
print(f'食料費比率 vs 高齢化率: r = {r:.3f}, p = {p:.4f}')

import statsmodels.api as sm
X = sm.add_constant(df['高齢化率'])
mod = sm.OLS(df['食料費比率'], X).fit()
print(mod.summary().tables[1])

このような一連の流れは、 ほぼ全ての SSDSE-B 分析で再利用できます。 回帰分析 を扱うときも、 この骨格に沿って準備を進めると安全です。

🌍 他分野での類似概念

回帰分析 の発想や定式化は、 回帰モデル の枠を超えて、 多くの応用分野で形を変えて登場します。 ここでは代表的な対応関係を整理します。

分野類似概念・対応する道具
経済学需給・効用最大化・回帰モデル賃金関数・需要関数の推定
疫学・公衆衛生リスク比・オッズ比・コホート研究喫煙と疾患リスクの関係
機械学習教師あり学習・特徴量重要度線形モデル・木モデル・NN
マーケティング顧客生涯価値・チャネル寄与度広告効果のアトリビューション
製造業SPC・ロバストデザイン歩留まり要因の特定
政策評価因果推論・準実験SSDSE-B を使った県別効果推定

「回帰分析」は単独の手法ではなく、 多くの分析の 共通言語 として位置づけられます。 用語自体を覚えるよりも、 「どんな場面でこの考え方が顔を出すか」を蓄積していくと、 応用が利きやすくなります。

✅ 分析前後のチェックリスト

回帰分析 を扱う前後で確認すべきポイント:

SSDSE-B は教育用に公開されており、 そのまま研究結果として外部発表する際は e-Stat の原典への引用 を必ず添えるのが慣例です。

🏛️ 応用事例

分野応答変数 y説明変数 X の例
経済・人口地域の死亡率・出生率高齢化率・所得・医療資源
教育進学率世帯所得・学校数・地域
マーケティング購買金額年齢・性別・過去履歴
製造業歩留まり温度・圧力・原料
医療血圧・血糖値年齢・BMI・運動量
SSDSE-B 都道府県分析食料費比率所得水準・気温・年齢構成

共通するのは 「ある結果指標を、 複数の説明変数で予測・解釈したい」 という発想。 回帰分析は科学・実務の最も基本的なデータ要約ツールであり、 機械学習へ進む前提でもあります。

❓ よくある質問

Q1. 単回帰と重回帰、 どちらを使えばいい?
A. 「他の影響を取り除いた効果」を知りたいなら重回帰。 関係の俯瞰・可視化なら単回帰でも十分。 まずは単回帰でデータの肌触りを掴み、 重回帰で交絡を調整するのが定石。
Q2. R² がどれくらいなら「良い」モデル?
A. 分野により大きく異なる。 物理学では R² > 0.99 が当たり前、 社会科学では R² = 0.3 でも十分有意な発見になり得る。 SSDSE-B 都道府県のような集計データはノイズが小さく R² は高くなる傾向。
Q3. 残差が正規分布しないとダメ?
A. 厳密には係数の推定だけなら不要、 仮説検定や区間推定では仮定したい。 サンプル数が大きければ中心極限定理で漸近的に正規になるので、 重要なのは「明らかに歪んでいないか」を残差プロットで見ること。
Q4. 外れ値はどう扱う?
A. 単純に除外せず、 原因を調査するのが先。 SSDSE-B では沖縄県が高齢化率・死亡率の関係から外れる例。 これは「沖縄特有の事情を別変数で説明できないか」というヒントになる。

🕰 歴史と発展

回帰分析の起源は Francis Galton (1822–1911) による「親子の身長」研究 (1886) に遡ります。 Galton は「背の高い親の子は、 親より平均に近い背丈になる」現象を発見し、 これを "regression toward the mean"(平均への回帰)と呼びました。 これが "regression" という名称の起源です。

その後、 Karl Pearson による相関係数・R. A. Fisher による分散分析・最小二乗法の確立を経て、 20 世紀後半には Nelder & Wedderburn (1972) の一般化線形モデル (GLM) として拡張されました。 21 世紀のいまは、 機械学習の ペナルティ付き回帰 (Ridge, Lasso, Elastic Net)ベイズ回帰カーネル法 など、 多くの発展系を持っています。

SSDSE-B のような公的統計分析では、 古典的な OLS と GLM が引き続き主役。 過学習や多重共線性に注意しつつ、 解釈可能性を重視する文化が続いています。

✅ 実装前後のチェックリスト

段階確認項目
事前応答変数の尺度(量的か質的か)/ 欠損値の有無/ 外れ値の予備チェック
事前説明変数の単位の確認(標準化が必要か)
事前サンプル数 n vs 説明変数 p の比(経験則: n ≥ 10p)
推定後係数の符号・大きさ・有意性
推定後R² と 調整済み R² の差(過学習の兆候)
推定後残差プロット(パターン・不均一分散)
推定後VIF(多重共線性)
推定後残差の正規性(QQ プロット)
解釈因果ではなく条件付き相関の解釈に留める
報告係数・SE・p 値・R² ・サンプル数・前処理の方針

🗺 概念マップ

この用語の前提・並列・発展を一覧で:

関係主要用語
前提となる用語平均分散標準偏差標本母集団
関連性の把握相関共分散散布図
回帰モデル線形回帰OLS残差
検定・推定仮説検定p 値信頼区間点推定
因果推論処置群対照群交絡自然実験
変数の尺度名義尺度順序尺度間隔尺度比例尺度