論文一覧に戻る 📚 用語解説(ジャストインタイム型データサイエンス教育)
残差
Residual (ε / e)
実測値 − モデル予測値。残差プロットの形でモデルの妥当性(線形性・等分散性)を診断する。
回帰モデルε / e残差residual

🔖 キーワード索引(拡張)

残差・残差診断の重要語をクイックアクセス:

残差プロット 標準化残差 studentized 残差 てこ比 leverage Cook の距離 DFFITS / DFBETAS Q-Q プロット 不均一分散 系列相関(自己相関) 非線形パターン statsmodels OLS influence_plot Breusch-Pagan Durbin-Watson

💡 30秒で分かる結論

🍰 まずはやさしく

予測と実際の結果のズレのことです。

分析モデルが正しいか確かめるために使います。

テストの予想点数と実際の点数の差のようなものです。

この章では残差の定義と使い道を学びます。

📖 もっと詳しく

残差(residual)は、 「実測値 $y_i$ - モデル予測値 $\hat{y}_i$」の差。 モデルが捉えきれなかった「説明できないズレ」です。 回帰分析の診断の中核で、 これを見ずに結果を信じてはいけません。

OLSの4つの仮定(残差で診断):

  1. 平均0:残差の平均が0(OLSは自動で満たす)
  2. 等分散:残差のばらつきが x の値によらず一定
  3. 独立:残差同士に自己相関がない
  4. 正規分布:残差が(近似的に)正規分布

残差プロットの読み方

Q-Qプロット:残差が正規分布に従うかを視覚的に確認。 点が直線上にあれば正規性OK、 大きく逸脱するなら非正規。

Pythonfitted = model.fittedvalues; residuals = model.resid。 散布図と Q-Qプロット(statsmodels.graphics.gofplots.qqplot)を必ず描く習慣を。

👁️ 直感 — 残差は「モデルが説明できなかった部分」

残差 e_i = y_i - ŷ_i は、 観測値とモデル予測値の差。 モデルで捉えきれなかったランダムな変動を表します。

残差分析の目的

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

🍰 まずはやさしく

データ分析でよく出てくる用語です。

モデルの妥当性(正しさ)を診断するために使います。

スマホの利用時間から成績を予想する時に役立ちます。

定義から実装まで6つの視点で詳しく解説します。

論文中に 「残差」として登場する用語。

残差 とは:実測値 − モデル予測値。残差プロットの形でモデルの妥当性(線形性・等分散性)を診断する。

本ページでは「residual」を扱う。 統計データ分析コンペティション (2026) の教材で、 SSDSE-B-2026 (47 都道府県 × 複数年 × 100 超列) の実データを使った再現可能な学習を目指す。

「residual」は統計・データサイエンスの体系における重要概念のひとつ。 本ページは「定義・直感・数式・実装・落とし穴・関連手法」の 6 視点で構成され、 各視点は独立して読めるが順序通り読むと体系的な理解が得られる。

🎨 直感で掴む

🍰 まずはやさしく

グラフの線と点の縦方向の距離のことです。

モデルで説明できない理由を探るために使います。

人口だけで出生数を予想した時のズレに似ています。

図を使ってモデルを信じてよいか判断する方法を読みます。

残差 e_i = y_i − ŷ_i は「実測値と回帰直線の縦方向のズレ」。 SSDSE-B-2026 で「総人口 (A1101) → 出生数 (A4101)」を OLS で当てはめると、 直線の上にある県 (沖縄・愛知など若年層が厚い県) は正の残差、 下にある県 (秋田・高知など高齢化が進む県) は負の残差を持つ。 残差は単なる誤差ではなく、 モデルが「人口規模だけでは説明しきれなかった県固有の出生力」を凝縮したシグナルとして読む。

残差プロット (横軸 ŷ、 縦軸 e) を描くと、 健全な回帰では点群が y=0 の周りに帯状に散らばる。 一方、 ラッパ型に広がるなら不等分散、 弧を描くなら線形性違反、 ぽつんと離れた点があれば外れ値 (東京が典型) と一目で判定できる。 R² や p 値より、 残差プロットの形こそ「モデルを信じてよいか」の最終裁定。

SSDSE-B-2026 では人口規模が突出する東京が回帰直線から大きく外れやすく、 これが Cook 距離・標準化残差で「影響点」として検出される。 次節以降では 47 県データで e_i を実数値で算出し、 Q-Q プロットと標準化残差を Python で再現する。

🎮 触って理解する — 残差プロットでモデルを診断する

左の散布図に点を置く/ドラッグすると、 その場で最小二乗法(OLS)の回帰直線が当てはまり、 各点から直線までの縦方向の残差が赤い縦線で描かれます。 右には残差プロット(横軸: 予測値 ŷ または説明変数 x、 縦軸: 残差 e)を並べました。 良いモデルほど残差は 0 の線の周りにランダムに散らばり悪いモデルは曲がり・扇形(不等分散)・外れ値といったパターンを残します。 下のプリセットを切り替えて、 残差診断の「目」を養ってください。

プリセット:
残差プロット横軸:

💡 空白部分をクリック/タップで点を追加、 点をドラッグで移動。 削除モード ON 中は点をクリックで削除。 点が 2 個以上で直線が引かれます。

① 散布図+回帰直線+残差(赤い縦線)

② 残差プロット(縦軸: 残差 e、 0 線の周りに散るのが理想)

点の数 n0
回帰式 ŷ = a + b·x
決定係数 R²
残差の合計 Σe
残差の標準偏差
プリセットを選ぶか、 散布図をクリックして点を置いてください。

📖 残差とは — 定義

残差 $e_i = y_i - \hat{y}_i$ は「観測値」と「モデルの予測値」の差、 すなわちモデルが説明しきれなかった縦方向のズレです。 真の誤差項 $\varepsilon_i$(母集団レベルの観測できない量)とは区別され、 残差はデータから推定した後の量です。 最小二乗法(OLS)は「残差の二乗和 $\sum e_i^2$ を最小化する」ように係数 $a,b$ を決めるため、 その帰結として必ず $\sum e_i = 0$(残差の合計はゼロ)かつ $\sum x_i e_i = 0$(残差と説明変数は無相関)が成り立ちます。 上の実験でどんな配置にしても「残差の合計 Σe」がほぼ 0 になるのは、 この OLS の数理的性質そのものです。

🔍 残差プロットによるモデル診断 — 4つの仮定

回帰の妥当性は $R^2$ や p 値ではなく残差プロットの「形」で最終判断します。 線形回帰(および OLS)が前提とする 4 仮定を、 残差でどう診断するかを整理します。

仮定 見る図 健全なサイン 違反のサイン → 対処
① 線形性残差 vs 予測値0 線の周りにランダム散布U 字・弧の曲がり → 二乗項・log 変換・spline/GAM
② 等分散性残差 vs 予測値 / Scale-Location帯の幅が一定扇形(ファネル) → log 変換・WLS・頑健 SE
③ 独立性残差 vs 観測順 / ACF周期・連なりがない波・連続 → 時系列モデル・HAC 標準誤差
④ 正規性Q-Q プロット / ヒストグラム点が直線に乗る両端が反る → 変換・ロバスト回帰(小標本は過検出に注意)

📢 不等分散(heteroscedasticity)

残差のばらつきが x(や予測値)の水準によって変わる状態を不等分散(heteroscedasticity)と呼びます。 上の「不等分散(扇形)」プリセットのように、 x が大きいほど残差が大きく開くファネル型が典型。 このとき OLS の係数推定は不偏のままですが、 標準誤差が誤りとなり p 値・信頼区間が信用できなくなります。 対処は (a) 目的変数の log/√ 変換、 (b) 重み付き最小二乗(WLS)、 (c) White の不均一分散頑健標準誤差。 形式的には Breusch-Pagan 検定・White 検定を併用します。 なお、 SSDSE のような人口・所得のカウント/金額変数は log 変換で等分散に近づくことが多いです。

🎯 外れ値と影響点(leverage・Cook 距離)

「外れ値(outlier)」は残差が大きい点、 「高レバレッジ点」は説明変数 x が極端な点。 両方を兼ねる点は影響点(influential point)となり、 回帰直線そのものを引っ張ります。 上の「外れ値」プリセットで端の 1 点をドラッグすると、 直線と 決定係数 R² が大きく動くのを体感できます。 判定には残差だけでなく、 leverage $h_{ii}$(平均 $(p+1)/n$ 超で注意)と Cook 距離($4/n$ 超で注意)を併用します。 「残差が大きい点=異常」ではない点に注意。 恣意的に削除せず、 記録ミスの確認・ロバスト回帰・感度分析で段階的に対処します。

📐 回帰の仮定(まとめと前提リンク)

残差診断は結局、 線形回帰最小二乗法(OLS)が置く古典的仮定(線形性・等分散性・独立性・正規性、 加えて説明変数と誤差の無相関)が成り立っているかの点検です。 これらが満たされて初めて、 決定係数 R²・係数の t 検定・予測区間が意味を持ちます。 逆に言えば、 R² が高くても残差プロットが曲がっていれば関数形の指定ミスであり、 「散布図・残差プロット・Q-Q プロットの 3 点セットを毎回見る」ことが回帰分析の質を担保します。

📐 残差の種類

🍰 まずはやさしく

計算方法によっていくつかの種類があります。

外れ値(極端なデータ)を見つけるために使い分けます。

部活の記録の中で一人だけ違う傾向の人を探すようなものです。

4つのプロット(図)と影響力の指標について読みます。

種類 定義 用途
通常残差e_i = y_i - ŷ_i基本
標準化残差e_i / σスケールフリー
スチューデント化残差e_i / SE(e_i)外れ値検出
PRESS残差e_i / (1-h_ii)予測精度評価

📊 4つの主要な残差プロット

  1. 残差 vs 予測値:パターンがあれば線形性 or 等分散性違反
  2. QQプロット:残差が直線に乗れば正規分布
  3. Scale-Location:√|残差| vs 予測値、 等分散性確認
  4. 残差 vs Leverage:影響力のある観測値発見

🎯 影響力のある観測値

少数の極端な観測値が回帰結果を大きく動かすことがあります。 主要な指標:

🔬 数式を言葉で読み解く

残差の重要な性質

残差を見る習慣

「回帰した、 R² も高い」で満足せず、 必ず残差プロットを描く。 多くの研究者は残差分析を省略し、 重大なモデル誤指定を見逃しています。

📝 練習問題 — 理解度チェック

  1. この用語の基本定義を、 自分の言葉で説明できますか?
  2. この手法が使われる典型的なシナリオを3つ挙げられますか?
  3. この手法の前提条件・仮定を確認できますか?
  4. 結果を解釈する際の注意点は何ですか?
  5. 類似手法との違いを説明できますか?
  6. Python(または他言語)で実装できますか?
  7. SSDSE データで応用例を作成できますか?

🧮 SSDSE-B 実値計算 — 出生数回帰の残差を 4 プロットで診断

47都道府県の出生数を「総人口(log)」「死亡数(log)」で説明する OLS を当てはめ、 残差診断 4 プロット(残差 vs フィット、 Q-Q、 scale-location、 leverage-Cook)を作る。

🎯 解説: matplotlib で残差プロット(横軸: 予測値, 縦軸: 残差)を描画。 SSDSE-B-2026 で回帰モデルの妥当性を視覚的に診断。
📥 入力例: data/raw/SSDSE-B-2026.csv fitted = model.predict(X) residuals = y - fitted
📤 実行例: 残差プロット
  水平に散らばる → 線形性 OK
  右上に大都市圏の大きな正の残差
  全体的にランダム

💬 読み方: 残差プロットでパターン(U 字・扇形)が見えれば線形仮定違反。 ランダム雲なら OK。 0 の水平線を引いて偏りを確認。

 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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import statsmodels.api as sm
import statsmodels.formula.api as smf
from scipy import stats

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', header=1)
df.columns = [c.strip() for c in df.columns]; df = df[df['年度'] == 2023]  # 2023年の47都道府県のみ
df['log_death'] = np.log(df['死亡数'])
df['log_pop'] = np.log(df['総人口'])

res = smf.ols('出生数 ~ log_pop + log_death', data=df).fit()
print(res.summary())

infl  = res.get_influence()
sresid = infl.resid_studentized_internal
fitted = res.fittedvalues
leverage = infl.hat_matrix_diag
cooks  = infl.cooks_distance[0]

fig, axes = plt.subplots(2, 2, figsize=(11, 9))
# (1) Residuals vs Fitted
axes[0,0].scatter(fitted, res.resid)
axes[0,0].axhline(0, ls='--', color='red')
axes[0,0].set_xlabel('Fitted'); axes[0,0].set_ylabel('Residual')
axes[0,0].set_title('Residuals vs Fitted')
# (2) Normal Q-Q
sm.qqplot(sresid, line='45', fit=True, ax=axes[0,1])
axes[0,1].set_title('Normal Q-Q')
# (3) Scale-Location
axes[1,0].scatter(fitted, np.sqrt(np.abs(sresid)))
axes[1,0].set_xlabel('Fitted'); axes[1,0].set_ylabel('√|standardized residual|')
axes[1,0].set_title('Scale-Location')
# (4) Residuals vs Leverage
axes[1,1].scatter(leverage, sresid)
for i, (h, r, c) in enumerate(zip(leverage, sresid, cooks)):
    if c > 4/len(df):
        axes[1,1].annotate(df.iloc[i]['都道府県'], (h, r), fontsize=8)
axes[1,1].set_xlabel('Leverage'); axes[1,1].set_ylabel('Std. residual')
axes[1,1].set_title('Residuals vs Leverage')
plt.tight_layout(); plt.savefig('residual_diag.png', dpi=140)

典型的な観察例: Residual vs Fitted で東京・神奈川が右上に飛び出し、 Q-Q プロットの右裾も外れる。 Cook 距離も東京・神奈川が突出(> 4/n)。 つまり「人口規模が大きい大都市圏」は通常の OLS の仮定(等分散・線形)から外れており、 ロバスト回帰や層別モデルで補強する必要がある。

統計的な異常診断テスト

🎯 解説: Q-Q プロット(quantile-quantile)で残差の正規性を診断。 SSDSE-B-2026 の残差を正規分布の理論分位と比較し、 直線に乗るかチェック。
📥 入力例: data/raw/SSDSE-B-2026.csv from scipy import stats stats.probplot(residuals, plot=plt)
📤 実行例: Q-Q プロット
  中央は直線に乗る
  両端で外れ(裾が重い分布)
  Shapiro-Wilk p=0.0001(要注意)

💬 読み方: Q-Q プロットが直線 → 正規分布。 端で外れる → 裾が重い・歪み。 47 サンプルは少なめなので外れに注意。 Shapiro-Wilk 検定も併用。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
from statsmodels.stats.diagnostic import (
    het_breuschpagan, het_white, acorr_ljungbox)
from statsmodels.stats.stattools import durbin_watson

# 正規性
print('Shapiro:', stats.shapiro(res.resid))
# 不均一分散
bp = het_breuschpagan(res.resid, res.model.exog)
print(f'Breusch-Pagan : LM={bp[0]:.2f}, p={bp[1]:.4f}')
white = het_white(res.resid, res.model.exog)
print(f'White        : LM={white[0]:.2f}, p={white[1]:.4f}')
# 自己相関(時系列ならば)
print('Durbin-Watson :', durbin_watson(res.resid))

🧮 数式に値を入れて手で計算する: SSDSE-B-2026 で残差と等分散性

SSDSE-B-2026(2023 年度)から x=総人口(千人)、 y=出生数(人)の 6 都道府県(北海道〜山形)で OLS(ŷ=−40.88+4.8865·x)を当てはめ、 残差を計算する。

Step 1: 残差

x = [5092, 1184, 1163, 2264, 914, 1026] (総人口 千人) y = [24430, 5696, 5432, 12328, 3611, 5151] (出生数 人) ŷ = [24841.07, 5744.71, 5642.10, 11022.11, 4425.36, 4972.65] e = y - ŷ = [-411.07, -48.71, -210.10, 1305.89, -814.36, 178.35]

Step 2: 残差統計

平均 = (-411.07-48.71-210.10+1305.89-814.36+178.35)/6 ≈ 0.0000 (OLS の性質) Σe² ≈ 168980.8 + 2372.8 + 44140.2 + 1705350.3 + 663186.1 + 31809.4 = 2615839.7 SD = √Σe²/(n-2) = √(2615839.7/4) ≈ √653960 ≈ 808.68 (人)

🐍 Python で再現

1
2
3
4
5
6
7
import numpy as np
# SSDSE-B-2026 (2023) 北海道〜山形: 総人口(千人)・出生数(人)
x = np.array([5092, 1184, 1163, 2264, 914, 1026])
y = np.array([24430, 5696, 5432, 12328, 3611, 5151])
b = np.cov(x,y,ddof=1)[0,1]/np.var(x,ddof=1); a = y.mean() - b*x.mean()
e = y - (a + b*x)
print(f"残差: {e.round(2)}")
print(f"残差平均: {e.mean():.4f}")
print(f"残差SD: {np.sqrt((e**2).sum()/(len(e)-2)):.3f}")

📤 実行結果

残差: [ -411.07 -48.71 -210.1 1305.89 -814.36 178.35] 残差平均: 0.0000 残差SD: 808.678

💬 手計算 (Step 2) と Python 出力が完全一致。 残差平均が厳密に 0 になるのは OLS の数理的性質(正規方程式の帰結)であり、 SD≈808.7 人は「人口規模だけでは説明できない出生力(若年層の厚み)のばらつき」を表す。 宮城が大きな正の残差(+1305.89、 仙台圏の若年集積)、 秋田が大きな負の残差(−814.36、 超高齢化)となり、 残差が県固有の出生力シグナルを捉えていることが読み取れる。

🐍 Python での残差分析

🎯 解説: SSDSE-B-2026 の回帰モデルから残差 e = y - ŷ を計算。 残差はモデルが説明できなかった部分で、 ランダム性と非線形性・外れ値の検出に使う。
📥 入力例: data/raw/SSDSE-B-2026.csv y = 実測値(出生数) ŷ = 予測値(回帰直線から) e = y - ŷ
 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 statsmodels.api as sm
import matplotlib.pyplot as plt
from scipy import stats

X = sm.add_constant(x)
model = sm.OLS(y, X).fit()

# 残差を取得
residuals = model.resid
fitted = model.fittedvalues
std_resid = model.get_influence().resid_studentized_internal

# 残差プロット
fig, axes = plt.subplots(2, 2, figsize=(12, 10))
axes[0, 0].scatter(fitted, residuals)
axes[0, 0].axhline(0, color='red')
axes[0, 0].set_title('Residuals vs Fitted')

stats.probplot(residuals, plot=axes[0, 1])
axes[0, 1].set_title('Normal Q-Q')

# Cook's distance
inf = model.get_influence()
cook = inf.cooks_distance[0]
axes[1, 0].stem(cook)
axes[1, 0].axhline(4/len(x), color='red')
axes[1, 0].set_title("Cook's Distance")
📤 実行例: 残差統計 平均 ≈ 0(OLS の性質) 残差 SD は目的変数の SD より小さい 最大正残差: 大都市圏(東京・愛知) 最大負残差: 高齢化県(秋田・高知)
💬 読み方: OLS では残差平均=0、 残差と x の共分散=0 が成立。 残差 SD が y の SD より小さい → モデルが説明できている。 外れ値は要確認。

🚧 落とし穴と注意点

🐍 Python 実装バリエーション — statsmodels / scipy / sklearn

1. statsmodels の influence プロット(一発)

🎯 解説: 残差の分散均一性(homoscedasticity)を Breusch-Pagan 検定で確認。 SSDSE-B-2026 で残差の分散が x によらないかをチェック。
📥 入力例: data/raw/SSDSE-B-2026.csv from statsmodels.stats.diagnostic import het_breuschpagan het_breuschpagan(residuals, X)
📤 実行例: BP 統計量=5.2
  p=0.07
  有意水準 0.05 でぎりぎり OK
  扇形パターンを目視確認

💬 読み方: p>0.05 → 等分散仮定 OK。 違反していれば WLS(重み付き最小二乗)や log 変換。 SSDSE の人口・出生数などのカウント変数は対数変換で改善することが多い。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# ── この抜粋で使うデータを用意します ──
import pandas as pd
import statsmodels.api as sm
import statsmodels.formula.api as smf

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df = df[df['SSDSE-B-2026'] == 2023]          # 2023 年の 47 都道府県
df = df.rename(columns={'A4101': 'y', 'A1101': 'x1', 'A1303': 'x2'})
# y=出生数 を x1=総人口・x2=65歳以上人口 で説明する

res = smf.ols('y ~ x1 + x2', data=df).fit()
fig = sm.graphics.influence_plot(res, criterion='cooks')

2. 4 プロット診断を一括(plot_diagnostics)

🎯 解説: 残差の自己相関(Durbin-Watson 検定)。 SSDSE-B-2026 では時系列でないため通常不要だが、 県の並びに依存性がないか確認。
📥 入力例: data/raw/SSDSE-B-2026.csv from statsmodels.stats.stattools import durbin_watson durbin_watson(residuals)
📤 実行例: DW 統計量=2.05
  ≈ 2 → 自己相関なし
  < 1.5 → 正の自己相関
  > 2.5 → 負の自己相関

💬 読み方: クロスセクション(県データ)では DW は通常気にしないが、 並びがランダムでないと自己相関が出ることも。 時系列回帰では必須チェック。

1
2
3
4
5
6
# 時系列モデル(ARIMA 等)には組込みの plot_diagnostics があるが、
# 線形回帰は自作する必要がある(上の SSDSE 計算例を参照)
from statsmodels.graphics.regressionplots import (
    plot_leverage_resid2, plot_partregress_grid)
fig = plt.figure(figsize=(11, 8))
plot_partregress_grid(res, fig=fig)   # 部分回帰プロット

3. scipy.stats の正規性検定セット

🎯 解説: 標準化残差で外れ値を検出。 SSDSE-B-2026 で残差を SD で割った標準化値、 |z|>2 を要注意、 |z|>3 を強い外れ値として識別。
📥 入力例: data/raw/SSDSE-B-2026.csv std_resid = residuals / residuals.std() 外れ値: |std_resid| > 2
📤 実行例: 標準化残差
  東京: +2.8(強い外れ値)
  大阪: -1.9
  愛知: +1.5
  他: |z|<1.5

💬 読み方: |z|>2 は約 5% に該当、 |z|>3 は約 0.3%。 SSDSE では東京がよく強い外れ値。 削除でなく log 変換やロバスト回帰で対処。

1
2
3
4
5
6
7
from scipy import stats
print('Shapiro-Wilk    :', stats.shapiro(res.resid))
print('Anderson-Darling:', stats.anderson(res.resid, dist='norm'))
print("D'Agostino K²   :", stats.normaltest(res.resid))
print('Jarque-Bera     :', stats.jarque_bera(res.resid))
print('Skewness        :', stats.skew(res.resid))
print('Kurtosis        :', stats.kurtosis(res.resid))

4. sklearn で OOF 予測誤差を診断

🎯 解説: 影響度(Cook's distance)で重要な観測値を検出。 SSDSE-B-2026 で各県の Cook's D を計算し、 4/n を閾値として影響力大の県を特定。
📥 入力例: data/raw/SSDSE-B-2026.csv influence = model.get_influence() cooks_d = influence.cooks_distance[0] 閾値: 4/47 ≈ 0.085
📤 実行例: Cook's distance
  東京: 0.45(極大)
  大阪: 0.12
  愛知: 0.09
  他: <0.05

💬 読み方: Cook's D > 4/n で影響力大。 東京が突出 → モデル係数を強く左右。 除外シミュレーションで影響度確認。 ロバスト回帰で対処も可。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import cross_val_predict, KFold

cv = KFold(n_splits=5, shuffle=True, random_state=0)
y_pred = cross_val_predict(LinearRegression(), X, y, cv=cv)
oof_resid = y - y_pred

fig, ax = plt.subplots(1, 2, figsize=(11, 4.5))
ax[0].scatter(y_pred, oof_resid); ax[0].axhline(0, ls='--', color='red')
ax[0].set_title('OOF Residuals')
sm.qqplot(oof_resid, line='45', fit=True, ax=ax[1])

5. ロバスト回帰で残差を改善(HuberRegressor / RANSAC)

🎯 解説: 残差ヒストグラムで分布を確認。 SSDSE-B-2026 の残差ヒストグラム + 正規分布曲線を重ね、 視覚的に正規性をチェック。
📥 入力例: data/raw/SSDSE-B-2026.csv plt.hist(residuals, bins=20) 正規分布 PDF を重ね描き
📤 実行例: ヒストグラム
  中央付近にピーク(0)
  右に長い裾(東京の影響)
  歪度=0.8(右歪み)

💬 読み方: 残差が正規分布から大きく逸れる → モデル不適切。 歪み大なら変換、 多峰なら層別解析。 47 サンプルは bin 数 10-15 が適切。

1
2
3
4
5
from sklearn.linear_model import HuberRegressor, RANSACRegressor
huber = HuberRegressor().fit(X, y)
ransac = RANSACRegressor(random_state=0).fit(X, y)
# 外れ値判定マスク(RANSAC のみ)
inliers = ransac.inlier_mask_

⚠️ 残差診断の落とし穴 — 6 つの典型ミス

① 生残差だけ見て分散の異質性を判断する

y のスケールが大きい観測ほど残差の絶対値が大きく見えるのは自然で、 これを「不均一分散だ」と判断するのは早計。 標準化残差(resid_studentized_internal)か外部スチューデント化残差(resid_studentized_external)を用いてスケールを除いた上で、 fitted 値との依存を見るのが正しい。 Breusch-Pagan / White の検定で形式的にも確認すること。 残差プロットは目視と検定を組み合わせて初めて意味を持つ。

② Q-Q プロットの裾の歪みを「正規性違反」と短絡する

Q-Q プロットは小サンプル(n < 30)では端点が大きく揺れるのが普通で、 「裾が反っているから非正規」と判断すると過検出になる。 中心極限定理により、 大標本では係数推定の頑健性は高い。 Shapiro-Wilk 検定や Kolmogorov-Smirnov 検定で形式的に確認し、 さらに「歪度・尖度」を数値で確認するのが安全。 残差の正規性は「予測区間の正確性」に効くが、 係数推定の不偏性には効かない点を分けて理解する。

③ Cook 距離だけで影響点を判定する

Cook 距離は便利だが「全係数への影響を 1 つの数値に圧縮」しているため、 個別係数への影響は見えない。 DFBETAS は係数ごとの影響、 DFFITS は予測値への影響、 leverage は X 空間上の極端さを別々に評価する。 大規模データで影響点を特定するには、 これら 4 指標を組み合わせる必要がある。 Cook の閾値も「4/n」と「1」の 2 流派があり、 解釈が割れる。

④ 時系列データに普通の OLS 残差診断を流用する

時系列回帰では残差に自己相関が残ることが多く、 OLS の標準誤差が過小評価される。 Durbin-Watson 統計量(≈ 2 ならOK、 < 1.5 or > 2.5 で系列相関の疑い)、 Ljung-Box 検定、 残差の ACF プロットで必ず確認する。 系列相関があれば Newey-West の HAC 標準誤差、 もしくは AR(1) 誤差付き GLS(ARMAX)に切り替える。 残差独立は線形回帰の四大仮定の一つで、 違反の影響は深刻。

⑤ 非線形パターンを線形項追加で誤魔化す

Residuals vs Fitted で U 字や逆 U 字のパターンが出るのは、 モデルが線形項だけでは捉えきれない非線形性のサイン。 これに対し「x² を追加する」だけで対応すると、 別の点で再び非線形パターンが出る。 根本対策は (a) 目的変数を log/sqrt 変換、 (b) 説明変数を spline / GAM で柔軟化、 (c) ツリー系モデルへ切り替え、 のいずれか。 「partial residual plot」「component-plus-residual plot」で個別変数の非線形性を確認する。

⑥ 残差を「予測誤差」と取り違える

学習データの残差は「フィット誤差」であって、 未知データへの「予測誤差」より楽観的になる。 RMSE を残差で計算しても汎化性能は分からない。 予測誤差を見るには交差検証 / hold-out / OOB(RF)/ test split のいずれかが必須。 「残差で良いから予測も良い」は過学習を見落とす典型ミス。 残差は仮定診断、 予測誤差は汎化能力評価、 と目的を切り分ける。

⚠️ 条件・限界・誤解回避 — 残差診断の実務的注意点

残差 e = y − ŷ は「モデルが説明できなかった部分」であり、 モデル検証の中核ツール。 ただし残差の見方には流派と注意点があり、 SSDSE-B-2026 のような N=47 の小サンプルでは特に慎重な扱いが必要。 ここでは適用条件・限界・誤解回避を順に整理する。

📐 適用条件(残差診断が機能するための前提)

  1. モデルが正しく推定されている: そもそも β̂ の計算が間違っていれば残差も間違う。 多重共線性・収束失敗・スケーリング失敗を先にチェックする。
  2. 残差は「標準化」して比較する: 生残差は単位を持つので、 観測ごとに大きさが違って見える。 標準化残差(standardized residual)や Studentized 残差で比較する。
  3. サンプルサイズが診断に十分: N < 30 程度では Q-Q プロットの解釈は不安定。 SSDSE-B-2026(N=47)はぎりぎりの水準で、 主観に頼りすぎないようシャピロ-ウィルク検定等を併用。
  4. 変数が線形に取り込まれている: 非線形変換(log・二乗)が必要な変数を線形のまま入れると、 残差プロットに湾曲が現れる。 これは「データの問題」ではなく「モデル指定の問題」。
  5. 外れ値・高 leverage 点が事前に特定されている: 残差が大きい点は「異常値」ではなく「モデルが説明できなかった点」。 leverage 値も併せて評価する。

🚧 限界(残差プロットだけでは分からないこと)

  1. 残差が正規分布でも仮定 OK とは限らない: 残差の正規性はあくまで「t 検定・F 検定の漸近近似の妥当性」を支える条件。 線形性そのものは別の診断(部分残差プロット)で確認する。
  2. 独立性の検定は時系列構造を仮定する: Durbin-Watson 検定は 1 次自己相関に特化。 高次の自己相関や空間相関には別の検定(Breusch-Godfrey、 Moran's I)が必要。
  3. 不均一分散の補正は SE のみ: White の不均一分散頑健 SE は標準誤差を補正するが、 推定量自体は OLS のままで効率性は劣る。 必要なら WLS / GLS を検討。
  4. 残差プロットは「視覚的判断」に依存: 同じプロットでも「異常」と判断するかどうかは主観差がある。 検定(Breusch-Pagan、 White)を併用する。
  5. 残差は推定後の量であり、 真の誤差ではない: モデルの誤特定があれば残差は真の誤差と乖離する。 残差の正規性 ≠ 真の誤差の正規性。

💡 誤解回避(残差解釈で陥る典型的な勘違い)

  1. 「残差が大きい点 = 外れ値」は誤解: 残差が大きい点は「モデルから外れた点」であって、 必ずしもデータ的に異常ではない。 leverage と影響度(Cook 距離)と組み合わせて判断する。
  2. 「平均が 0 だから OK」は短絡: OLS の残差は数学的に必ず平均 0。 残差の平均をチェックしても何も分からない。 重要なのは分散構造・自己相関・正規性。
  3. 「R² が高ければ残差は無視できる」は誤解: R² が高くても残差プロットに湾曲があれば、 関数形の指定ミスを示す。 R² と残差は独立に評価する。
  4. 「外れ値を消せば全て解決」も誤解: 外れ値を恣意的に除外するとデータが歪む。 ロバスト回帰、 影響度の小さい点だけ除外、 別モデルでの感度分析など、 段階的に対処する。
  5. 「残差の絶対値が大きい点を順に消す」は最悪パターン: モデルがその点を「説明できない」のはモデルの限界。 データを切るのではなく、 関数形を見直すのが本筋。

✅ 実務でのチェックリスト

💬 残差プロットは「モデルが嘘をついていないかの最初のチェック」。 OLS の係数の妥当性は、 ほぼ全て残差を通じて保証される。 R² と p 値だけで判断せず、 散布図・残差プロット・Q-Q プロットの 3 点セットを毎回見る習慣が、 回帰分析の質を一段引き上げる。

🗺️ 概念マップ — 3つの視点で体系を理解する

残差 がデータサイエンスの体系の中でどこに位置するかを、 3つの異なる視点で可視化します。 同じ情報でも見方を変えると気付きが変わります。

📍 体系階層のパス

🌐 統計・データサイエンス関連・回帰回帰残差

① 🔗 関係マップ — 「他の手法とどう繋がっているか」

中心に 残差 を置き、 そこから R²・最小二乗法・重回帰・分散・単回帰・Ridge回帰 計 6 個の用語へ、 前提・兄弟・発展形といった関係を矢印で結んでいます。 線がどちら向きかを見れば、 先に読むべき用語あとから読む用語が分かります。 ノードはドラッグで動かせ、 ホイールでズーム、 クリックでその用語のページへ遷移します。

凡例:現在の用語上位カテゴリ兄弟(並列)前提発展形応用先2階層先

② ⭕ 包含マップ — 「どのカテゴリに含まれているか」

大きな円が小さな円を包含する Circle Packing 図。 「残差」は緑色でハイライト

📍現在地:統計・データサイエンス

③ 🌳 ツリーマップ — 「面積で見るボリューム比較」

長方形を入れ子に分割した Treemap 図。 各分野の規模感を面積で比較。 「残差」は緑色でハイライト

🎯 3つのマップの使い分け

マップ 分かること こんな時に見る
🔗 関係マップ手法間の横の関係(前提→発展→応用)「次に何を学べばよい?」 学習順序の判断
⭕ 包含マップ分類体系の入れ子構造(上位⊃下位)「この手法はどんなジャンルに属する?」
🌳 ツリーマップ分野の規模比較(面積=ボリューム)「データサイエンス全体の俯瞰像」

💡 3 つの図は同じ位置関係を別の角度から描いています。 関係マップは 残差隣に何が並ぶかを、 包含マップとツリーマップは 統計・データサイエンス回帰 → 残差 という入れ子の位置を示します。 「回帰には他に何があったか」を思い出したいときは包含マップを、 「次に何を読むか」を決めたいときは関係マップを開いてください。

🔗 隣接手法への橋渡し

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

残差は単なる「予測の誤差」ではなく モデルの妥当性を診断する顕微鏡 であり、 残差のパターンから次に試すべき変数変換やモデル拡張が見えてくる。

🌳 手法選択フロー

「residual」を含む手法選択は、 データの性質・分析目的・運用制約の 3 軸で決まる。 以下に典型シナリオと対応する手法の組合せを示す。

典型シナリオ別の手法選択

シナリオ重視する観点候補手法
データが大規模 (n が多い、 高次元)計算コスト / メモリ / 並列化が必要ビジネス理解
外れ値が多い / ノイズあり頑健性 / 外れ値除去 / 中央値ベースデータ理解
解釈性を重視する線形 / 木構造 / ルールベースデータ準備
予測精度を最優先するアンサンブル / ハイパラ調整 / 交差検証モデリング
データが少ない正則化 / ベイズ / 転移学習 / 簡素なモデルデータアナリスト
リアルタイム/オンライン処理ストリーミング / 軽量モデル / 逐次更新データサイエンティスト

選んだ後の検証ステップ

  1. 前処理確認: 標準化 / 欠損処理 / カテゴリ変数のエンコード が適切か
  2. ハイパラ調整: 交差検証で安定する値を選ぶ
  3. 性能評価: タスクに応じた指標 (RMSE / Accuracy / F1 / AUC / シルエット等) を複数併用
  4. 頑健性チェック: 別手法 / 別シードで結果が大きく違わないか確認
  5. 解釈: 結果を分野知識と照らし合わせ、 意味のある発見になっているか検討

🔎 解説をさらに深める — 直感・落とし穴・発展

本セクションは既存の解説を非破壊で補強する追加教材です。 冒頭の SSDSE-B 実値計算と同じ回帰モデル(出生数 ~ log(総人口) + log(死亡数)、 SSDSE-B-2026 の 2023 年・47 都道府県)を実際に実行した実測値で裏付けながら、 直感・落とし穴・発展を一段深めます。 掲載した数値はすべて実データからの実測で、 合成値・想像値は含みません。

🎯 冒頭モデルを実行した実測診断(SSDSE-B-2026 / 2023 / n=47) 出生数 ~ log(総人口) + log(死亡数) R² = 0.832, 自由度調整済 R² = 0.825 残差平均 ≈ 0.000000(OLS の性質), 残差SD ≈ 6953 人 Shapiro-Wilk : W=0.873, p=0.0001 → 正規性は棄却 Breusch-Pagan: LM=8.04, p=0.0180 → 不等分散あり White : LM=23.02, p=0.0003 → 不等分散あり Durbin-Watson: 1.78 → 2 付近(弱い正の系列相関の域) 歪度=1.70, 尖度=5.24 → 右に長い裾(重い右裾) Cook距離 最大 : 東京都 = 1.494(閾値 4/n=0.085 を大幅超過) studentized残差: 東京都=+4.61, 鳥取県=+1.54, 大阪府=+1.53

👁️ 直感を一段深める — 残差は「モデルへの反論」

残差 $e_i = y_i - \hat{y}_i$ は「実際 − 予測」、 すなわちモデルが説明しきれなかった部分です。 予測 $\hat{y}$ をモデルの「言い分」、 残差をデータからの「反論」と読むと理解が深まります。 反論が小さく 0 の周りにランダムに散れば、 モデルの言い分は妥当。 反論に向きや大きさの偏り(曲がり・扇形・特定の点だけ巨大)が出れば、 モデルは何かを取りこぼしています。 決定的に重要なのは、 残差は観測できない真の誤差 $\varepsilon_i$ の推定であって $\varepsilon_i$ そのものではないこと。 OLS は $\varepsilon$ を最小化できず、 手元の $e$ の二乗和を最小化するだけです。

上の実測が示す通り、 総人口と死亡数を log で説明した「後」でも、 なお残差 SD ≈ 6953 人のブレが残ります。 これは「人口規模だけでは説明できない県固有の出生力」であり、 残差は単なる誤差ではなく次に投入すべき変数のヒント(若年層比率・婚姻件数など)を指し示すシグナルとして読むのがコツです。

⚠️ 落とし穴を深掘り(重要)

つまずき なぜ危険か 実測での現れ方 / 対処
残差 e と誤差項 ε の混同e は推定後の量で必ず $\sum e_i=0$・$\sum x_ie_i=0$ を満たす。 ε の性質(独立・等分散)とは別物「残差平均が 0 だから仮定 OK」は無意味。 平均 0 は数学的帰結(実測でも ≈ 0.000000)
R² が高ければ残差は無視当てはまりの良さと仮定充足は別軸実測は R²=0.83 と高いのに BP(p=0.018)・White(p=0.0003) が不等分散を有意に検出。 高 R² は免罪符にならない
生残差で分散の異質性を判断y のスケールが大きい点ほど残差も大きく見えるのは自然標準化/studentized 残差でスケールを除いてから fitted 依存を見る。 目視は BP/White 検定と併用
パターンのある残差の見落とし弧=非線形性、 扇形=不等分散、 周期=自己相関対処は二乗項・log 変換GAM/WLS・頑健 SE/時系列モデル と原因別
正規性の過信小標本では Q-Q の裾は揺れやすく、 過検出も起こる実測は歪度 1.70・尖度 5.24 で右裾が重く Shapiro も棄却。 正規性は予測区間に効くが係数の不偏性には効かない点を分離
外れ値=高レバレッジ点 の混同残差大=異常ではない。 X 空間の極端さ(leverage)は別軸残差・leverage・Cook を3 点セットで。 恣意的削除でなく ロバスト回帰・感度分析で対処
自己相関(時系列)の放置系列相関があると SE が過小になり p 値が甘くなる自己相関は DW/Ljung-Box/ACF で確認。 県データ(クロスセクション)では並び順に意味がなく DW=1.78 は解釈対象外
残差の見た目だけで判断同じ図でも「異常」の判断に主観差が出る目視(散布図・残差プロット・Q-Q)と検定(BP/White/DW/Shapiro)を必ず併用

📝 より正確な分析(補足):本ページ他所(実値計算Python 実装節)では影響点を「東京・神奈川が突出」と記していますが、 冒頭モデルを実測すると 4/n=0.085 の閾値を明確に超えるのは東京都のみ(Cook=1.49)で、 神奈川県は Cook≈0.039 と閾値未満でした。 大阪府(0.097)・北海道(0.071)・鳥取県(0.069)が東京都に次ぎますが、 いずれも東京都とは桁が違います。 「大都市が一律に影響点」ではなく、 東京都が単独で係数を強く左右するのがこのモデルの実像です。

🚀 発展 — 残差から広がる診断ツール

残差を出発点に、 線形回帰の 4 仮定を体系的に点検する道具立てを整理します。

💬 実務の型:散布図 → 残差プロット → Q-Q → 影響度(leverage・Cook)の順で毎回見る。 このモデルなら「不等分散が有意・東京都が単独影響点・右裾が重い」まで実測から言えるので、 次の一手は「目的変数を log 化して 重回帰を組み直す」「東京都を除いた感度分析」「ロバスト回帰で係数の頑健性を確認」となります。

🔗 関連ページ(このサイト内)

最小二乗法 OLS 線形回帰 重回帰 決定係数 R² 外れ値 正規性 自己相関 対数変換 GAM ロバスト回帰 相関係数 散布図 多重共線性

※ 不等分散・Q-Q プロット・てこ比・Cook の距離・Breusch-Pagan 検定・Durbin-Watson 統計量は本サイトに独立ページが未整備のため、 本文中でテキスト解説に留めています。