渋谷駅前で働くデータサイエンティストのブログ

元祖「六本木で働くデータサイエンティスト」です / 道玄坂→銀座→東京→六本木→渋谷駅前

何故今日においても回帰分析の理論的基礎を勉強しておくべきなのか

先日のことですが、以下のredtea(@Syuiro_2)さんの記事をお見かけしました。

これがもう本当に素晴らしい回帰分析の解説記事で、もう少し色々書き足すだけでかの佐和本*1の現代版として書籍化できるのではないか、というほどの優れた内容です*2。発展的話題として最近時々話題になる二重機械学習(Double/Debiased Machine Learning)についても触れられており、大いに勉強になりました。僕が四の五の論じる前に、まずは皆様にはぜひご一読いただければと思います。もっと言ってしまえば、以下に僕が記す戯言のほぼ全てはこちらの記事の内容で網羅されていますので、読む必要がないとすら言えます(笑)。


で、そのredteaさんの記事の最後のLevel 6の節を読むと、こう書かれています。

Level 6: 哲学的問いへ

最後のレベルでは、これまでの「回帰」という概念そのものを問い直します。が、私がこのレベルには到底到達していないので書けません笑

こんなのがあるのかもしれませんし、ないのかもしれません。Level 5より上位の理解、または別観点の理解がある方は是非執筆していただけますと嬉しいです。

「回帰」という概念そのものを問い直す、という哲学的問いに対しては僕も全く答えられませんが(笑)、「何故今日においてもこれらの回帰分析の理論的基礎を学ぶべきなのか」という実務家観点から語るポエムなら書けそうな気がします。ということで、相変わらずネタ切れ続きにつき他人様の記事をネタに何か書こうという浅ましさ加減で恐縮ですが以下につらつらと綴ってみようと思います。

「『説明』のための多変量解析=線形モデル族=回帰分析」となりがちな故に回帰分析は多用されやすい


 y_i = \beta_0 + \beta_1 x_{i1} + \beta_2 x_{i2} + \dots + \beta_p x_{ip} + \epsilon_i

皆さんも良くご存知のように、回帰分析は一般に「多変量解析」の代表例として多用されやすい統計的学習モデルの一つです。理由を挙げたらキリがないかと思いますが、基本的には上記のモデル式が示すように「説明変数を沢山盛り込める」点と「モデルの解釈が直感的で分かりやすい」点が挙げられるのではないでしょうか。


前者は論を俟たないでしょう。「重」回帰分析の語が示す通りで、サンプルサイズさえ十分にあれば(≒ランク落ちの問題さえなければ)、そして各種精度の問題さえ許容できれば、事実上幾らでも説明変数を付け足していくことが出来ます。特にビジネス上の各種データ分析においては「要因分析」と言えば鉄板中の鉄板のテーマであり、考えられる限りの多数の要因の中から意味のあるものを選びたい……というケースではうってつけのアプローチです。


後者についてはこのブログで大昔*3描いたこの図が分かりやすいかと思います。つまり、素朴に解釈すれば「その説明変数の回帰係数が大きければ大きいほど目的変数の増加に貢献する」「その説明変数の回帰係数がプラス(マイナス)なら目的変数に対して増やす(減らす)方向に働く」というように、極めて直感的に解釈できます。


勿論、線形モデルのような「単なる線形和」の関係が森羅万象全てに当てはまるとは限りませんし、実際そこを考慮して工夫されたり新たに考案されたりした統計的学習モデルは他にも沢山あります。しかしながら、その説明変数の多さから表現され得る自由度の高さもあり、極めて柔軟に運用できるモデルであるということで、分野を問わず回帰分析は広く用いられているということだと個人的には理解しています。


だが現実の分析課題においては、回帰分析が正しい結果を返すための理論的な前提が満たされないことが多い


ということで良いことずくめに見える回帰分析ですが、以前佐和本を取り上げた際にも強調した通り、割と細かい理論的前提が求められる代物でもあります。代表的なものを佐和本から引用すると、

(4.11)  \mathbf{y} = \mathbf{X} \mathbf{\beta} + \mathbf{\epsilon}

と書くとき、 \mathbf{X} \mathbf{\epsilon}は、以下の仮定を満たす。

仮定1  E(\mathbf{\epsilon}) = 0.
仮定2  V(\mathbf{\epsilon}) = \sigma^2 \mathbf{I},  \sigma^2は正定数である。
仮定3  rank ~ \mathbf{X} = p.

なお n \times p行列 \mathbf{X}の要素は、固定された(非確率的)変数値とする。

の、ようになっています。これらの前提は割と直感的にも分かりやすいものだと思いますが、きちんと定式化された内容を覚えておくことは重要です。ちなみに上のイラストはこの佐和本からの引用箇所をNano Banana 2にまとめさせたものです*4


なのですが、これらの前提を綺麗に満たしているデータの方が現実世界では多数派だと思った方が無難です。例えば、前回の記事でも取り上げたトレンドを伴う時系列データがその筆頭で、モロに仮定1に反している上に、往々にして仮定2も満たさなかったりします。


仮定3に従わないという意味では、これまた以前の記事でも取り上げた多重共線性が当てはまります。これは「予測」には殆ど影響しない代わりに、回帰係数にバイアスがかかるため「説明」には大きな悪影響を及ぼします。


なお、除外変数バイアスという概念も回帰分析の「説明」の正確性に影響します。これは「本来含められるべき説明変数が回帰モデルに含まれないがために、その変数が本来担うべきだった寄与度が既にモデルに含まれている説明変数に上乗せされることで、回帰係数にバイアスが生じる」というものです。どちらかというと、実社会で行われる回帰分析の多くがこれに侵されていると言った方が妥当かもしれません。


また、回帰分析というと使い古された時代遅れの分析手法だと思ってしまう人が今時だと多そうなイメージがありますが、そんなことはありません。例えば、最近だとredteaさんの記事の後ろの方でも取り上げられた通り、今流行りの二重機械学習(Double/Debiased Machine Learning)でも回帰分析は用いられます。例として以下にGeminiに書かせたデモコードを貼っておきます*5

import numpy as np
import pandas as pd
from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import KFold
from sklearn.linear_model import LinearRegression
import matplotlib.pyplot as plt

# ==========================================
# 1. データ生成 (Data Generation)
# ==========================================
np.random.seed(71)
n_samples = 2000
n_features = 10

# 交絡因子X (10次元の標準正規分布)
X = np.random.normal(size=(n_samples, n_features))

# 介入変数T (Xの一部と非線形な関係を持つ + ノイズ)
# X[:, 0]とサインカーブ、X[:, 1]と2乗の関係を持つとする
np.random.seed(72)
T = np.sin(X[:, 0]) + X[:, 1]**2 + np.random.normal(size=n_samples)

# 目的変数Y
# ★ 知りたい真の因果効果 (ATE) = 2.0
true_ate = 2.0

# YもXの一部と非線形な関係を持つ (交絡が存在する)
np.random.seed(73)
Y = true_ate * T + np.cos(X[:, 0]) + 2 * X[:, 1] + np.random.normal(size=n_samples)

print(f"【設定】真の因果効果 (True ATE): {true_ate:.3f}\n")

# ==========================================
# 2. 比較用:単純なアプローチ(ナイーブなモデル)
# ==========================================
# パターンA: 交絡因子Xを完全に無視した単回帰
lr_naive = LinearRegression()
lr_naive.fit(T.reshape(-1, 1), Y)
print(f"比較1 (Tのみの単回帰): {lr_naive.coef_[0]:.3f} -> 交絡を無視しているためバイアスがかかる")

# パターンB: 交絡因子Xを考慮するが、線形回帰として投入 (重回帰)
X_with_T = np.hstack([T.reshape(-1, 1), X])
lr_multiple = LinearRegression()
lr_multiple.fit(X_with_T, Y)
print(f"比較2 (TとXの重回帰): {lr_multiple.coef_[0]:.3f} -> Xの非線形性を捉えきれずバイアスが残る\n")

# ==========================================
# 3. Double Machine Learning (DML) のスクラッチ実装
# ==========================================
# K-Fold交差適合 (Cross-fitting) の設定
n_splits = 5
kf = KFold(n_splits=n_splits, shuffle=True, random_state=74)

# 残差を格納する配列を用意
Y_residuals = np.zeros(n_samples)
T_residuals = np.zeros(n_samples)

# 非線形関係を捉えるための機械学習モデル (ランダムフォレスト)
# ※過学習を防ぐためハイパーパラメータは適度に調整
model_y = RandomForestRegressor(n_estimators=100, max_depth=5, random_state=75)
model_t = RandomForestRegressor(n_estimators=100, max_depth=5, random_state=76)

print("DMLの交差適合 (Cross-fitting) を実行中...")

for fold, (train_idx, test_idx) in enumerate(kf.split(X)):
    # 訓練用とテスト用(残差計算用)にデータを分割
    X_train, X_test = X[train_idx], X[test_idx]
    Y_train, Y_test = Y[train_idx], Y[test_idx]
    T_train, T_test = T[train_idx], T[test_idx]
    
    # [ステップ1] Yの残差化: XからYを予測
    model_y.fit(X_train, Y_train)
    Y_pred = model_y.predict(X_test)
    Y_residuals[test_idx] = Y_test - Y_pred
    
    # [ステップ2] Tの残差化: XからTを予測
    model_t.fit(X_train, T_train)
    T_pred = model_t.predict(X_test)
    T_residuals[test_idx] = T_test - T_pred

# [ステップ3] 最終ステージ: Yの残差をTの残差で単回帰 (切片なし)
dml_ols = LinearRegression(fit_intercept=False)
dml_ols.fit(T_residuals.reshape(-1, 1), Y_residuals)
dml_ate = dml_ols.coef_[0]

print(f"\n【結果】DMLによる推定因果効果: {dml_ate:.3f}")
print(f"-> 真の因果効果 ({true_ate:.3f}) と比較してみてください\n")

# ==========================================
# 4. 可視化: 残差同士のプロット (FWL定理の視覚化)
# ==========================================
plt.figure(figsize=(8, 6))
plt.scatter(T_residuals, Y_residuals, alpha=0.3, label="Data points")
plt.plot(T_residuals, dml_ols.predict(T_residuals.reshape(-1, 1)), 
         color='red', linewidth=2, label=f"DML Estimate (slope = {dml_ate:.3f})")
plt.xlabel("T Residuals (T independent of X)")
plt.ylabel("Y Residuals (Y independent of X)")
plt.title("Double Machine Learning: FWL Theorem Visualization")
plt.legend()
plt.grid(True)
plt.show()

要は「目的変数Yを交絡変数Xで機械学習によって回帰した残差」と「介入変数Tを交絡変数Xで機械学習によって回帰した残差」同士を回帰すると交絡調整された介入変数Tの目的変数Yに対するATEが求まるというのがFrisch-Waugh-Lovell (FWL) 定理を援用したDMLの主張であり、同時にDMLの肝でもあるわけですが、最後に「残差同士を線形回帰する」以上は2つの残差がどちらとも線形回帰における理論的要件を満たしていることが重要であり*6、満たさない場合はバイアスが残るということを想定しなければならないというわけです。


素朴に考えれば何もしなくても上手くいきそうな気がしてきますが、回帰分析の理論的要件を満たさない典型的なデータとして時系列データが挙げられることは、先述した通りです。トレンドを伴う時系列データはまさにその典型で、適切に回帰できなかった場合は残差に強い系列相関が残る可能性があります。そうすると、当然ながら推定されたATEにも強いバイアスがかかりかねません。


もう一点、そもそも時系列データの場合は1段目で行われる2つの機械学習による回帰分析にも問題が起こり得ます。これは単純な話で、一般的なDMLで行われる素朴なK-folds CVだと系列相関に由来するleakage*7が生じる可能性が否定できないからです。よって、本来であれば「時系列データに特化した交差検証」をきちんと実施する必要があります。これについては上記リンク先の2年前に出た知人の記事が優れた解説となっているので、その推奨に従うべきだと考えています。個人的にはhv-blocked CVが良いのではないかと思いました。


以上はあくまでも一例ですが、MMM (Marketing/Media Mix Modeling)のように根底にあるアプローチが回帰分析だという現代的な分析手法は他にも多くあるわけで、当然ながらそれらの手法には回帰分析と同じ制約が課せられます。しかも、そういった手法が対象とする実世界のデータの多くが回帰分析の理論的前提を満たさないこともまた同様です。そのような現実があればこそ、今日においても回帰分析の理論的基礎は広く学ばれるべきだと個人的には考えています。


回帰分析の結果の信頼性を評価するためにも、その理論的基礎の知識はある程度以上必要


これまで見てきた通り、実世界のデータの多くは回帰分析に求められる理論的前提を満たさないことが多く、場合によってはデータを前処理するなどして幾ら調整してもなおどうにもならないことすら少なくないわけです。ではお手上げなのか?全てを諦めるべきなのか?というとそうでもありません。佐和本6章では、そういった理論的前提から外れたデータに対して回帰分析を行う際にはどうすべきかという指針が示されています。

6. 標準的諸仮定からのズレ
 6.1 誤差項の相関と分散不均一
 6.2 仮説検定
 6.3 正規分布からのズレ
 6.4 残差の分析

具体的な内容は割愛しますが、Durbin-Watson比やQ-Qプロットといった定番の「仮定からの外れ具合」に対する評価方法が取り上げられています。これらの評価によって、目の前に出てきた回帰分析の結果をどこまで信頼して良いかが推し量れるわけで、そこで「ある程度なら信頼できる」となればそれで良いわけですし、「信頼できない」となったら他のアプローチを試すなどの代替手段を検討する余地も出てくるということですね。


しかしながら、そういった「回帰分析の結果の信頼性」を測れるようになるには、これまでに論ってきたような回帰分析の理論的基礎の知識が必要ですし、それがなければそもそもそのために何をしなければならないかも分からないわけです。今時なら「生成AIが全てをやってくれる」というのは確かにその通りですが、そもそもユーザーが認識しておらずプロンプトにもコンテクストにも与えられていない課題意識を生成AIが汲んでくれるとは限りません。今日においても、それらを学ぶべきだと僕が考える所以です。


時には回帰分析だけで完結させず、実験など他のアプローチで補完することも必要


あとは、いつもながらですが「回帰分析だけで完結させない」ことも大事です。過去の観察データに対する分析に頼り切りにせず、積極的に条件統制のなされた介入実験を行ってエビデンスの補強を試みるというのを僕個人はいつでも推奨しています。


勿論完璧な条件統制がされた実験などというものは絵に描いた餅であり、これはこれで面倒な因果推論の対象になることも多い代物ですが、それでも回帰分析一辺倒よりは介入実験を組み合わせる方がよほど信頼性を担保できるはずです。


最後に


ということで、今回も何年も前から繰り返し論ってきた話題の繰り返しのような記事で失礼しました。次回ぐらいは最近の論文のレビューでもやろうかと考えておりますが、いかんせん本業が忙しくてなかなか時間が取れず……ということでお後がよろしいようで。

*1:温故知新:古典的名著『回帰分析』(佐和隆光)を読む - 渋谷駅前で働くデータサイエンティストのブログ

*2:このブログの記事も引用していただき恐縮しております→多重共線性のはなし - 渋谷駅前で働くデータサイエンティストのブログ

*3:13年前らしい

*4:微妙に何か違う気がするんですが………………まぁいっか

*5:Geminiのセンスが悪いのか、最後に出てくるATEの推定値が交絡調整前のバイアスのかかった推定値よりも真の値から外れているのはご愛嬌ということで笑

*6:この場合は単回帰なのでたかだか2つの残差の正規性ぐらいだとは思いますが

*7:各blockの前後からの系列相関=トレンドによる影響が混入する