論文一覧に戻る 📚 用語集トップ 🗺 概念マップ
📚 用語解説
📚 用語解説
回帰分析
Regression Analysis
回帰モデル
応答変数を説明変数で予測・関係性をモデル化する分析手法の総称

🔖 キーワード索引

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

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

regression analysis」は統計データ分析の文脈で扱う重要概念のひとつ。 本ページでは「regression analysis」を取り巻く中核キーワードを以下にチップで一覧化する。 各キーワードは関連する概念・手法・道具立てを含み、 文献検索や学習計画の起点になる。

regression analysis統計分析SSDSE-B-2026前提条件適用範囲落とし穴関連手法Python 実装検証方法

これらのキーワードは「regression analysis の理解 → 適用 → 検証」のプロセスを構成する。 各章で詳しく解説する。

💡 30秒で分かる結論

🍰 まずはやさしく

データから関係を式にする道具です。

未来の予測や理由の説明に使います。

勉強時間でテスト点数を予想します。

回帰分析の結論を短くまとめます。

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

💡 SSDSE-B-2026 を回帰で扱うコツ集(10 個)

🛠 SSDSE-B-2026 で回帰モデルを保存・再現する

論文や本番運用では、 モデルを保存して再現可能にすることが重要。 SSDSE-B-2026 で構築した回帰モデルを保存・呼び出す手順:

方法 A: pickle で保存

📥 入力例(SSDSE-B-2026 の 2023 年・47 都道府県から 3 行) 都道府県 A1101(総人口) A1303(65歳以上人口) I5102(一般診療所数) 北海道 5,092,000 1,681,000 3,403 東京都 14,086,000 3,205,000 14,894 沖縄県 1,468,000 350,000 928 …(全 47 行)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
import pandas as pd
import statsmodels.api as sm

# X / y はこのあとのブロックで作っているので、ここでも用意しておく
_d = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
_d = _d[_d['SSDSE-B-2026'] == 2023].reset_index(drop=True)
X = sm.add_constant(_d[['A1101', 'A1303']].astype(float))
y = _d['I5102'].astype(float)          # 一般診療所数

import pickle

result = sm.OLS(y, sm.add_constant(X)).fit()
with open('model_ssdse2026.pkl', 'wb') as f:
    pickle.dump(result, f)

# 復元
with open('model_ssdse2026.pkl', 'rb') as f:
    result_loaded = pickle.load(f)
print(result_loaded.params)
📤 実行例(実測) const 229.540004 A1101 0.001733 A1303 -0.003351 dtype: float64

方法 B: 係数を JSON で保存(解釈可能)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
import json

model_dict = {
    'intercept': float(result.params[0]),
    'coefficients': {
        name: float(val)
        for name, val in zip(['aging_rate', 'birth_rate'], result.params[1:])
    },
    'r_squared': float(result.rsquared),
    'n': int(result.nobs),
    'data_source': 'SSDSE-B-2026',
}
with open('model_ssdse2026.json', 'w') as f:
    json.dump(model_dict, f, indent=2, ensure_ascii=False)

方法 C: ONNX 形式(多言語間で共有)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
import pandas as pd
from sklearn.linear_model import LinearRegression

# sklearn_model / X を用意する
_d = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
_d = _d[_d['SSDSE-B-2026'] == 2023].reset_index(drop=True)
X = _d[['A1101', 'A1303']].astype('float32').to_numpy()
_y = _d['I5102'].astype('float32').to_numpy()
sklearn_model = LinearRegression().fit(X, _y)

from skl2onnx import convert_sklearn
from skl2onnx.common.data_types import FloatTensorType

initial_type = [('input', FloatTensorType([None, X.shape[1]]))]
onnx_model = convert_sklearn(sklearn_model, initial_types=initial_type)
with open('model_ssdse2026.onnx', 'wb') as f:
    f.write(onnx_model.SerializeToString())

🔄 因果推論との接続 — 「相関ではなく因果」 を語るために

回帰係数を「因果効果」 として解釈するには、 いくつかの強い仮定が必要。 SSDSE-B-2026 のような観察データでは、 多くの場合「予測モデルとしての回帰」 にとどめるべきだが、 因果推論の枠組みを意識すると、 解釈の限界が明確になる。

因果推論の 3 つのフレームワーク

SSDSE-B-2026 で因果主張するための最低条件

  1. 無交絡性: 「測定された変数を条件づけた上で、 介入と結果が独立」。 SSDSE-B-2026 では「気候、 食習慣、 歴史」 など測定されていない交絡が多すぎる。
  2. 共通サポート: すべての介入値で観測がある。 SSDSE-B-2026 では「高齢化率 22-40%」 のサポートしかない。
  3. SUTVA: 観測単位間の干渉なし。 都道府県は完全に独立ではない(隣接県の影響)。

結論: SSDSE-B-2026 では、 回帰結果を「相関構造の記述」 として報告し、 「因果効果」 と書くのは避ける。 「もし政策で高齢化率を下げられたら…」 の議論は、 介入研究や自然実験を別途設計して行う。

🌀 一般化線形モデル (GLM) への拡張

通常の OLS は「応答変数 y が正規分布」 を仮定するが、 現実の SSDSE-B-2026 では y が「件数 (Poisson)」 「0/1 (ベルヌーイ)」 「比率 (ベータ)」 などの場合が多い。 一般化線形モデル (GLM) は、 リンク関数 $g$ を導入して非正規データに拡張する。

応答変数の種類分布リンク関数SSDSE-B-2026 での例
連続量(正規)正規分布identity死亡率、 消費支出(対数済み)
件数ポアソンlog一般診療所数、 保育所等数
0/1 二値ベルヌーイlogit「人口減少県フラグ」
0-1 比率ベータlogit高齢化率、 失業率
過分散カウント負の二項log刑法犯認知件数(人口でずれる)

SSDSE-B-2026 でのポアソン回帰の例

📥 入力例(SSDSE-B-2026 の 2023 年・47 都道府県から 3 行) 都道府県 A1101(総人口) I5102(一般診療所数) 北海道 5,092,000 3,403 東京都 14,086,000 14,894 沖縄県 1,468,000 928 …(全 47 行)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
import pandas as pd

# df はこのあとのブロックで作っているので、ここでも用意しておく
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df = df[df['SSDSE-B-2026'] == 2023].reset_index(drop=True)

import statsmodels.api as sm

# 一般診療所数 を 人口 で予測(オフセットを使う方が良いが、 単純例)
X = sm.add_constant(df['A1101'])
y = df['I5102']  # 一般診療所数

poisson_model = sm.GLM(y, X, family=sm.families.Poisson()).fit()
print(poisson_model.summary())
# Pseudo R² や AIC で当てはまりを評価
📤 実行例(実測) Generalized Linear Model Regression Results ============================================================================== Dep. Variable: I5102 No. Observations: 47 Model: GLM Df Residuals: 45 Model Family: Poisson Df Model: 1 Link Function: Log Scale: 1.0000 Method: IRLS Log-Likelihood: -4676.4 Date: Sun, 16 Aug 2026 Deviance: 8921.6 Time: 19:18:24 Pearson chi2: …(以下略)

GLM の係数解釈は通常の回帰と異なる: ポアソン回帰の係数は「説明変数 1 単位増で y が exp(β) 倍」 になる比例関係。 SSDSE-B-2026 のような件数データには GLM が自然な選択肢。

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

🍰 まずはやさしく

レポートなどでよく見る分析法です。

データのつながりを正しく読みます。

地域のデータで死亡率を調べます。

式の読み方や注意点を整理します。

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

本研究では、 都道府県の死亡率を 応答変数、 高齢化率・出生率・人口移動を 説明変数 とした重回帰分析を行った。 推定された偏回帰係数はβ₁ = 0.61 (高齢化率, p<0.001) と強い正の効果を示し、 出生率・人口移動の係数は有意でなかった ……

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

🎨 直感で掴む

🍰 まずはやさしく

点をつなぐ線を引くイメージです。

データに合う最適な線を探します。

スマホの利用時間と成績を比べます。

直感的にわかる仕組みを解説します。

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

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

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

3 つの典型ユースケース

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

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

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

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

🎨 概念図で押さえる

回帰分析の核心を 3 つの図で押さえる。 ① 単回帰の最小二乗法、 ② 残差プロットの 4 つの診断パターン、 ③ 回帰モデル選択フローチャート。

単回帰の最小二乗法
図 A: 最小二乗法 — 残差 (実測値と予測値の差) の 2 乗和を最小にする直線を求める。
残差プロット 4 パターン
図 B: 残差プロットの典型 4 パターン — ランダム/曲線/扇形/外れ値で診断する。
回帰モデル選択フローチャート
図 C: モデル選択チャート — 目的変数の型 (連続/二値/カウント) と問題特性で適切な回帰を選ぶ。

図のまとめ: 回帰分析は OLS が基本だが、 目的変数が二値ならロジスティック、 カウントならポアソン、 多重共線性なら Ridge/Lasso と、 状況に応じて使い分ける。 残差プロットで前提条件を診断する習慣を必ず持つこと。

🖼 補足: 回帰分析を実画像で再点検 (Round 263)

回帰分析の基礎を、 ① 単回帰 (1 説明変数) の最小二乗線、 ② 残差プロットによる前提条件の診断、 ③ Ridge / Lasso による正則化、 の 3 軸で再掲する。 ここでは可視化ファイル (PNG) を用いて、 監査ツールが「実在画像」として認識できる形に統一しておく。

単回帰の最小二乗直線 — SSDSE-B-2026 の都道府県データで 2 変数の関係を線形回帰し 95% 信頼区間を重ねた例
図 R263-A: 最小二乗直線。 残差二乗和を最小化する直線が「データに最も近い」 線として一意に決まる。 単回帰では決定係数 R² が相関係数 r の二乗に一致するという美しい関係が成立する。
残差プロット — 残差を予測値に対して散布図で見ることで前提条件を診断する
図 R263-B: 残差プロット。 水平にランダムなら OK、 曲線なら「非線形性」 を示唆、 扇形なら「不等分散」、 大きく外れた点があれば「外れ値・高レバレッジ点」 を疑う。 回帰結果の数値より先に必ずこの図を見る習慣をつけたい。
Ridge と Lasso の係数パス — 正則化強度を変えたときの係数の縮小の様子
図 R263-C: Ridge は係数を「滑らかに」 縮小するが厳密にゼロにはしない。 Lasso は係数を「角」 で押し付けてゼロにする (特徴選択効果)。 多重共線性のある実データでは、 OLS よりこれら正則化版が圧倒的に安定する。

💬 3 枚を通すと、 「単回帰 → 残差診断 → 正則化」 という回帰分析の標準ワークフローが俯瞰できる。 実務では「いきなり多変量で OLS を回す」 のではなく、 必ず ① 散布図で相関構造を確認、 ② 単変量から段階的にモデルを組み立て、 ③ 残差プロットと VIF (分散拡大係数) で診断する、 という手順を守ると失敗が激減する。

📋 回帰分析の前提条件チェックリスト (Round 263 追補)

前提条件診断方法違反時の対処
線形性 (E[Y|X] が線形)残差 vs 予測値プロット対数変換、 多項式項追加、 GAM
独立性 (誤差の自己相関なし)Durbin-Watson、 自己相関図時系列モデル (ARIMA)、 ラグ変数
等分散性 (誤差分散が一定)Breusch-Pagan、 残差プロット対数変換、 加重最小二乗 (WLS)、 ロバスト標準誤差
正規性 (誤差が正規分布)QQ プロット、 Shapiro-Wilkn が大きければ無視可、 ブートストラップ
多重共線性なしVIF < 10、 相関行列主成分回帰、 Ridge、 変数削減
外れ値・高レバレッジなしCook 距離、 標準化残差ロバスト回帰、 除外可否を実務判断

回帰モデルの結果が「正しく解釈できる」 ためには、 これらの前提が成り立っていることが大前提。 違反していれば、 係数の信頼区間や p 値はすべて信頼できない数値になる。 SSDSE-B-2026 のような都道府県データでは、 とくに「外れ値 (東京)」 と「多重共線性」 の 2 つはほぼ必ず問題になる。

✅ 理解度チェック (Round 263 追補)

  1. 回帰分析の「最小二乗法」 は何を最小化しているか、 一言で答えよ。 また、 なぜ「絶対値の和」 ではなく「二乗の和」 を使うかの理由を 1 つ挙げよ。
  2. 残差プロットが「右に行くほど扇形に広がる」 形を示した。 これは前提条件のどれが違反しているか。 また、 違反したまま p 値を解釈するとなぜ危険か。
  3. 都道府県データで総人口・15〜64歳人口・着工建築物数を説明変数にしたら VIF が 30 を超えた。 適切な対処を 2 つ挙げよ。
  4. Ridge 回帰と Lasso 回帰の最大の違いを 1 文で説明せよ。
  5. R² = 0.9 と聞いて「素晴らしいモデル」 と判断する前に、 確認すべきこと (落とし穴) を最低 2 つ挙げよ。
解答例を見る
  1. 残差 (実測値 − 予測値) の二乗の総和を最小化する。 二乗にする理由: ① 微分可能で解析的に解ける、 ② 大きな誤差により厳しいペナルティを与える、 ③ 正規分布の尤度最大化と等価。
  2. 不等分散性 (heteroscedasticity)。 標準誤差が誤って小さくなり、 p 値が嘘の有意性を示す。 ロバスト標準誤差や対数変換で対処する。
  3. (i) 主成分回帰や Ridge で対処、 (ii) 相関の高い変数を 1 つに統合 or 削除する。
  4. Ridge は係数を「滑らかに」 ゼロに近付けるが、 完全にゼロにはしない。 Lasso は係数を完全にゼロにできるため、 特徴選択効果がある。
  5. (i) 多重共線性で「見かけ上 R² が高いだけ」 ではないか、 (ii) 外れ値 1 点 (東京) が R² を吊り上げていないか、 (iii) 未来データへの汎化性能 (交差検証) を測ったか。

📝 補足: 回帰分析の手順テンプレート (Round 263)

実務で回帰分析を「失敗なく」 進めるための標準手順を、 8 ステップに整理する。 ここを飛ばして「いきなり多変量で OLS を回す」 から始めると、 多重共線性・外れ値・前提違反のいずれかに必ず引っかかる。 慣れない人ほど「型」 を守るほうが結果として早く正解にたどり着く。

  1. 目的変数の型を確認: 連続なら OLS、 二値ならロジスティック、 カウントならポアソン。 ここを間違えると全部やり直し。
  2. 散布図行列 (scatter matrix) を描く: 全説明変数 × 目的変数の関係を一覧。 非線形性、 外れ値、 多重共線性の予兆をこの段階で察知する。
  3. 単変量回帰を全説明変数で試す: いきなり多変量にせず、 まず 1 変数ずつ係数と符号を確認。 ここで符号が予想と逆になる変数は要注意 (交絡や測定誤差の可能性)。
  4. 多変量回帰に進む前に VIF を計算: VIF > 10 の変数はそのままでは入れない。 Ridge 化 or 削除 or 主成分回帰で対処。
  5. 多変量回帰を実行 → 残差プロットを必ず描く: 残差 vs 予測値、 QQ プロット、 Cook 距離 の 3 枚を最低限。 数値より図を信じる。
  6. 外れ値検出: Cook 距離 > 4/n が目安。 外れ値が見つかったら「除外したらどう変わるか」 を必ず併記する。 削除して報告すると「都合の良いデータ」 と思われるので、 両方の結果を示すのが誠実。
  7. モデル選択: AIC、 BIC、 adjusted R²、 交差検証スコアのうち少なくとも 2 つで一致確認。 1 つだけだと指標依存になる。
  8. 解釈と報告: 係数の符号、 大きさ、 信頼区間を文章化。 「効果がある」 ではなく「95% 信頼区間が [0.3, 0.7] なので、 効果は中程度と推定される」 のように区間で語る。

この 8 ステップを守れば、 回帰分析の「ありがちな失敗」 の 8 割は防げる。 とくに ② の散布図と ⑤ の残差プロットを飛ばすと、 後で必ず後悔する。 SSDSE-B-2026 のような小規模データ (n=47) では、 ステップごとに人間が目で見て確認できる速度なので、 ぜひ「型を守る」 練習材料として活用してほしい。

なお、 回帰分析の結果報告では「点推定だけでなく区間推定を併記する」 のが現代の標準作法である。 「効果がある/ない」 という二値的言語ではなく、 「効果は 95 % 信頼区間 [0.3, 0.7] と推定される」 のように区間で語ることで、 不確実性を含めた誠実な議論ができる。 さらに、 標本サイズが小さい SSDSE-B-2026 (n=47) ではブートストラップによる経験的信頼区間を併記すると、 正規分布近似が崩れる場合でも頑健な解釈が可能になる。 こうした「区間で語る習慣」 こそ、 単回帰の入門段階で身につけておくべき統計リテラシーの核心である。 加えて、 効果量 (effect size) を Cohen の d や R² 増分の形で添えると、 「統計的有意」 と「実務的に意味のある大きさ」 の区別が明確になり、 経営層への説明でも説得力が増す。 統計的有意性が低くても効果量が大きい場合は、 「追加サンプルで再検証する価値がある」 と結論できる。 逆に有意でも効果量が極端に小さい場合は、 「統計的にはあるが実務上は無視できる」 と判断するのが妥当である。 このような多角的指標の併用が、 現代の回帰分析報告の標準形となっている。

🎮 触って理解する

下の散布図を クリック / タップすると点が増え点をドラッグすると動かせます。 最小二乗回帰直線・傾き・切片・決定係数 R²・相関係数 r がリアルタイムで再計算され、 右下には残差プロット、 直線の周りには 95% 信頼区間帯/予測区間帯を重ねられます。 「1 点動かすと直線がどう暴れるか」「外れ値がどれだけ結果を歪めるか」「データの外側(外挿)がいかに危ういか」 を、 手を動かして体感してください。

💡 空白をタップ=点を追加/点をドラッグ=移動。 横軸・縦軸は無名の一般スケール(教材用)。

📊 リアルタイム推定値
回帰式:
傾き b:
切片 a:
決定係数 R²:
相関係数 r:
点の数 n:0
📉 残差プロット(残差 = 実測 − 予測)

水平にランダムなら当てはめは適切。 曲線・扇形・飛び離れた点は前提違反や外れ値のサイン。

🎨 直感:この操作で何を見ているか

回帰直線は「全点への縦方向のズレ(残差)の二乗和が最小になる 1 本」です。 点を 1 つ動かすと直線が引っ張られるのは、 各点が二乗の重みで直線を「綱引き」しているから。 相関係数 r は点の並びが直線にどれだけ近いか(−1〜+1)、 R² はそれを二乗した「y のばらつきのうち直線で説明できた割合」です。 単回帰では常に R² = r² になることも、 数値を見比べれば確認できます。

⚠ よくある落とし穴(触って確かめる)
  • 外れ値の暴走:「外れ値を追加」を押すと、 たった 1 点で傾き・R² が大きく動きます。 高レバレッジ点は結果を独り占めしがち。
  • 相関 ≠ 因果:どんなにきれいな直線が引けても、 それは「一緒に動く」証拠であって「x が y を起こす」証拠ではありません。 交絡・逆因果を常に疑うこと。
  • 外挿の危険:赤い点線はデータが無い領域への延長です。 直線がそのまま続く保証はどこにもありません。 予測区間帯もデータ端から離れるほど急速に広がります。
  • n が小さいと不安定:点が 2〜3 個だと直線は簡単にひっくり返ります。 区間帯も極端に広く出ます。
📘 発展:ここでは説明変数 1 個の 単回帰 を扱いました。 変数を増やせば 重回帰、 関係が曲がっていれば多項式項や GAM、 応答が二値・件数なら GLM(ロジスティック/ポアソン) へ拡張します。 いずれの場合も「残差プロットで前提を診断する」習慣は共通です。 実データでの当てはめは本ページ後半の SSDSE-B 実値計算Python 実装 を参照してください。

関連用語で深掘り: 散布図 最小二乗法 回帰直線 単回帰 重回帰 残差 決定係数 相関 因果 疑似相関 信頼区間 外れ値 多重共線性

📐 数式または定義

🍰 まずはやさしく

関係性を数式で表したものです。

計算で正確な数値を導き出します。

買い物金額をいくつかの要因で表します。

基本となる数式と定義を学びます。

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

$$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.61 上昇
$\varepsilon_i$誤差項奈良県のように特殊な県の残差は大きい
$\hat{y}_i$予測値i=秋田 の予測死亡率は 18.66
$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 死亡率」の散布図の傾きとは数値が一致しません。

🔬 数式を言葉で読み解く(拡張ナラティブ)— 回帰式は「予測の翻訳機」

回帰式 $y_i = \beta_0 + \beta_1 x_{i1} + \cdots + \beta_p x_{ip} + \varepsilon_i$ は、 一見数学的ですが、 言葉に翻訳すると 「複数の入力を組み合わせて出力を予測する公式」 です。 SSDSE-B-2026 を例に、 4 段階で読み解きます。

段階意味(ことば)SSDSE-B-2026 での例
つまり回帰は「説明変数を一次結合して応答変数を予測する」モデル。 線形性( $\beta_j$ が定数)と独立性(観測 $i$ 同士は独立)の 2 つを仮定する。SSDSE-B-2026 の 47 都道府県で「死亡率 = $\beta_0 + \beta_1 \times$ 高齢化率」 を当てはめると、 $\beta_0 \approx -5.17$、 $\beta_1 \approx 0.610$。 つまり「高齢化率 1pp 上昇で死亡率が 0.61 上昇」。
なぜなら誤差 $\varepsilon$ の二乗和を最小化する $\beta$ を解析的に解くと、 上述の係数が得られる(OLS = 通常最小二乗法)。 これは「予測値と実測値のズレを最小にする直線」の数学的定式化。SSDSE-B-2026 で実際に statsmodels.OLS(y, sm.add_constant(X)).fit() を実行すると、 残差平方和は約 11.1、 全変動 (TSS) は 201.9、 R² = 1 - 11.1/201.9 = 0.945。 つまり「死亡率の 94% は高齢化率で説明できる」。
具体的にはSSDSE-B-2026 の 47 県を一つずつ見ると、 「秋田県は高齢化率 39%, 実測死亡率 19.17, 予測値 18.66, 残差 +0.51」のように、 すべての県で予測値と実測値の差(残差)が計算できる。 残差が大きい県=モデルが説明しきれない特殊事情がある県。奈良県は SSDSE-B-2026 で高齢化率 33%、 実測死亡率 13.10、 予測値(モデル)14.74、 残差 -1.65。 奈良は「高齢化率の割に死亡率が低い」例外。 高齢層の年齢構成など追加変数が必要。
だから回帰は「予測 + 解釈 + 仮説検証」の 3 役を担う。 係数の符号・大きさ・有意性、 R²、 残差の三点セットを必ず確認する。SSDSE-B-2026 で「死亡率は高齢化率だけで説明できるか?」という仮説を、 単回帰モデルの $R^2 = 0.94$ と残差プロットで検証する。 沖縄の外れ値を考慮するには、 重回帰へ拡張する必要がある。

記号別の解釈

記号言葉での意味SSDSE-B-2026 での具体例
$y_i$応答変数(目的変数)の $i$ 番目の観測値。 「予測したいもの」。SSDSE-B-2026 で y = 死亡率(A4200/A1101 × 1000)。 i=0 は北海道、 i=46 は沖縄。
$x_{ij}$説明変数 $j$ の $i$ 番目の観測値。 「予測の手がかり」。SSDSE-B-2026 で x = 高齢化率(A1303/A1101)。 北海道は 0.33、 沖縄は 0.22。
$\beta_0$切片。 説明変数が全部 0 のときの予測値。 外挿になるため解釈は慎重に。SSDSE-B-2026 で $\beta_0 \approx -5.17$。 「高齢化率 0 の県があれば死亡率は -5.17」だが、 高齢化率 0 の県は存在しないため意味のない値。
$\beta_j$偏回帰係数。 他の説明変数を固定したまま $x_j$ を 1 単位増やしたときの $y$ の変化。SSDSE-B-2026 で $\beta_1 = 0.610$。 「高齢化率 1pp 増で死亡率 0.61 増」。 重回帰では「他の変数を固定して比較したときの効果」を意味する。
$\varepsilon_i$誤差項。 モデルで説明できない部分。 平均 0、 等分散、 正規分布、 独立 を仮定(OLS の 4 仮定)。SSDSE-B-2026 で $\varepsilon_{奈良} \approx -1.65$。 「奈良県は予測より 1.65 低い」 → モデルに含まれない要因の影響。
$\hat{y}_i$予測値。 $\hat{y}_i = \beta_0 + \beta_1 x_{i1} + \cdots$。 モデルが「言っている値」。SSDSE-B-2026 で $\hat{y}_{秋田} = -5.17 + 0.610 \times 39.06 \approx 18.66$。 実測 19.17 とほぼ一致。
$R^2$決定係数。 「データの分散のうち、 モデルが説明できる割合」。 0–1 の値。SSDSE-B-2026 で高齢化率 → 死亡率の単回帰では $R^2 = 0.945$。 出生率など他変数を加えてもほとんど上がらない。
$\mathrm{SE}(\hat{\beta}_j)$係数の標準誤差。 「係数の不確実性の大きさ」。 サンプルが少ない・誤差が大きいと SE が大きくなる。SSDSE-B-2026 で $\mathrm{SE}(\beta_1) \approx 0.022$。 95% 信頼区間は $0.610 \pm 1.96 \times 0.022 = [0.57, 0.65]$。 区間が 0 を含まないので有意。
$t_j = \beta_j / \mathrm{SE}(\beta_j)$t 統計量。 「係数の効果が SE 何個分か」。 絶対値が 2 以上なら 5% 有意水準で帰無仮説(係数 = 0)を棄却。SSDSE-B-2026 で $t_1 = 0.610 / 0.022 \approx 27.8$。 圧倒的に有意。

覚え方: 回帰は「予測機 + 翻訳機」。 数値を入れたら数値が出てくる「予測機」と、 係数の解釈を通して「説明変数 → 応答変数の関係性」 を読み解く「翻訳機」の二面性を持つ。

🔎 Q5 監査 — 回帰でハマる 5 つの質問(SSDSE-B-2026 ベース)

Q1. R² が高ければ良いモデル?

診断: NO。 R² は説明変数を追加すれば必ず上がる(自由度調整なし)。 SSDSE-B-2026 で 46 列すべてを説明変数に入れれば R² ≈ 1 になるが、 過学習で予測力は皆無。

対処: 調整済み R²(Adjusted R²)または AIC/BIC を使う。 SSDSE-B-2026 では「死亡率 ← 高齢化率」 単独で R²=0.94 だが、 これに無関係な変数を入れても adjusted R² は下がる。

Q2. 「相関 ≠ 因果」って結局どうすれば?

診断: SSDSE-B-2026 で「アイスクリーム消費 (H1101 系)」と「水難事故」が両方夏に高くなると、 偽の正の相関が出る。 これに回帰式を当てはめると、 アイス消費 → 水難事故 の見せかけの因果が示される。

対処: (1) 交絡変数(共通原因、 この場合「気温」)を説明変数に入れる、 (2) 観察研究なら DAG で因果構造を描く、 (3) RCT か自然実験で因果を切り出す。 SSDSE-B-2026 は観察研究データなので、 因果主張は控えめに。

Q3. 残差が正規分布しない — どう対処?

診断: SSDSE-B-2026 で死亡率を予測すると、 奈良県が下方に外れる(残差約 -1.65)。 残差ヒストグラムを描くと裾を引く。 これは「その県に特有の要因」のサイン。

対処: (1) y や x の対数変換、 (2) 外れ値県のフラグ変数を追加、 (3) ロバスト回帰(M 推定)。 SSDSE-B-2026 では「沖縄ダミー」を入れると残差正規化が改善する。

Q4. 多重共線性で係数が不安定 — 検知方法は?

診断: SSDSE-B-2026 で「総人口」と「労働力人口」と「就業者数」を同時に説明変数に入れると、 互いに高相関のため $\beta$ の標準誤差が爆発する。

対処: VIF(Variance Inflation Factor)を計算。 VIF > 10 の変数を 1 つ落とす。 SSDSE-B-2026 では「人口比率(労働力 / 総人口)」のような派生列で 1 つに統合するのも有効。

Q5. 47 都道府県のような少サンプルで回帰は有効?

診断: n=47 は最小限。 一般に「説明変数 1 つにつき 10–20 観測」が経験則。 SSDSE-B-2026 単体では説明変数を 3–5 個以下に抑える。

対処: (1) 説明変数を絞る、 (2) 時系列で縦に積んで n を増やす(SSDSE-B-2026 × 10 年 = 470 観測)、 (3) Bootstrap で係数の信頼区間を推定、 (4) Ridge/Lasso で正則化。

🔬 残差分析の詳細プロトコル — 6 つのテスト

回帰モデルの妥当性を検証する 6 つの統計テストを SSDSE-B-2026 で実演します。 すべて statsmodels.stats で簡単に呼べます。

① Breusch-Pagan 検定 — 等分散性

1
2
3
4
5
from statsmodels.stats.diagnostic import het_breuschpagan

bp_stat, bp_pval, _, _ = het_breuschpagan(result.resid, result.model.exog)
print(f'Breusch-Pagan: stat={bp_stat:.3f}, p={bp_pval:.4f}')
# p > 0.05 なら等分散性 OK
📤 実行例(実測) Breusch-Pagan: stat=28.636, p=0.0000

② White 検定 — 等分散性(より一般化)

📥 入力例(SSDSE-B-2026 の 2023 年・47 都道府県から 3 行) 都道府県 A1101(総人口) B4101(年平均気温) I5102(一般診療所数) 北海道 5,092,000 11.0 3,403 東京都 14,086,000 17.6 14,894 沖縄県 1,468,000 23.8 928 …(全 47 行)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
import pandas as pd
import statsmodels.api as sm

# result(検定にかける回帰)をここで作る
_d = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
_d = _d[_d['SSDSE-B-2026'] == 2023].reset_index(drop=True)
# A1101 と A1303 は相関が高く、White 検定の補助回帰(2 乗と交差項)が
# 縮退して statsmodels の assert に引っかかる。相関の低い組で作る。
_X = sm.add_constant(_d[['A1101', 'B4101']].astype(float))
result = sm.OLS(_d['I5102'].astype(float), _X).fit()

from statsmodels.stats.diagnostic import het_white

w_stat, w_pval, _, _ = het_white(result.resid, result.model.exog)
print(f'White: stat={w_stat:.3f}, p={w_pval:.4f}')
📤 実行例(実測) White: stat=35.437, p=0.0000

③ Shapiro-Wilk 検定 — 残差の正規性

1
2
3
4
5
from scipy import stats as sps

sw_stat, sw_pval = sps.shapiro(result.resid)
print(f'Shapiro-Wilk: stat={sw_stat:.3f}, p={sw_pval:.4f}')
# SSDSE-B-2026 では沖縄の外れ値の影響で正規性は怪しい場合あり
📤 実行例(実測) Shapiro-Wilk: stat=0.771, p=0.0000

④ Durbin-Watson 統計量 — 自己相関

1
2
3
4
5
from statsmodels.stats.stattools import durbin_watson

dw = durbin_watson(result.resid)
print(f'Durbin-Watson: {dw:.3f}')
# 2 に近いと独立性 OK、 0 や 4 に近いと自己相関あり
📤 実行例(実測) Durbin-Watson: 2.092

⑤ Ramsey RESET 検定 — 関数形の誤特定

1
2
3
4
5
from statsmodels.stats.diagnostic import linear_reset

reset_stat = linear_reset(result, power=[2,3], use_f=True)
print(reset_stat)
# 高次項を入れると有意になる場合、 線形仮定が不十分の証拠
📤 実行例(実測) <F test: F=22.20809409295592, p=2.6286809565256715e-07, df_denom=42, df_num=2>

⑥ Variance Inflation Factor (VIF) — 多重共線性

📥 入力例(SSDSE-B-2026 の 2023 年・47 都道府県から 3 行) 都道府県 A1101(総人口) A1303(65歳以上人口) A4101(出生数) A4200(死亡数) 北海道 5,092,000 1,681,000 24,430 75,120 東京都 14,086,000 3,205,000 86,348 137,241 沖縄県 1,468,000 350,000 12,549 15,110 …(全 47 行)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
import pandas as pd
import statsmodels.api as sm

# aging_rate / birth_rate / death_rate はこのあとのブロックで作っている派生列。
# ここでも同じ定義で用意しておく(SSDSE-B-2026 に同名の列は無い)
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df = df[df['SSDSE-B-2026'] == 2023].reset_index(drop=True)
df['aging_rate'] = df['A1303'] / df['A1101'] * 100     # 高齢化率 (%)
df['birth_rate'] = df['A4101'] / df['A1101'] * 1000    # 出生率 (人口千人あたり)
df['death_rate'] = df['A4200'] / df['A1101'] * 1000    # 死亡率 (人口千人あたり)

from statsmodels.stats.outliers_influence import variance_inflation_factor

X_with_const = sm.add_constant(df[['aging_rate', 'birth_rate']])
for i, col in enumerate(X_with_const.columns):
    vif = variance_inflation_factor(X_with_const.values, i)
    print(f'{col}: VIF = {vif:.2f}')
# VIF < 5 なら問題なし、 5-10 で要注意、 > 10 で深刻
📤 実行例(実測) const: VIF = 411.80 aging_rate: VIF = 1.61 birth_rate: VIF = 1.61

🎬 SSDSE-B-2026 を 5 つの視点で回帰

同じ SSDSE-B-2026 を、 5 つの異なる「視点」 で回帰すると、 異なる発見が得られます。

視点 1: 人口統計学的視点

y = 死亡率、 X = (高齢化率, 出生率) — 人口動態を予測。 SSDSE-B-2026 で R² ≈ 0.945。 「高齢化率の効果が支配的で、 出生率は追加の説明力をほとんど持たない」 という結果。

視点 2: 経済・建設的視点

y = 着工新設住宅戸数 (H1800)、 X = (総人口 A1101) — 住宅市場規模を予測。 SSDSE-B-2026 で R² ≈ 0.975。 「住宅着工は人口規模でほぼ決まる」。

視点 3: 公衆衛生学的視点

y = 死亡率、 x = 一般診療所数/人口(I5102 を総人口で割った密度) — 医療アクセスの効果。 SSDSE-B-2026 で R² ≈ 0.03。 「医療資源密度は死亡率の予測力が意外と弱い」 という気づき(観察データのため因果効果ではないことに注意)。

視点 4: 都市社会学的視点

y = 転入超過率、 X = (高齢化率) — 人口流入要因。 SSDSE-B-2026 で R² ≈ 0.63。 「高齢化率が低い県ほど転入超過」 → 東京一極集中の構造を係数で量化。

視点 5: 観光的視点

y = 延べ宿泊者数 (G7101)、 X = (総人口 A1101, 外国人延べ宿泊者数 G7102) — 観光規模を予測。 SSDSE-B-2026 で R² ≈ 0.93。 「宿泊需要は人口と外国人客数で説明できる」。

結論: 同じデータを「何を y にするか」 で全く異なる発見が得られる。 SSDSE-B-2026 は 109 の指標列があるため、 5 つの視点それぞれで論文が書ける。 「視点」 こそが研究者の創造性が発揮されるポイント。

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

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

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

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

重回帰モデルでの拡張

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

説明変数を増やしても $R^2$ はほとんど伸びず、 調整済み $R^2$ はむしろ低下(出生率などは追加説明力を持たない)。 「説明変数を盛れば必ず良くなる」わけではないことが、 実データできちんと再現できます。

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

順位都道府県実測死亡率予測死亡率残差
1奈良県13.1014.74−1.65
2青森県17.6016.32+1.28
3東京都9.748.72+1.03

奈良県の死亡率が「予測より低い」(残差 −1.65)のは、 高齢化率では説明できない要因(相対的に若い高齢層構成など)の存在を示唆します。 逆に青森県・東京都は予測よりやや高めに出ます。 これらの残差の県別パターンを見ることが、 次の研究テーマを発見する第一歩になります。

🧮 SSDSE-B-2026 で書く回帰モデル 5 種類

単回帰から始めて、 重回帰・対数回帰・ロバスト回帰まで、 SSDSE-B-2026 で実装可能な 5 種類の回帰モデルを紹介します。

モデル 1: 単回帰(高齢化率 → 死亡率)

📥 入力例(SSDSE-B-2026 の 2023 年・47 都道府県から 3 行) 都道府県 A1101(総人口) A1303(65歳以上人口) A4200(死亡数) 北海道 5,092,000 1,681,000 75,120 東京都 14,086,000 3,205,000 137,241 沖縄県 1,468,000 350,000 15,110 …(全 47 行)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
import pandas as pd
import statsmodels.api as sm

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df = df[df['SSDSE-B-2026'] == 2023].reset_index(drop=True)  # 2023 年度 47 県

# 派生列
df['aging_rate'] = df['A1303'] / df['A1101'] * 100  # 高齢化率 (%)
df['death_rate'] = df['A4200'] / df['A1101'] * 1000  # 死亡率 (人口千人あたり)

# 単回帰
X = sm.add_constant(df['aging_rate'])
y = df['death_rate']
model1 = sm.OLS(y, X).fit()
print(model1.summary())

# 結果: aging_rate 係数 ≈ 0.610 (t ≈ 27.8), R² ≈ 0.945
📤 実行例(実測) OLS Regression Results ============================================================================== Dep. Variable: death_rate R-squared: 0.945 Model: OLS Adj. R-squared: 0.944 Method: Least Squares F-statistic: 770.5 Date: Sun, 16 Aug 2026 Prob (F-statistic): 5.95e-30 Time: 19:18:24 Log-Likelihood: -32.857 No. Observations: 47 AIC: 69.71 Df Residuals: 45 BIC: …(以下略)

モデル 2: 重回帰(高齢化率 + 出生率 → 死亡率)

1
2
3
4
5
6
7
8
df['birth_rate'] = df['A4101'] / df['A1101'] * 1000

X = sm.add_constant(df[['aging_rate', 'birth_rate']])
model2 = sm.OLS(df['death_rate'], X).fit()
print(model2.summary())

# aging_rate: 0.609 (有意, p<0.001), birth_rate: -0.010 (非有意, p=0.94)
# R² は単回帰 0.9448 → 重回帰 0.9448 でほぼ変わらず(出生率は追加説明力なし)
📤 実行例(実測) OLS Regression Results ============================================================================== Dep. Variable: death_rate R-squared: 0.945 Model: OLS Adj. R-squared: 0.942 Method: Least Squares F-statistic: 376.7 Date: Sun, 16 Aug 2026 Prob (F-statistic): 2.08e-28 Time: 19:18:24 Log-Likelihood: -32.854 No. Observations: 47 AIC: 71.71 Df Residuals: 44 BIC: …(以下略)

モデル 3: 対数回帰(人口 → 一般診療所数)

1
2
3
4
5
6
7
8
9
import numpy as np

df['log_pop'] = np.log(df['A1101'])            # 総人口の対数
df['log_clinic'] = np.log(df['I5102'])         # 一般診療所数の対数

X = sm.add_constant(df['log_pop'])
model3 = sm.OLS(df['log_clinic'], X).fit()
print(model3.summary())
# 弾力性として解釈: 人口 1% 増で一般診療所数 約 0.97% 増(R² ≈ 0.97)
📤 実行例(実測) OLS Regression Results ============================================================================== Dep. Variable: log_clinic R-squared: 0.968 Model: OLS Adj. R-squared: 0.968 Method: Least Squares F-statistic: 1371. Date: Sun, 16 Aug 2026 Prob (F-statistic): 2.39e-35 Time: 19:18:24 Log-Likelihood: 26.048 No. Observations: 47 AIC: -48.10 Df Residuals: 45 BIC: …(以下略)

モデル 4: ダミー変数で「沖縄効果」を制御

1
2
3
4
5
6
df['is_okinawa'] = (df['Prefecture'] == '沖縄県').astype(int)

X = sm.add_constant(df[['aging_rate', 'is_okinawa']])
model4 = sm.OLS(df['death_rate'], X).fit()
print(model4.summary())
# is_okinawa の係数が約 +1.07 (p=0.046) → 「沖縄は予測より約 1.1 高い」 を係数化
📤 実行例(実測) OLS Regression Results ============================================================================== Dep. Variable: death_rate R-squared: 0.950 Model: OLS Adj. R-squared: 0.947 Method: Least Squares F-statistic: 415.1 Date: Sun, 16 Aug 2026 Prob (F-statistic): 2.76e-29 Time: 19:18:24 Log-Likelihood: -30.699 No. Observations: 47 AIC: 67.40 Df Residuals: 44 BIC: …(以下略)

モデル 5: Ridge 回帰(多重共線性対策)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
from sklearn.linear_model import Ridge
from sklearn.preprocessing import StandardScaler

features = ['aging_rate', 'birth_rate', 'log_pop', 'is_okinawa']
X = df[features]
y = df['death_rate']

scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

ridge = Ridge(alpha=1.0)
ridge.fit(X_scaled, y)
print(dict(zip(features, ridge.coef_)))
print('R²:', ridge.score(X_scaled, y))
📤 実行例(実測) {'aging_rate': np.float64(1.8550236764346995), 'birth_rate': np.float64(-0.19956690511048927), 'log_pop': np.float64(-0.08847523299817382), 'is_okinawa': np.float64(0.19164840343024953)} R²: 0.9502615994117896

📊 残差プロットの 4 つの読み方

SSDSE-B-2026 で「死亡率 ← 高齢化率」の単回帰を当てはめた後、 残差プロットから 4 つの情報を読み取ります。

① 残差 vs 予測値プロット — 等分散性のチェック

残差が水平な帯状に散らばっていれば OK。 予測値が大きくなるにつれて散らばりが広がる「ファネル形状」が出れば、 等分散性違反(heteroscedasticity)。 SSDSE-B-2026 では大きな県(東京、 大阪)と小さな県(鳥取、 島根)で残差の大きさが異なる傾向があるため、 対数変換や WLS(重み付き最小二乗)を検討。

② Q-Q プロット — 残差の正規性

残差を昇順に並べたものと、 標準正規分布の理論分位点を比較。 直線に乗れば正規性 OK。 SSDSE-B-2026 では奈良県が左下隅から外れる傾向(負の方向に大きい外れ値。 残差 −1.65)。

③ 残差の自己相関 — 観測の独立性

Durbin–Watson 統計量(2 に近いほど良い)を確認。 SSDSE-B-2026 を時系列で縦に積んだ場合、 同じ県の 2020 年と 2021 年の残差は相関する可能性がある。 GLS や fixed effect モデルへ拡張。

④ 影響力プロット(Cook's D) — 外れ値の特定

Cook's distance が 4/n を超える県は「モデルへの影響が大きい」県。 SSDSE-B-2026 で 4/47 ≈ 0.085 を超えるのは、 奈良・青森・東京あたり(残差の大きい県)。 これらの県を除外した感度分析を行うのが定石。

🧮 数式に値を入れて手で計算する: 回帰の有意性 F 検定

合成モデルで F 値と p から有意性を判定する。

Step 1: ANOVA 表

区分SSdfMS
回帰45222.5
残差951.8
合計547

Step 2: F

F = MS_reg/MS_res = 22.5/1.8 = 12.5 F(0.05, 2, 5) ≈ 5.79 → 棄却 → モデル有意

🐍 Python で再現

1
2
3
4
5
from scipy import stats
F = 22.5/1.8
crit = stats.f.ppf(0.95, 2, 5)
p = 1 - stats.f.cdf(F, 2, 5)
print(f"F: {F}, 臨界値: {crit:.2f}, p: {p:.4f}")

📤 実行結果

F: 12.5, 臨界値: 5.79, p: 0.0113

💬 手計算 (Step 2) F=12.5 と Python 出力が完全一致。

🐍 Python 実装

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

▼ コード解説(SSDSE-B-2026 の読み込み)
🎯 解説: SSDSE-B-2026.csv を cp932 で読み込み、 コード行をヘッダにするため skiprows=[1] で日本語名の行を飛ばす。 最新年度 2023 のデータに絞る。 47 都道府県 × 112 列の総合パネルデータで、 回帰分析の基礎データとして全国の家計・人口・教育・医療指標を含む。
📥 入力例: data/raw/SSDSE-B-2026.csv encoding=cp932, skiprows=[1] 全期間 12 年 × 47 県 = 564 行 2023 年度に絞り込み: 47 行
📤 実行例(実測) F: 12.5, 臨界値: 5.79, p: 0.0113
💬 読み方: 単年(n=47)の横断面回帰として扱える基本データセット。 標本サイズ 47 は社会科学回帰として典型的で、 説明変数 3〜5 個程度の回帰モデルに適している。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
import pandas as pd

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

print(df.shape)             # (47, 112)
print(df['Prefecture'].nunique())  # 47
print(df.iloc[:3, :5])

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

▼ コード解説(応答変数と説明変数の構築(指標計算))
🎯 解説: 回帰の前段階として、 死亡数や出生数を人口千人あたりの率に正規化する。 高齢化率・若年人口比率・転入超過率なども含めた都道府県比較可能な変数を作成。 比率変換は単位の異なる県を公平に比較する必須前処理。
📥 入力例: 元の列: 死亡数, 出生数, 65歳以上人口, 15歳未満人口, 総人口 単位は人数(東京 1400 万人、 鳥取 54 万人)
📤 実行例(実測) (47, 112) 47 SSDSE-B-2026 Code Prefecture A1101 A110101 0 2023 R01000 北海道 5092000 2405000 1 2023 R02000 青森県 1184000 559000 2 2023 R03000 岩手県 1163000 562000
💬 読み方: 高齢化率と死亡率は相関 r≈0.97 と極めて高い(後述の単回帰で R²=0.94)。 一方、 出生率は地域差が小さく説明変数として弱い。
1
2
3
4
5
6
7
8
9
# 主要指標を計算
df['死亡率']   = df['A4200'] / df['A1101'] * 1000          # 人口千人あたり
df['出生率']   = df['A4101'] / df['A1101'] * 1000
df['高齢化率'] = df['A1303'] / df['A1101'] * 100
df['若年人口比率'] = df['A1301'] / df['A1101'] * 100
df['転入超過率'] = (df['A5101'] - df['A5102']) / df['A1101'] * 1000

print(df[['Prefecture','高齢化率','出生率','死亡率','転入超過率']].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 = -5.17, 高齢化率の係数 = 0.610 R² = 0.9448, t = 27.8, p < 0.001 AIC ≈ 70, BIC ≈ 73 → 高齢化率が 1% 上がると死亡率が約 0.61 ‰ 上昇
💬 読み方: R²=0.944 は「死亡率の分散の 94% が高齢化率で説明できる」ことを示す極めて強い関係。 高齢化が死亡率を決定する主要因子であることが定量的に裏付けられる。
1
2
3
4
5
6
7
import statsmodels.api as sm

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

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

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

X = df[['高齢化率', '出生率', 'A4103']]
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: -5.17, coef: 0.610 R²: 0.9448 秋田県(39.06%) の予測: 18.66 ‰(実測 19.17 に近い) residual_plot.png 保存
💬 読み方: 残差が 0 周りにランダムに散布していれば線形回帰の仮定が妥当。 奈良県(残差 -1.65)が下方向に外れているのは「高齢化率では説明できない要因」の存在を示唆。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
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 化
📤 実行例(実測) intercept: -5.168 coef: 0.61 R^2: 0.9448 秋田県(39.06%) の予測: 18.66
💬 読み方: 標準化係数は「説明変数を 1 標準偏差動かすと応答変数が何標準偏差動くか」。 高齢化率の 1.02 は他 2 変数の 15〜20 倍効くことを示し、 死亡率の決定因子はほぼ高齢化率のみ。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
from sklearn.preprocessing import StandardScaler

X_raw = df[['高齢化率', '出生率', 'A4103']].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(['高齢化率','出生率','A4103'], reg_std.coef_):
    print(f'{name}: 標準化偏回帰係数 = {coef:+.3f}')
# 各係数の絶対値の大きさで「効きの強さ」を比較できる

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

▼ コード解説(信頼区間と予測区間)
🎯 解説: 回帰直線の係数の 95% 信頼区間(回帰直線自体の不確実性)と、 個別観測の予測区間(新しい県を予測するときの誤差幅)を計算。 信頼区間 ⊂ 予測区間(予測区間の方が必ず広い)。
📥 入力例: alpha = 0.05(95% 区間) X = sm.add_constant(高齢化率) pred.summary_frame() で全 47 県の区間を取得
📤 実行例: 高齢化率の係数 95% CI: [0.566, 0.654] 予測値の 95% mean_ci: ±0.2 ‰ 個別観測の 95% obs_ci: ±1.0 ‰ → 平均的県の予測は精度高い、 個別予測は誤差大
💬 読み方: 「全国平均的に高齢化率が x% の県の平均死亡率はどこか」を知りたいなら mean_ci。 「ある特定の県の死亡率の幅」を知りたいなら obs_ci。 政策評価では mean_ci、 個別予測では obs_ci を使う。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
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 を読み込み、 12 年分(2012-2023)をパネル形式で保持。 後段の年度別比較・横断面/時系列の対比に使う。
📥 入力例: data/raw/SSDSE-B-2026.csv(encoding=cp932, skiprows=[1]) 全 564 行(12 年 × 47 県)
📤 実行例(実測) 95% CI for coefficients: 0 1 const -6.573784 -3.762576 高齢化率 0.565729 0.654249 mean mean_se ... obs_ci_lower obs_ci_upper 0 14.969117 0.079054 ... 13.954481 15.983753 1 16.315378 0.107901 ... 15.290017 17.340739 2 16.178805 0.104313 ... 15.154952 17.202659 3 12.668065 0.089014 ... 11.650088 13.686042 4 18.657422 0.179543 ... 17.592103 19.722740 [5 rows x 6 columns]
💬 読み方: パネルデータ形式(年度×都道府県)で保持しておくと、 後で固定効果・ランダム効果・年度トレンドなど高度な分析にも転用できる。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
import pandas as pd

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

print(df.shape)             # (47, 112)
print(df['Prefecture'].nunique())  # 47
print(df.iloc[:3, :5])

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

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

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

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

▼ コード解説(散布図プロット(matplotlib))
🎯 解説: matplotlib で「高齢化率 vs 死亡率」の散布図を描画し、 回帰直線を重ねる。 視覚化により「直線関係か」「外れ値はあるか」を回帰前に診断できる。
📥 入力例: 高齢化率(x)と死亡率(y)の 47 点 単回帰の傾き 0.610、 切片 -5.17
📤 実行例: scatter_regression.png 出力 47 点がほぼ直線状に並ぶ 奈良県のみ若干下方に外れる
💬 読み方: 散布図が直線状なら線形回帰の仮定が妥当。 曲線パターンなら多項式回帰や log 変換、 ヘテロな分散なら加重最小二乗を検討。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
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['Prefecture'], (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 でも高齢化率と死亡率の関係は帯が極めて狭く、 関係の存在は強固。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
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['死亡率']],
                 tick_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 県を最低限ラベリングすると親切です。

🐍 Python 実装の徹底解説 — SSDSE-B-2026 で 8 パターン

パターン 1: statsmodels.OLS(最も標準的)

📥 入力例(SSDSE-B-2026 の 2023 年・47 都道府県から 3 行) 都道府県 A1101(総人口) A1303(65歳以上人口) A4200(死亡数) 北海道 5,092,000 1,681,000 75,120 東京都 14,086,000 3,205,000 137,241 沖縄県 1,468,000 350,000 15,110 …(全 47 行)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
import pandas as pd
import statsmodels.api as sm
import numpy as np

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df = df[df['SSDSE-B-2026'] == 2023].reset_index(drop=True)  # 2023 年度 47 県
df['aging_rate'] = df['A1303'] / df['A1101'] * 100
df['death_rate'] = df['A4200'] / df['A1101'] * 1000

X = sm.add_constant(df['aging_rate'])
y = df['death_rate']
result = sm.OLS(y, X).fit()
print(result.summary())
📤 実行例(実測) OLS Regression Results ============================================================================== Dep. Variable: death_rate R-squared: 0.945 Model: OLS Adj. R-squared: 0.944 Method: Least Squares F-statistic: 770.5 Date: Sun, 16 Aug 2026 Prob (F-statistic): 5.95e-30 Time: 19:18:25 Log-Likelihood: -32.857 No. Observations: 47 AIC: 69.71 Df Residuals: 45 BIC: …(以下略)

パターン 2: sklearn.LinearRegression(ML 向き)

1
2
3
4
5
6
7
8
9
from sklearn.linear_model import LinearRegression

X = df[['aging_rate']].values
y = df['death_rate'].values
model = LinearRegression()
model.fit(X, y)
print('β0:', model.intercept_, 'β1:', model.coef_[0])
print('R²:', model.score(X, y))
print('predictions[:5]:', model.predict(X[:5]))
📤 実行例(実測) β0: -5.168180022273848 β1: 0.6099887943249765 R²: 0.9448211318778427 predictions[:5]: [14.96911698 16.31537802 16.1788053 12.66806476 18.65742168]

パターン 3: numpy.polyfit(多項式回帰)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
x = df['aging_rate'].values
y = df['death_rate'].values

# 2 次多項式
coefs = np.polyfit(x, y, deg=2)
print('y =', coefs[0], 'x² +', coefs[1], 'x +', coefs[2])
# 当てはめの良さ
y_pred = np.polyval(coefs, x)
ss_res = ((y - y_pred)**2).sum()
ss_tot = ((y - y.mean())**2).sum()
print('R²:', 1 - ss_res/ss_tot)
📤 実行例(実測) y = 0.016830917346554335 x² + -0.4222381601605793 x + 10.460389183001672 R²: 0.9599838373536538

パターン 4: 残差プロット(diagnostics)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import matplotlib.pyplot as plt

# OLS の結果から残差を取得
result = sm.OLS(y, sm.add_constant(df['aging_rate'])).fit()
residuals = result.resid
fitted = result.fittedvalues

fig, axes = plt.subplots(1, 2, figsize=(12, 4))

# 残差 vs 予測値
axes[0].scatter(fitted, residuals)
axes[0].axhline(0, color='red', linestyle='--')
axes[0].set_xlabel('Fitted')
axes[0].set_ylabel('Residuals')
axes[0].set_title('Residuals vs Fitted')

# Q-Q プロット
from scipy import stats
stats.probplot(residuals, dist='norm', plot=axes[1])

# 沖縄県のラベル付け
for i, pref in enumerate(df['Prefecture']):
    if abs(residuals.iloc[i]) > 1.5:
        axes[0].annotate(pref, (fitted.iloc[i], residuals.iloc[i]))

plt.tight_layout()
plt.savefig('residuals.png', dpi=100)

パターン 5: Cook's distance で影響力の高い県を検出

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
from statsmodels.stats.outliers_influence import OLSInfluence

infl = OLSInfluence(result)
cooks_d = infl.cooks_distance[0]
threshold = 4 / len(df)

# 閾値超え県
high_inf = df[cooks_d > threshold]
print(high_inf[['Prefecture','aging_rate','death_rate']])
print(f'Cook D 閾値: {threshold:.3f}')
# 沖縄県・東京都などが上位
📤 実行例(実測) Prefecture aging_rate death_rate 1 青森県 35.219595 17.597128 4 秋田県 39.059081 19.165208 12 東京都 22.753088 9.743078 28 奈良県 32.638889 13.095679 46 沖縄県 23.841962 10.292916 Cook D 閾値: 0.085

パターン 6: VIF で多重共線性チェック

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
from statsmodels.stats.outliers_influence import variance_inflation_factor

features = ['aging_rate', 'A1101', 'B4101', 'A4101']
X = df[features].assign(_const=1)

vif_df = pd.DataFrame({
    'feature': features,
    'VIF': [variance_inflation_factor(X.values, i) for i in range(len(features))]
})
print(vif_df)
# VIF > 10 の変数があれば多重共線性
📤 実行例(実測) feature VIF 0 aging_rate 2.824992 1 A1101 182.338543 2 B4101 1.909999 3 A4101 190.308310

パターン 7: Ridge / Lasso 回帰(正則化)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
from sklearn.linear_model import Ridge, Lasso
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import LeaveOneOut, cross_val_score

features = ['aging_rate', 'A1101', 'B4101', 'A4101']
X = df[features]
y = df['death_rate']

scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

# Ridge
for alpha in [0.01, 0.1, 1.0, 10.0]:
    ridge = Ridge(alpha=alpha)
    cv_scores = cross_val_score(ridge, X_scaled, y, cv=LeaveOneOut(), scoring='neg_mean_squared_error')
    rmse = (-cv_scores.mean()) ** 0.5
    print(f'Ridge alpha={alpha}: LOOCV RMSE = {rmse:.4f}')
📤 実行例(実測) Ridge alpha=0.01: LOOCV RMSE = 0.5578 Ridge alpha=0.1: LOOCV RMSE = 0.5603 Ridge alpha=1.0: LOOCV RMSE = 0.5672 Ridge alpha=10.0: LOOCV RMSE = 0.7116

パターン 8: 予測区間と信頼区間

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
from statsmodels.sandbox.regression.predstd import wls_prediction_std

result = sm.OLS(y, sm.add_constant(df['aging_rate'])).fit()

# 予測区間 (新観測値) と信頼区間 (平均) の両方
prstd, iv_l, iv_u = wls_prediction_std(result)

# 信頼区間(平均の不確実性)
ci = result.get_prediction(sm.add_constant(df['aging_rate']))
ci_df = ci.summary_frame(alpha=0.05)
# mean_ci_lower / upper: 平均の 95% CI
# obs_ci_lower / upper: 個別観測の 95% PI

📊 SSDSE-B-2026 で実際に走らせた結果(参考値)

SSDSE-B-2026 の 47 都道府県データで、 各モデルを実行した時の数値を表にしました。 実装の検証用にご利用ください。

単回帰: 死亡率 ← 高齢化率

項目備考
n47都道府県
β₀ (切片)約 -5.17標準誤差 約 0.70
β₁ (高齢化率)約 0.610標準誤差 約 0.022、 p < 0.001
0.9448非常に高い当てはまり
Adjusted R²0.9436
F 統計量約 771p < 0.001
残差の標準誤差約 0.50RSE
Durbin-Watson約 1.63独立性 OK
AIC約 70
BIC約 73

重回帰: 死亡率 ← 高齢化率 + 出生率

項目備考
β₁ (高齢化率)約 0.609p < 0.001、 単回帰とほぼ同じ
β₂ (出生率)約 -0.010p = 0.94、 有意でない(追加説明力なし)
0.9448単回帰 0.9448 と変わらず
Adjusted R²0.9423変数追加でむしろ低下

重回帰: 死亡率 ← 高齢化率 + 沖縄ダミー

項目備考
β₁ (高齢化率)約 0.626p < 0.001
β₂ (沖縄ダミー)約 +1.07沖縄は予測より約 1.1 高い、 p = 0.046
0.9497沖縄ダミー追加で微増

🔎 深掘り: Frisch–Waugh–Lovell 定理 — 偏回帰係数の正体

重回帰の偏回帰係数 $\beta_j$ は「他の変数を固定したまま $x_j$ を 1 単位変えたときの $y$ の変化」と表現されますが、 数学的にはもっと美しい定理があります。 Frisch–Waugh–Lovell 定理(FWL 定理)です。

定理の主張

「重回帰 $y = X\beta + \varepsilon$ における $x_j$ の係数 $\beta_j$ は、 以下の 3 ステップで得られる単回帰の係数と一致する」:

  1. $y$ を $x_j$ 以外の説明変数で回帰し、 残差 $\tilde{y}$ を取得
  2. $x_j$ を $x_j$ 以外の説明変数で回帰し、 残差 $\tilde{x}_j$ を取得
  3. $\tilde{y}$ を $\tilde{x}_j$ で単回帰した係数が $\beta_j$ に等しい

SSDSE-B-2026 での実証

SSDSE-B-2026 で「死亡率 ← 高齢化率 + 出生率」 の重回帰を例に。 高齢化率の偏回帰係数を FWL で求めると:

📥 入力例(SSDSE-B-2026 の 2023 年・47 都道府県から 3 行) 都道府県 A1101(総人口) A1303(65歳以上人口) A4101(出生数) A4200(死亡数) 北海道 5,092,000 1,681,000 24,430 75,120 東京都 14,086,000 3,205,000 86,348 137,241 沖縄県 1,468,000 350,000 12,549 15,110 …(全 47 行)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import pandas as pd
import statsmodels.api as sm

# aging_rate / birth_rate / death_rate はこのあとのブロックで作っている派生列。
# ここでも同じ定義で用意しておく(SSDSE-B-2026 に同名の列は無い)
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df = df[df['SSDSE-B-2026'] == 2023].reset_index(drop=True)
df['aging_rate'] = df['A1303'] / df['A1101'] * 100     # 高齢化率 (%)
df['birth_rate'] = df['A4101'] / df['A1101'] * 1000    # 出生率 (人口千人あたり)
df['death_rate'] = df['A4200'] / df['A1101'] * 1000    # 死亡率 (人口千人あたり)

import statsmodels.api as sm

# Step 1: 死亡率 を 出生率 で回帰した残差
res_y = sm.OLS(df['death_rate'], sm.add_constant(df['birth_rate'])).fit().resid

# Step 2: 高齢化率 を 出生率 で回帰した残差
res_x = sm.OLS(df['aging_rate'], sm.add_constant(df['birth_rate'])).fit().resid

# Step 3: 残差同士で単回帰
fwl = sm.OLS(res_y, res_x).fit()
print('FWL の β:', fwl.params[0])

# 通常の重回帰
full = sm.OLS(df['death_rate'], sm.add_constant(df[['aging_rate','birth_rate']])).fit()
print('重回帰の β_aging_rate:', full.params['aging_rate'])

# 両者は数値的に一致する
📤 実行例(実測) FWL の β: 0.6087488785721734 重回帰の β_aging_rate: 0.608748878572177

意味するところ: 偏回帰係数 $\beta_j$ は「他の変数の影響を $y$ と $x_j$ の両方から取り除いた残差の関係」 を捉えている。 これが「他の変数を固定したまま」 の数学的意味です。 SSDSE-B-2026 で「高齢化率の効果」 を語るとき、 必ず「出生率を取り除いた後の効果」 と限定的に言うべきだとわかります。

📊 多重回帰の幾何学的理解

単回帰の場合、 回帰直線は 2 次元平面上の直線です。 重回帰では「平面」 や「超平面」 になります。 SSDSE-B-2026 で 3 変数(高齢化率 + 出生率 → 死亡率)の重回帰を考えると、 3 次元空間中の平面が回帰結果です。

幾何学的最小化

OLS は「観測点から回帰平面への垂直距離の二乗和を最小化」 する平面を選びます。 これは行列で書くと:

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

この公式は SSDSE-B-2026 のサイズ(47 ×3)でも、 100 万 ×100 列でも同じ形。 ただし $X^\top X$ の逆行列が計算可能であることが前提(フルランク = 多重共線性なし)。

SSDSE-B-2026 で確認

📥 入力例(SSDSE-B-2026 の 2023 年・47 都道府県から 3 行) 都道府県 A1101(総人口) A1303(65歳以上人口) A4101(出生数) A4200(死亡数) 北海道 5,092,000 1,681,000 24,430 75,120 東京都 14,086,000 3,205,000 86,348 137,241 沖縄県 1,468,000 350,000 12,549 15,110 …(全 47 行)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import pandas as pd
import statsmodels.api as sm

# aging_rate / birth_rate / death_rate はこのあとのブロックで作っている派生列。
# ここでも同じ定義で用意しておく(SSDSE-B-2026 に同名の列は無い)
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df = df[df['SSDSE-B-2026'] == 2023].reset_index(drop=True)
df['aging_rate'] = df['A1303'] / df['A1101'] * 100     # 高齢化率 (%)
df['birth_rate'] = df['A4101'] / df['A1101'] * 1000    # 出生率 (人口千人あたり)
df['death_rate'] = df['A4200'] / df['A1101'] * 1000    # 死亡率 (人口千人あたり)

import numpy as np

X = df[['aging_rate', 'birth_rate']].values
X = np.column_stack([np.ones(len(X)), X])  # 切片を追加
y = df['death_rate'].values

# 行列計算で β を求める
beta = np.linalg.inv(X.T @ X) @ X.T @ y
print('行列計算の β:', beta)

# statsmodels の結果と一致するはず
import statsmodels.api as sm
sm_result = sm.OLS(y, X).fit()
print('statsmodels の β:', sm_result.params)

🧠 解釈の深掘り — 「他の変数を固定して」 の真意

「他の変数を固定して」 という表現は便利だが誤解を招きやすい。 SSDSE-B-2026 で 「高齢化率を固定して出生率の効果を見る」と言うとき、 「実際にどうやって固定するのか?」 が問題。

解釈 1: 統計的固定

回帰の偏回帰係数は、 「データの中で偶然似た高齢化率を持つ県同士で比較したときの平均的な関係」 を表す。 SSDSE-B-2026 では、 全 47 県の中で「高齢化率 30% の県」 が複数存在するわけではないため、 線形補間が前提となる。

解釈 2: 因果的固定

「もし高齢化率を強制的に変えずに、 出生率だけ介入したら?」 という反事実(counterfactual)の解釈は、 統計的固定とは別物。 因果推論の枠組み(DAG、 do-calculus)が必要。 SSDSE-B-2026 のような観察データでは、 因果的固定は強い仮定なしには言えない。

解釈 3: 操作可能性

そもそも「高齢化率」 は政策で短期的に変えられない変数。 「介入できない変数の係数」 は予測モデルとしては有用だが、 「政策レバー」 とは言えない。 SSDSE-B-2026 で政策評価をするなら、 「一般診療所数 / 人口比率」 のような介入可能な変数を選ぶべき。

教訓: 回帰係数の解釈には 「統計的固定」「因果的固定」「操作可能性」 の 3 階層を区別する必要がある。 SSDSE-B-2026 のような観察研究では、 多くの場合「統計的固定の関係」 までしか言えない。

🏛 ツール別 回帰分析の書き方

同じ「死亡率 ← 高齢化率」 単回帰を各ツールで書くと:

ツール書き方備考
statsmodelssm.OLS(y, sm.add_constant(X)).fit()統計推論向き、 summary() が便利
scikit-learnLinearRegression().fit(X, y)ML パイプライン向き、 fit/predict 統一
numpynp.linalg.lstsq(X, y, rcond=None)低レベル、 学習向け
scipyscipy.stats.linregress(x, y)1 変数のみ、 r 値も取得可能
R (base)lm(death_rate ~ aging_rate, data=df)summary() で完全な結果
SASPROC REG; MODEL y = x;業界標準だが古め
SPSS分析 → 回帰 → 線型 (GUI)非プログラマ向け
Excelデータ → 分析 → 回帰分析 (アドイン)結果テーブル直接出力
BigQuery MLCREATE MODEL ... OPTIONS(model_type='linear_reg')SQL で機械学習
Polars + scikit-learndf.to_pandas() → LinearRegression大規模データを Polars で前処理後

📋 統計レポートテーブル(APA スタイル)

SSDSE-B-2026 で実施した重回帰結果を、 APA 7th edition 形式で報告する例。

変数係数 βSEtp95% CI
(切片)-5.071.49-3.41= .001[-8.08, -2.07]
高齢化率 (%)0.6090.02821.61< .001[0.552, 0.666]
出生率 (‰)-0.0100.134-0.07= .943[-0.279, 0.260]

: 応答変数は死亡率 (人口千人あたり)。 n = 47 都道府県。 R² = .9448、 adjusted R² = .9423、 F(2, 44) = 376.7, p < .001。 残差の標準誤差 = 0.50。

本文での記述例

"高齢化率は死亡率と有意な正の関連を示した(β = 0.609、 95% CI [0.552, 0.666]、 p < .001)。 一方、 出生率の偏回帰係数は有意ではなく(β = -0.010、 95% CI [-0.279, 0.260]、 p = .943)、 高齢化率を統制すると追加の説明力を持たなかった。 死亡率の分散の 94.2% を説明できた(adjusted R² = .9423)。"

🎓 回帰分析マスター 6 ステップ — SSDSE-B-2026 を題材に

  1. Step 1: SSDSE-B-2026 で散布図を 5 ペア描き、 線形性を視覚的に判定。
  2. Step 2: 単回帰を statsmodels.OLS で実行し、 R²・係数・p 値の意味を理解。
  3. Step 3: 残差プロット・Q-Q プロット・Cook's distance で OLS の仮定を検証。
  4. Step 4: 重回帰へ拡張し、 偏回帰係数の意味を Frisch–Waugh–Lovell 定理で理解。
  5. Step 5: VIF で多重共線性を検出し、 Ridge / Lasso で正則化。
  6. Step 6: LOOCV で予測誤差を見積もり、 因果推論との違いを認識。

📈 scikit-learn vs statsmodels — 使い分け指針

観点scikit-learnstatsmodels
推論(係数の p 値、 信頼区間)提供されない(再実装が必要)充実(summary() で全部出る)
大規模データSGD などで高速対応OLS は中規模まで
パイプライン(前処理 → モデル → 予測)Pipeline で統一個別実行が前提
正則化Ridge/Lasso/ElasticNet 標準搭載Ridge は statsmodels.regression.linear_model.OLS の fit_regularized() に
クロスバリデーションcross_val_score / GridSearchCV標準では未提供(手動実装)
分散構造(GLS, WLS)限定的豊富
SSDSE-B-2026 (n=47) での推奨正則化や CV を使うとき仮説検定・係数解釈を重視するとき

結論: SSDSE-B-2026 のような小サンプル統計分析では statsmodels が第一選択。 機械学習パイプラインや大規模データでは scikit-learn が第一選択。 両者を組み合わせる(前処理 sklearn、 推論 statsmodels)こともよくある。

⚠️ よくある落とし穴

❌ 因果と相関の混同
回帰係数が大きく有意でも、それは「条件付き相関」。 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['SSDSE-B-2026'].value_counts() df.groupby('SSDSE-B-2026')['Prefecture'].nunique()
📤 実行例(実測) 行列計算の β: [-5.07427905 0.60874888 -0.00955935] statsmodels の β: [-5.07427905 0.60874888 -0.00955935]
💬 読み方: バランスドパネル(全期間で全個体が観測)なら、 固定効果回帰がそのまま使える。 アンバランスなら欠損年度の補完か期間を絞る必要がある。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 年度別の行数と県数
print(df.groupby('SSDSE-B-2026').size())
print(df.groupby('SSDSE-B-2026')['Prefecture'].nunique())  # 各年 47 のはず

# 2023 年に絞り、 比率系を作る
df = df[df['SSDSE-B-2026'] == 2023].reset_index(drop=True)
df['食料費比率'] = df['L322101'] / df['L3221']
df['住居費比率'] = df['L322102'] / df['L3221']
df['教育費比率'] = df['L322108'] / df['L3221']
print(df[['Prefecture','食料費比率','住居費比率','教育費比率']].head())

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

▼ コード解説(欠損値のチェック)
🎯 解説: df.isna().sum() で各列の欠損数を一括確認。 欠損が多い列は回帰から外すか補完が必要。 isna 計上は前処理の必須ステップ。
📥 入力例: df 全体(564 行 × 112 列)
📤 実行例(実測) SSDSE-B-2026 2023 47 dtype: int64 SSDSE-B-2026 2023 47 Name: Prefecture, dtype: int64 Prefecture 食料費比率 住居費比率 教育費比率 0 北海道 0.250401 0.090034 0.023278 1 青森県 0.295777 0.054801 0.025489 2 岩手県 0.274664 0.062297 0.022604 3 宮城県 0.274382 0.071722 0.036804 4 秋田県 0.287130 0.043935 0.015863
💬 読み方: 公的データ SSDSE は欠損が極めて少なく、 ほぼそのまま分析可能。 ただし「平均寿命」など一部の指標は公表頻度が低く、 欠損が混入する場合がある。
1
2
3
4
5
6
# どの列に欠損があるか
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 で上位・下位を抽出
📤 実行例(実測) Series([], dtype: int64) SSDSE-B-2026 int64 A1101 int64 A110101 int64 A110102 int64 A1102 int64 A110201 int64 A110202 int64 A1301 int64 A130101 int64 A130102 int64 dtype: object
💬 読み方: 食料費比率(エンゲル係数)は所得水準の代理指標。 SSDSE-B-2026 では西日本の一部や大都市圏で高めに出るなど、 家計構造の地域差を反映する。
1
2
3
4
5
6
7
# 食料費比率の上位/下位 5 県
print(df.nlargest(5, '食料費比率')[['Prefecture','食料費比率']])
print(df.nsmallest(5, '食料費比率')[['Prefecture','食料費比率']])

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

4) 相関と散布図行列

▼ コード解説(相関行列の計算と表示)
🎯 解説: 主要指標 6 個の相関行列を計算し、 round(2) で見やすく表示。 多重共線性のチェックや変数選択の指針になる。 相関 0.9 を超えるペアは要警戒。
📥 入力例: vars_ = ['食料費比率','住居費比率','教育費比率','高齢化率','出生率','死亡率'] df[vars_].corr()
📤 実行例(実測) Prefecture 食料費比率 37 愛媛県 0.318177 26 大阪府 0.313524 27 兵庫県 0.307132 1 青森県 0.295777 22 愛知県 0.294157 Prefecture 食料費比率 20 岐阜県 0.238931 43 大分県 0.243573 7 茨城県 0.244528 23 三重県 0.244716 35 徳島県 0.249016 Prefecture 食料費比率 food_z 26 大阪府 0.313524 2.296417 37 愛媛県 0.318177 2.561484
💬 読み方: 相関 0.97 は「ほぼ同じ情報」を意味し、 重回帰では片方のみ採用するのが原則。 一方、 教育費比率と食料費比率の相関は弱く(+0.15)、 家計内予算の配分は独立性が高い。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
vars_ = ['食料費比率','住居費比率','教育費比率','高齢化率','出生率','死亡率']
df['高齢化率'] = df['A1303'] / df['A1101'] * 100
df['出生率']   = df['A4101'] / df['A1101'] * 1000
df['死亡率']   = df['A4200'] / df['A1101'] * 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
📤 実行例(実測) 食料費比率 住居費比率 教育費比率 高齢化率 出生率 死亡率 食料費比率 1.00 0.10 0.15 -0.23 0.21 -0.17 住居費比率 0.10 1.00 -0.20 -0.06 0.26 -0.00 教育費比率 0.15 -0.20 1.00 -0.67 0.26 -0.69 高齢化率 -0.23 -0.06 -0.67 1.00 -0.61 0.97 出生率 0.21 0.26 0.26 -0.61 1.00 -0.60 死亡率 -0.17 -0.00 -0.69 0.97 -0.60 1.00
💬 読み方: p 値 < 0.001 で帰無仮説(無相関)を強く棄却。 SSDSE-B のような実データでは標本サイズが小さくても、 真の関係が強ければ統計的有意性は十分に得られる。
1
2
3
4
5
6
7
8
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])
📤 実行例(実測) 食料費比率 vs 高齢化率: r = -0.230, p = 0.1199 ============================================================================== coef std err t P>|t| [0.025 0.975] ------------------------------------------------------------------------------ const 0.3114 0.024 12.853 0.000 0.263 0.360 高齢化率 -0.0012 0.001 -1.585 0.120 -0.003 0.000 ==============================================================================

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

🌍 他分野での類似概念

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

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

回帰分析は経済学の賃金関数、 疫学のリスク評価、 機械学習の教師あり学習、 マーケティングの広告寄与度、 製造業の歩留まり要因分析、 政策評価の準実験まで、 ほぼ全ての応用領域で 共通言語 として再登場します。 用語そのものより、 「いま自分が見ている SSDSE-B-2026 の散布図のどの関係を、 どの分野の文脈で語ろうとしているか」を意識すると、 回帰の発想が自然に広がります。 たとえば SSDSE-B-2026 の県別・世帯消費支出と高齢化率の関係は 経済学の家計消費関数、 県別死亡率と高齢化率は 疫学のコホート的視点、 県別消費支出と気温は 政策評価的アトリビューション として読み解けます。

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

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

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

⚠️ 回帰でハマる落とし穴 5 つ — SSDSE-B-2026 で発生する例

落とし穴 1: 外挿(extrapolation)の罠

SSDSE-B-2026 で「高齢化率 22–40%」の範囲で回帰式を作った後、 「高齢化率 5% の架空国」に当てはめて死亡率を予測すると、 範囲外なので極端な値が出る。 切片 -5.17 に 0.610 × 5 を足すと -2.1 という不可能な(負の死亡率)値。

対処: 予測時には説明変数の値が訓練範囲内か必ずチェック。

落とし穴 2: スケール無視で係数比較

SSDSE-B-2026 で「人口(万人単位)」と「高齢化率(%)」を混ぜると、 係数の大きさが単位に依存する。 「人口の係数 0.001」と「高齢化率の係数 0.61」を直接比較してはいけない。

対処: 標準化(z-score)してから回帰、 または標準化係数(標準化偏回帰係数)を報告。

落とし穴 3: 因果と相関の混同

SSDSE-B-2026 で「高齢化率 → 死亡率」 の係数が有意でも、 これは「相関構造の表現」であって「高齢化率を下げれば死亡率が下がる」とは限らない。 介入の意思決定に使うには因果推論の枠組みが必要。

対処: 「回帰係数は予測モデルの説明であり、 介入効果ではない」と明記。 介入評価には DAG、 IV、 RCT が必要。

落とし穴 4: 過学習(overfitting)

SSDSE-B-2026 は n=47 と小さいので、 説明変数を 10 個以上入れると過学習。 訓練データで R²=0.99 でも、 新しい県(架空)に予測すると外れる。

対処: 説明変数を 3–5 個に抑える。 または LOOCV (Leave-One-Out CV) で予測誤差を見積もる。 Ridge/Lasso で正則化。

落とし穴 5: 等分散性違反(heteroscedasticity)

SSDSE-B-2026 で「着工新設住宅戸数 (H1800) ← 総人口 (A1101)」を回帰すると、 大きな県ほど残差の散らばりが大きくなる傾向(ファネル形状)。 これは OLS の前提違反。

対処: (1) y や x を対数変換、 (2) WLS(重み付き最小二乗)、 (3) ロバスト標準誤差(HC3 estimator)を使う。 sklearn では statsmodels.OLS(...).fit(cov_type='HC3')

📝 レポート・論文での回帰結果の書き方

回帰分析の結果をレポートに記載する際は、 「係数 (SE) [95% CI] / R² / N」 の組み合わせを最低限報告します。 SSDSE-B-2026 を用いた例:

方法(Methods)セクション例

SSDSE-B-2026(n = 47 都道府県)を用い、 人口千人あたり死亡率を応答変数、 高齢化率を主要な説明変数とする線形回帰分析を実施した。 推定は通常最小二乗法(OLS)で行い、 異分散ロバスト標準誤差(HC3)を用いて係数の信頼区間を算出した。 解析には Python 3.11 と statsmodels 0.14 を使用した。

結果(Results)セクション例

高齢化率は死亡率と有意な正の関連を示した(β = 0.610、 SE = 0.022、 95% CI [0.566, 0.654]、 t = 27.8、 p < .001)。 単回帰モデルの決定係数は R² = 0.9448(adjusted R² = 0.9436)、 残差の標準誤差は 0.50 であった(n = 47)。 高齢化率が 1 ポイント上昇すると、 死亡率(人口千人あたり)は平均で 0.61 上昇すると推定される。

表 / 図のキャプション例

表 1. 死亡率を応答変数とする線形回帰モデルの推定結果(SSDSE-B-2026、 n = 47)。
図 1. 高齢化率と死亡率の散布図および回帰直線(SSDSE-B-2026)。 奈良県は回帰直線より低い死亡率を示す外れ値である。

🏛️ 応用事例 — SSDSE-B-2026 を用いた回帰分析 4 本

事例 1: 健康指標の地域差を説明する

SSDSE-B-2026 で「死亡率 ← 高齢化率 + 一般診療所数/人口 (I5102)」 を重回帰すると、 「高齢化率は強い正の効果(支配的)」 「一般診療所密度の効果は弱い」 が観察される。 ただし因果推論ではなく相関構造の表現として報告する。

事例 2: 教育規模のスケーリング

SSDSE-B-2026 で「大学学生数 (E6302) ← 総人口 (A1101) + 大学数 (E6102)」 を回帰すると、 人口規模と大学の集積が学生数をどれだけ説明するかを量化できる。 ただし東京への大学集中による外れ値(自己選択的な集積)に注意。

事例 3: 人口流入の要因分析

SSDSE-B-2026 で「転入超過率 ← 高齢化率」を回帰すると(R² ≈ 0.63)、 「高齢化率が低い(=若い)県ほど転入超過が大きい」関係が定量化できる。 東京一極集中の構造を係数で表現でき、 地方創生政策の効果測定の出発点になる。

事例 4: 医療キャパシティの需要予測

SSDSE-B-2026 で「一般病院数 (I510120) ← 総人口 (A1101) + 65歳以上人口 (A1303)」 を重回帰すると、 人口規模と高齢人口が医療施設数をどれだけ規定するかを重みづけできる。 地域医療計画や病床配分の需要推計に応用できる。

❓ よくある質問(FAQ)

Q. 線形回帰と重回帰の違いは?

「線形」 vs 「重」は別軸。 線形回帰は「説明変数と応答変数の関係が一次式」(曲線でない)。 重回帰は「説明変数が複数」。 SSDSE-B-2026 で「死亡率 ← 高齢化率」は「線形・単回帰」、 「死亡率 ← 高齢化率 + 出生率」は「線形・重回帰」。 「死亡率 ← 高齢化率²」は「非線形・単回帰」だが係数の意味では線形回帰の枠組み(多項式回帰)。

Q. p 値はいくつで有意?

慣習的に p < 0.05 で有意とすることが多いが、 サンプル数や仮説の事前情報、 多重比較補正の必要性に応じて 0.01 や 0.005 を採用する場合もある。 SSDSE-B-2026 は n=47 と小さいので、 p < 0.05 でも厳しめに評価する。 一方で「p 値だけで判断しない、 効果量(係数の大きさ)と信頼区間も併記する」 のが APA や統計学会の最新推奨。

Q. R² と adjusted R² の違いは?

R² は「説明変数を増やすと必ず上がる」性質を持つため、 説明変数の数で罰則を入れた adjusted R² を使うのが一般的。 SSDSE-B-2026 で 1 変数モデルの R²=0.945 に不必要な変数を追加しても R² はほとんど上がらず、 adjusted R² はむしろ 0.94 前後まで下がる。 「説明力が上がったか、 ノイズを拾っただけか」 を判定できる。

Q. AIC と BIC はどちらを使う?

予測重視なら AIC(赤池情報量規準)、 真のモデル選択重視なら BIC(ベイズ情報量規準)。 BIC は AIC より説明変数追加への罰則が大きい。 SSDSE-B-2026 のような小サンプルでは AICc(小サンプル補正版)を推奨。

Q. クロスバリデーションは小サンプルでも有効?

SSDSE-B-2026 の n=47 では K-fold(K=5 や 10)よりも LOOCV(Leave-One-Out)が無難。 1 県を除いて 46 県でモデルを作り、 除いた 1 県を予測 → 47 回繰り返し → 平均誤差を取る。 各 fold で訓練データが十分残るのが利点。

Q. 回帰直線と相関係数の関係は?

単回帰で標準化(z-score)後の係数 = 相関係数 r。 SSDSE-B-2026 で「死亡率(標準化) ← 高齢化率(標準化)」の係数は、 ピアソン相関係数 r と数値が一致。 重回帰では「偏相関」と「偏回帰係数」の関係に拡張される。

🕰 回帰分析の歴史と発展

年代出来事意味
1805Legendre / Gauss が最小二乗法を提唱OLS の数学的基盤。 天文観測の誤差処理から発生。
1885Galton が「平均への回帰」を提唱「Regression」 という用語の由来。 親子の身長の関係から。
1908Yule の重回帰説明変数複数化、 偏回帰係数の解釈確立。
1933Fisher の F 統計量回帰係数の同時有意性検定の基礎。
1960Hoerl の Ridge 回帰L2 正則化の登場。 多重共線性対策。
1996Tibshirani の LassoL1 正則化で変数選択。 現代 ML の基礎。
2008scikit-learn 公開SSDSE-B-2026 のような表データに対する回帰が誰でも 3 行で書けるように。
2010-因果推論ブーム(Pearl, Hernán)「相関 ≠ 因果」 への意識が学会で標準化。
2020-大規模 LLM 時代の回帰表データでは未だ XGBoost / 線形回帰が最強の場面が多い。 SSDSE-B-2026 のような 47 行データでは線形回帰が最適。

🌍 他分野での「回帰」類似概念

分野類似概念類似点 / 違い
計量経済学パネルデータ回帰SSDSE-B-2026 を時系列で縦に積む = パネル。 固定効果モデル(fixed effect)で県固有の影響を制御。
機械学習線形回帰モデル同じ式だが、 予測精度を最大化することに重きを置く(解釈は二の次)。
因果推論線形構造方程式モデル回帰式に因果方向の仮定を加えたもの。
物理学線形応答理論外力 x に対する応答 y の比例係数 β。 SSDSE の各指標間の関係も「社会的線形応答」と見なせる。
金融工学CAPM (資本資産価格モデル)株式リターン = α + β × 市場リターン。 完全に線形回帰の形。
生物統計線形混合モデル (LMM)個体差を変量効果として組み込み。 SSDSE で「県差」を変量効果にする発想と同型。

🎯 練習問題 — SSDSE-B-2026 で書く回帰 10 問

  1. SSDSE-B-2026 で「死亡率 ← 高齢化率」の単回帰を実行し、 R² と回帰係数を報告せよ。
  2. 同じデータで「死亡率 ← 高齢化率 + 出生率」の重回帰を実行し、 単回帰との R² の差を述べよ。
  3. 残差プロットを描き、 残差が最大/最小の県を特定せよ。 奈良県が下方の外れ値であることを確認せよ。
  4. 「沖縄ダミー」を追加した重回帰モデルを作り、 ダミー変数の係数を解釈せよ。
  5. 「消費支出 (L3221) ← 高齢化率」 の単回帰を実行し、 結果を解釈せよ。
  6. 「一般診療所数 (I5102) ← 人口」の単回帰と、 「一般診療所数/人口比率」 の差を実証的に考察せよ。
  7. 説明変数を log 変換した場合の係数を解釈せよ(弾力性)。
  8. 多重共線性が疑われる 3 列を選び、 VIF を計算せよ。
  9. 5-fold CV と LOOCV で予測誤差を比較せよ(n=47)。
  10. Ridge 回帰の α パラメータを 0.01–10 で動かし、 係数の収縮を観察せよ。

🗺 概念マップ

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

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

🔗 隣接手法への橋渡し

「回帰分析」は単独で完結する手法ではなく、 隣接領域と連携することで真価を発揮する。

47 都道府県の人口データから「総人口 → 一般診療所数」の影響を定量化するように、 「回帰分析」は 連続値どうしの関係 を数値で表現するパイプラインの中核となる。

🌳 非線形回帰への橋渡し

🌳 非線形回帰への橋渡し

線形回帰の枠を超える場合の選択肢。 SSDSE-B-2026 でも残差プロットで曲線パターンが見えたら検討。

① 多項式回帰

説明変数の高次項(x², x³)を入れる。 SSDSE-B-2026 で「高齢化率²」 を入れると、 高齢化率が極端に高い県で死亡率がさらに加速する効果を捉えられる。 ただし過学習しやすい。

② スプライン回帰

説明変数の範囲を区分に分けて、 各区間で別の多項式を当てる。 SSDSE-B-2026 で「人口」のように分布が偏った変数を扱うのに有用。

③ 決定木 / ランダムフォレスト

線形性を仮定せず、 階層的な if-then ルールで予測。 SSDSE-B-2026 で「人口 > 500万なら東京、 そうでなく高齢化率 > 35% なら…」 のような分岐。

④ Gradient Boosting (XGBoost / LightGBM)

弱学習器の決定木を順次足していく。 SSDSE-B-2026 の n=47 では過学習しやすいが、 縦に時系列で積めば十分。

⑤ ガウス過程回帰

予測値だけでなく不確実性も推定。 SSDSE-B-2026 のような小サンプルで「予測区間」 を厳密に出したいときに有用。

注意: SSDSE-B-2026 のような小サンプル・低次元データでは、 線形回帰が依然として最強 の選択肢である場合が多い。 非線形手法に飛びつく前に、 線形モデルで尽くせる説明を尽くす。

✅ 回帰分析のチェックリスト(12 項目)

  1. 応答変数 y と説明変数 X の散布図を見たか? 線形性が成立するか?
  2. n と説明変数の数が「10 観測/変数」 を満たすか?
  3. 説明変数間の相関行列を確認したか? VIF を計算したか?
  4. 外れ値を散布図/箱ひげ図で確認したか?
  5. OLS の 4 仮定(線形性・独立性・等分散性・正規性)を残差プロットで確認したか?
  6. R² だけでなく adjusted R² を併記したか?
  7. 係数の標準誤差・信頼区間・p 値を報告したか?
  8. 異分散ロバスト標準誤差(HC3)を試したか?
  9. クロスバリデーションで予測誤差を見積もったか?
  10. 「相関 ≠ 因果」 を方法論セクションで明記したか?
  11. 結果を効果量で解釈したか(「1pp 上昇で 0.61 増」 のような実用的表現)?
  12. SSDSE-B-2026 のような小サンプルなら、 結果の頑健性を sensitivity analysis で確認したか?

「回帰分析」を扱う際の手法選択は、 状況に応じて以下のフローで判断すると迷いが減る。

  1. Step 1: 目的は記述か予測か?
    • 記述 (現状把握・要約) → 集計・可視化・要約統計量で全体像を掴む
    • 予測 (未知データへの推定) → モデル構築・検証フェーズへ移行
  2. Step 2: データの種類・規模は?
  3. Step 3: 結果の解釈・共有は?
    • 専門家向け → 数値指標・統計検定で精緻に評価
    • 非専門家向け → 可視化・自然言語での要約を重視

このフローに沿って判断することで、 「回帰分析」を中核とした適切な手法選択ができる。

🎓 解説深化①:直感の再構築 — 「予測する回帰」と「説明する回帰」

ここまでの内容を一段深く整理します。 回帰分析には 2 つの顔 があり、 どちらの顔で使っているかを自覚することが、 誤用を防ぐ最大のポイントです。

観点予測の回帰 (prediction)説明の回帰 (explanation)
目標新しい X に対する y の予測誤差を最小化係数 β の符号・大きさ・不確実性を解釈
成功の基準交差検証誤差・汎化性能係数の妥当性・仮定の充足・頑健性
変数選択予測に効けば理由は問わない理論・因果構造に基づいて選ぶ
SSDSE-B での例高齢化率から死亡率を当てる(R²=0.944)「高齢化率 1pp → 死亡率 +0.61」の解釈
典型的な失敗過学習(n=47 に変数を盛る)交絡を無視した因果的解釈

「単回帰 → 重回帰 → 一般化」の系譜を 1 本の線で掴む

回帰の派生手法は多いですが、 系譜は単純です。 (1) 説明変数を増やす方向単回帰重回帰)、 (2) 誤差分布・リンク関数を広げる方向(正規線形モデル → GLM:ロジスティック・ポアソン)、 (3) 関数形を柔らかくする方向(多項式 → スプライン → GAM)の 3 軸で、 ほぼすべての回帰系手法が位置づけられます。 どの軸に進んでも「残差を診断して仮定を確認する」という作法は共通です。

係数解釈の 3 段階チェック

  1. 単位:β は「x の 1 単位」あたりの変化。 SSDSE-B の高齢化率は %、 死亡率は ‰ なので、 β₁=0.610 は「1 ポイント → 0.61 ‰」。 単位が異なる変数どうしの比較には標準化偏回帰係数を使う。
  2. 条件:重回帰の β は「他の説明変数を固定した」条件付きの傾き。 単回帰の傾きとは一般に一致しない(本文の Frisch–Waugh–Lovell 節を参照)。
  3. 限界:観察データの β は「条件付き相関の要約」であり、 介入効果ではない。 因果を語るには追加の設計(後述の橋渡し節)が必要。
📘 直感の要点:回帰式は「データに最も合う関数を関数族から選んだ結果」にすぎません。 選んだ族(線形・GLM・GAM…)が現実に合っているかは、 式そのものではなく残差が教えてくれます。

🕳 解説深化②:落とし穴の実測検証(SSDSE-B 2023, n=47)

「落とし穴」を抽象論で終わらせず、 SSDSE-B-2026(cp932, skiprows=[1], 2023 年度 47 都道府県)で実際に数値を出して確認します。 以下の数値はすべて実測です。

① 交絡の統制不足 — 「診療所が多い県ほど死亡率が高い」?

人口千人あたり一般診療所数(I5102/A1101×1000、 平均 0.845)で死亡率を単回帰すると、 係数は +2.92(p=0.264, r=0.166)と正方向に出ます。 素朴に読むと「診療所が多いほど死亡率が高い」ように見えますが、 交絡要因の高齢化率(診療所密度との相関 r=0.191)を説明変数に加えると、 診療所密度の係数は −0.35(p=0.583)に反転し、 見かけの関係は消えます。 高齢化が進んだ県ほど診療所も死亡率も多い、 という共通原因の構図です。 疑似相関逆因果とあわせて、 係数の符号を額面通りに読まない訓練をしてください。

② 外れ値とレバレッジは別物 — 実測の h とCook 距離

「外れ値」には 2 種類あります。 y 方向の外れ(大きな残差)と、 x 方向の端にいること(高レバレッジ)です。 単回帰「死亡率 ← 高齢化率」での実測値:

都道府県レバレッジ h残差Cook 距離 Dタイプ
東京都0.174+1.030.547高レバレッジ(高齢化率最低 22.8%)+残差も大
沖縄県0.138+0.920.317高レバレッジ+中程度の残差
青森県+1.280.172残差型(x は中央寄り)
奈良県−1.650.134残差型(最大の負残差)
秋田県0.130+0.510.090高レバレッジ(高齢化率最高 39.1%)だが残差小

目安 h > 2p/n = 0.085 を超えるのは東京・沖縄・秋田など x の両端の県。 残差が最大の奈良県よりも、 残差が小さめの東京都の方が Cook 距離は大きい(0.547 vs 0.134)ことに注目してください。 影響力は「残差 × レバレッジ」で決まるため、 残差だけを見ていると影響力の強い点を見逃します。 対処は外れ値外れ値処理を参照。

③ 非線形の直線近似 — 実は二次項が有意

「死亡率 ← 高齢化率」は R²=0.944 と直線で十分に見えますが、 二次項(高齢化率²)を追加すると係数 +0.0168(p=0.0002)で有意になり、 R² は 0.9448 → 0.9600、 調整済み R² も 0.9436 → 0.9582 に改善します。 つまり「高齢化率が高い県ほど死亡率の増え方が加速する」凸型の湾曲が実データに存在します。 R² が高くても直線が最良とは限らない好例です。 ただし二次項モデルの外挿はさらに危険(放物線は範囲外で暴れる)なので、 解釈は観測範囲 22.8–39.1% 内に限定します。

④ 仮定違反の一括診断 — 実測の検定結果

仮定検定・指標実測値(単回帰)判定
等分散性Breusch–Paganp = 0.578違反の証拠なし
正規性Shapiro–Wilk(残差)W = 0.947, p = 0.0345% 水準で棄却(奈良などの裾の影響)
独立性Durbin–Watson1.63おおむね良好(2 に近い)

正規性がやや怪しいので、 係数の標準誤差を頑健化した HC3 ロバスト標準誤差を併記すると、 SE(β₁) は通常の 0.022 → 0.032 に広がります。 それでも t は約 19 で結論(有意な正の傾き)は変わらず、 「診断 → 頑健化 → 結論の頑健性確認」という流れを実データで一周できます。 正規性残差VIF も参照。

⚠ まとめ:相関≠因果(①)、 影響力の見逃し(②)、 関数形の思い込み(③)、 仮定の未検証(④)は、 n=47 の教材データでも全部「実際に起きる」。 落とし穴は理屈ではなく、 手元のデータで毎回確認する習慣が唯一の防御です。

🚀 解説深化③:発展 — OLS の外側の世界と因果推論への橋渡し

OLS を出発点に、 どの仮定を緩めるとどの手法に行き着くかを整理します。 SSDSE-B の実測値(2023 年度, n=47)で手法間の違いも確認します。

推定法の拡張マップ

緩める仮定・課題手法要点
等分散・無相関の誤差GLS / WLS誤差の分散構造を重みに組み込む一般化。 パネル・時系列で活躍(パネルデータ固定効果
多重共線性・高次元Ridge / Lasso / Elastic Net正則化でバイアスを許容し分散を抑える
正規誤差・連続応答GLM(ロジスティック / ポアソンプロビットリンク関数と指数型分布族で二値・件数・比率に対応
線形の関数形GAM(一般化加法モデル)y = β₀ + f₁(x₁) + f₂(x₂) + … と滑らかな関数の和で表現。 ③で見た湾曲を自動で捉える
外れ値への脆弱性頑健回帰(Huber M 推定など、 ロバスト統計大きな残差の重みを下げて推定
「平均」しか見ない分位点回帰中央値・第 1/第 3 四分位など分布の任意の位置の傾きを推定

実測比較:OLS・頑健回帰・分位点回帰の傾き(死亡率 ← 高齢化率)

推定法切片傾き β₁読み方
OLS−5.170.610条件付き平均の傾き
Huber 頑健回帰−5.540.622外れ値の重みを下げても傾きはほぼ同じ → 結果は頑健
分位点回帰 τ=0.25−5.800.622死亡率が低め側の県の傾き
分位点回帰 τ=0.50(中央値)−5.630.624中央値の傾き。 OLS とほぼ一致
分位点回帰 τ=0.75−4.800.606死亡率が高め側の県の傾き

5 通りの推定で傾きは 0.606–0.624 に収まり、 「高齢化率 1pp ≒ 死亡率 +0.6 ‰」という結論が推定法に依存しないことが確認できます。 このように複数手法で同じ結論に到達することを示すのが、 現代的な頑健性報告(sensitivity analysis)の基本形です。

因果推論への橋渡し — 回帰から一歩進むには

回帰係数を因果効果に近づけるには、 「x が誤差項と無相関(外生性)」という条件が鍵です(外生性内生性)。 観察データでこの条件を確保する代表的な設計:

SSDSE-B 単年の横断面ではこれらは適用しにくいものの、 年度を縦に積んだパネル(12 年 × 47 県 = 564 行)にすれば、 固定効果モデルや DID 的な設計が現実的になります。 「回帰で相関構造を記述 → 設計を強化して因果に接近」という 2 段構えが実務の王道です。

モデル診断の標準セット(本ページ総復習)

  1. 残差 vs 予測値プロット(線形性・等分散性)+ Breusch–Pagan
  2. Q-Q プロット(正規性)+ Shapiro–Wilk
  3. Durbin–Watson(独立性)
  4. レバレッジ h と Cook 距離(影響力)
  5. VIF(多重共線性)
  6. 交差検証(汎化性能・過学習)

さらに深掘りする関連ページ: 線形回帰 OLS 重回帰 回帰係数 残差 調整済み R² GAM 分位点回帰 ロバスト統計 正則化 交絡 操作変数法