콘텐츠로 이동

예측 대 추론

자료 분석은 근본적으로 다른 두 목표에 봉사한다. 하나는 결과를 최대한 정확히 예측하는 것이고, 다른 하나는 변수 사이의 관계를 이해하는 것이다. 이 구분이 모든 방법론적 결정을 좌우한다. 어떤 모형을 쓸지, 어떻게 평가할지, 어떤 가정이 중요한지, 결과를 어떻게 해석할지가 모두 여기서 갈린다. 둘을 뒤섞는 것이 응용 실무에서 방법론적 혼란의 가장 흔한 원천이다.

정의 1. 예측과 추론

예측은 보지 못한 자료에서 오차가 최소가 되도록 \(\hat Y = \hat f(X)\)를 추정하는 것을 목표로 한다. \(\hat f\)의 내부 구조는 표본 밖 손실에 비해 부차적이다.

추론은 \(X\)가 \(Y\)와 어떻게 관련되는지 이해하는 것을 목표로 한다. 어떤 변수가 중요한지, 효과의 방향과 크기는 어떤지, 그 관계가 인과적인지, 결론을 얼마나 확신할 수 있는지를 다룬다.

측면 예측 추론
목표 예측 손실 최소화 관계의 이해
모형 선택 가장 잘 예측하는 것 해석 가능한 모형 선호
평가 표본 밖 MSE / AUC \(p\)-값, 신뢰구간, 효과 크기
복잡도 높은 복잡도도 환영 더 단순한 모형 선호
타당성 위협 과적합 모형 오지정, 교란

두 가지 오차 분해

고정된 입력 \(x_0\)에서의 예측에 대해,

\[ \mathbb{E}[(Y - \hat f(x_0))^2] = \underbrace{\sigma^2}_{\text{줄일 수 없는 잡음}} + \underbrace{(\mathbb{E}[\hat f(x_0)] - f^*(x_0))^2}_{\text{편향}^2} + \underbrace{\mathrm{Var}(\hat f(x_0))}_{\text{분산}} \]

분석가가 최소화하는 것은 총예측오차다. 첫 항 \(\sigma^2\)은 어떤 모형으로도 내릴 수 없는 바닥이므로, 실제로 손댈 수 있는 것은 뒤의 두 항뿐이다. 더 복잡한 모형은 이 합이 최소가 될 때까지 편향을 분산과 맞바꾼다.

모수 \(\theta\)에 대한 추론에서는

\[ \mathrm{MSE}(\hat \theta) = \mathrm{bias}(\hat \theta)^2 + \mathrm{Var}(\hat \theta) \]

이지만, \(\hat\theta\)가 특정한 모집단 양을 추정한다는 해석 또한 중요하다. 회귀계수가 \(\beta_j\)의 의미 있는 추정량이 되는 것은 모형이 옳게 지정되었을 때뿐이며, 복잡하고 유연한 추정량은 MSE는 작아도 해석 가능한 목표 모수가 아예 없을 수 있다.

서로 다른 평가 기준

  • 예측: 모형이 보지 못한 자료에서 평가한다. 단순히 떼어놓은 시험 집합, \(k\)-겹 교차검증, 시계열 자료의 경우 시간 기준 분할을 쓴다.
  • 추론: 자료생성 과정에 대한 명시적 가정 아래에서 포함확률과 제1/2종 오류율을 통해 신뢰구간과 \(p\)-값의 타당성을 평가한다. 예측에서 교차검증이 맡는 역할, 곧 가진 자료만으로 성적을 확인하는 절차에 해당하는 것이 \(p\)-값에는 없다. 가정이 맞는지는 대체로 자료 밖의 근거로 따져야 하고, 남는 방책은 자료 분할이나 선택 후 추론처럼 절차를 미리 설계하는 것이다(연습문제 9).

서로 다른 복잡도의 최적점

예측에서는 편향–분산 절충에 따라, 모수를 더하면 시험 MSE가 늘어나기 시작하는 지점까지 복잡도를 허용한다. 다만 이 U자가 항상 그려지는 것은 아니다. 모수 수가 표본 크기를 한참 넘어서면 시험오차가 다시 내려가는 이중 하강이 관찰되며, 현대의 심층 모형은 훈련 자료를 사실상 외울 만큼 복잡한데도 잘 일반화되는 이 영역에서 작동한다. 어느 영역에 있는지는 이론이 아니라 표본 밖 평가가 알려 준다.

추론에서는 모형 복잡도가 개별 모수의 분산을 직접 부풀리고(다중공선성, 약한 도구변수) 그 결과 계수의 해석가능성을 위협한다. 대체로 더 단순한 모형이 선호되는데, 예측 정확도를 다소 잃더라도 그 모수를 특정 모집단 양의 추정대상으로 옹호할 수 있기 때문이다.

한 자료, 두 성적표

모형 복잡도가 개별 모수의 분산을 부풀린다는 말을 가장 날것으로 보여 주는 상황이 강한 다중공선성이다. 상관이 \(0.99\) 인 설명변수 \(x_1, x_2\) 를 만들고 \(y = x_1 + x_2 + \varepsilon\), \(\varepsilon \sim N(0, 1)\) 로 자료를 생성했다. 크기 \(n = 120\) 인 표본을 \(600\) 번 새로 뽑아 매번 최소제곱으로 적합한 뒤, 그때마다 얻은 계수와 시험오차를 나란히 그린 것이 아래 그림이다.

상관이 높은 두 변수에서 계수와 예측이 갈라지는 모습

왼쪽이 추론의 눈이다. 참값은 \((1, 1)\) 인데 \(\hat\beta_1\) 은 \(-1.43\) 에서 \(2.84\) 까지 흩어지고 표준편차가 \(0.67\) 이다. \(\hat\beta_2\) 도 마찬가지이며 둘의 상관은 \(-0.99\) 다. 점들이 직선 \(\beta_1 + \beta_2 = 2\) 위에 실처럼 놓이는 것이 핵심이다. 실제로 합의 표준편차는 \(0.089\) 로 개별 계수의 \(1/7\) 에 불과하다. 자료가 또렷이 식별하는 것은 두 계수의 합이지 각각이 아니다. 어떤 표본에서는 "\(x_1\) 이 전부"라 말하고 다른 표본에서는 "\(x_2\) 가 전부"라 말하게 된다.

오른쪽이 예측의 눈이다. 같은 \(600\) 개의 적합을 시험자료 \(20{,}000\) 개로 채점하면 MSE가 \(0.999\) 에서 \(1.179\) 사이에 모두 들어오고 평균은 \(1.025\) 다. 줄일 수 없는 잡음 \(\sigma^2 = 1\) 바로 위에 붙어 있다. \(\hat\beta_1\) 과 시험 MSE의 상관은 \(-0.07\) 로 사실상 무관하다. \(\hat\beta_1 = -1.4\) 를 보고한 적합이 \(\hat\beta_1 = 2.8\) 을 보고한 적합만큼 잘 맞힌다. 계수가 참값에서 멀어질수록 MSE가 조금씩 커지는 U자 모양이 보이기는 하지만, 가장 나쁜 적합조차 잡음 하한보다 \(18\%\) 높을 뿐이다.

실무에서 우리가 손에 쥐는 것은 이 \(600\) 개 중 하나뿐이고, 그것이 왼쪽 구름의 어디쯤인지는 알 수 없다. 그런데도 시험오차는 어느 표본에서나 좋게 나온다. 예측 성적이 계수 해석을 보증해 주지 못하는 이유가 이것이다. 이 상황에서 추론이 하는 일은 계수를 정확히 맞히는 것이 아니라 맞힐 수 없다고 말해 주는 것이다. 표준오차가 넓게 나오고 신뢰구간이 \(0\) 을 덮는 것이 그 경고이며, 시험오차만 보는 분석에는 이 경고 장치가 아예 없다.

다리를 놓는 방법들

경계는 뚜렷하지 않다.

  • LASSO는 예측을 최적화하면서 변수를 선택한다(추론적 성격의 희소성).
  • SHAP / LIME은 블랙박스 예측에 사후 해석가능성을 부여한다.
  • 인과 기계학습(이중/편향제거 기계학습, 인과 포레스트)은 유연한 방해모수 추정량을 쓰면서도 인과 추정대상에 대해 점근적으로 편향 없는 추정량을 겨냥한다.
  • 컨포멀 예측은 분포 가정 없이 임의의 예측기 주위에 타당한 예측구간을 준다.

이 도구들은 예측의 유연함을 지키면서 추론의 해석가능성이나 불확실성 정량화를 어느 정도 되찾으려는 시도다.

보기 1. 예측 대 추론. \(n = 300\)에서 \(x_1, x_2 \sim N(0,1)\) 독립이고 \(x_3 = 0.8x_1 + N(0,0.5^2)\)이다. 참 구조는 \(y = 3x_1 - 2x_2 + \varepsilon\)(\(\varepsilon \sim N(0,1)\))로 \(x_3\)은 들어 있지 않다. 같은 자료로 추론과 예측을 각각 해 본다.

(1) 세 계수의 표준오차를 이론적으로 구하시오. \(x_3\)을 넣은 대가가 \(x_1\)에 어떻게 나타나는가.

(2) \(200\)개로 적합해 \(100\)개에서 평가할 때 시험 MSE의 기댓값을 구하고, 모의실험과 견주시오.

풀이

(1) 해석적으로. 최소제곱 계수의 분산은

\[ \operatorname{Var}(\hat\beta_j) = \frac{\sigma^2}{n\operatorname{Var}(x_j)}\cdot\mathrm{VIF}_j, \qquad \mathrm{VIF}_j = \frac{1}{1-R_j^2} \]

이고 \(R_j^2\)은 \(x_j\)를 나머지 설명변수에 회귀했을 때의 결정계수다. \(x_2\)는 다른 둘과 독립이므로 \(\mathrm{VIF}_2 = 1\)이고

\[ \operatorname{SE}(\hat\beta_2) = \frac{1}{\sqrt{300}} = 0.0577 \]

이다. \(x_1\)과 \(x_3\)은 서로 얽혀 있다. \(\operatorname{Var}(x_3) = 0.64 + 0.25 = 0.89\)이므로

\[ \operatorname{Corr}(x_1, x_3) = \frac{0.8}{\sqrt{0.89}} = 0.8480, \qquad \mathrm{VIF} = \frac{1}{1-0.8480^2} = 3.560 \]

이다(\(x_2\)가 직교하므로 두 변수 모두 같은 VIF를 갖는다). 따라서

\[ \operatorname{SE}(\hat\beta_1) = \frac{1}{\sqrt{300}}\sqrt{3.560} = 0.1089, \qquad \operatorname{SE}(\hat\beta_3) = \frac{1}{\sqrt{300 \times 0.89}}\sqrt{3.560} = 0.1155 \]

\(x_3\)을 넣은 대가가 \(x_1\)의 표준오차에 \(\sqrt{3.56} = 1.89\)배로 찍힌다. \(x_3\)은 \(y\)에 아무 기여도 하지 않으면서 \(x_1\)의 추정을 두 배 가까이 흐린다. 이것이 공선성의 값이다.

(2) 해석적으로. 설명변수 \(p = 4\)(절편 포함)를 \(n = 200\)으로 추정하므로

\[ E[\text{시험 MSE}] = \sigma^2\left(1 + \frac{p}{n-p-1}\right) = 1 + \frac{4}{195} = 1.0205 \]

다. 추정의 웃돈이 \(2\%\)다. \(x_3\)을 빼면 \(p = 3\)이 되어 \(1.0153\)으로 내려가지만, 그 차이 \(0.005\)는 시험자료 \(100\)개로는 잴 수 없는 크기다(\(\text{MSE}\sqrt{2/100} = 0.14\)).

(1)(2) 수치적으로.

"""같은 자료, 서로 다른 두 목표."""

import numpy as np

rng = np.random.default_rng(42)
n = 300
x1 = rng.standard_normal(n)
x2 = rng.standard_normal(n)

# x3는 x1과 상관이 높지만(상관 약 0.85) y에는 아무 인과효과가 없다.
# 예측에는 도움이 되는데 해석하면 틀리는, 함정 변수다.
x3 = 0.8 * x1 + rng.normal(0, 0.5, n)

# 참 구조: y = 3*x1 - 2*x2 + 잡음.  x3는 들어 있지 않다.
y = 3 * x1 - 2 * x2 + rng.standard_normal(n)

X = np.column_stack([np.ones(n), x1, x2, x3])   # 절편 + 설명변수 3개

# === 목표 1: 추론 — 각 계수가 얼마이고 얼마나 믿을 만한가 ===
# 정규방정식 (X'X)b = X'y 를 풀어 최소제곱 추정량을 얻는다.
beta = np.linalg.solve(X.T @ X, X.T @ y)
y_hat = X @ beta

# 잔차분산 s^2. 자유도는 n - (계수 개수) = 300 - 4.
s2 = ((y - y_hat) ** 2).sum() / (n - 4)

# 계수의 표준오차는 s^2 * (X'X)^{-1} 의 대각원소의 제곱근이다.
se = np.sqrt(s2 * np.diag(np.linalg.inv(X.T @ X)))

# t = beta / SE. 대략 |t| > 2 면 그 계수가 0이라고 보기 어렵다.
# 참 구조에 없는 x3의 t가 작게 나오는지 확인해 보라.
print("Inference:")
for name, b, s in zip(["intercept", "x1", "x2", "x3"], beta, se):
    print(f"  {name:>10s}: beta = {b:+.3f}, SE = {s:.3f}, t = {b/s:+.2f}")

# === 목표 2: 예측 — 새 자료에서 얼마나 잘 맞히는가 ===
# 300개 중 200개로 학습하고 나머지 100개로 평가한다.
# 표준오차도 t값도 계산하지 않는다. 관심은 오직 하나, 시험오차다.
train_idx = rng.choice(n, 200, replace=False)
test_idx = np.setdiff1d(np.arange(n), train_idx)
b_train = np.linalg.solve(X[train_idx].T @ X[train_idx], X[train_idx].T @ y[train_idx])
mse_test = ((y[test_idx] - X[test_idx] @ b_train) ** 2).mean()
print(f"\nPrediction: test MSE = {mse_test:.3f}")

# --- (1)(2) 의 이론값 ---
r13 = 0.8 / np.sqrt(0.89)
vif = 1 / (1 - r13 ** 2)
print(f"\n이론 Corr(x1,x3) = {r13:.4f},  VIF = {vif:.4f}")
print(f"이론 SE: x1 = {np.sqrt(vif / n):.4f}, x2 = {np.sqrt(1 / n):.4f}, "
      f"x3 = {np.sqrt(vif / (n * 0.89)):.4f}")
print(f"이론 E[시험 MSE] = 1 + 4/(200-4-1) = {1 + 4 / 195:.4f}")

출력:

Inference:
   intercept: beta = +0.044, SE = 0.057, t = +0.78
          x1: beta = +3.008, SE = 0.105, t = +28.54
          x2: beta = -2.101, SE = 0.056, t = -37.41
          x3: beta = +0.031, SE = 0.113, t = +0.28

Prediction: test MSE = 0.942

이론 Corr(x1,x3) = 0.8480,  VIF = 3.5600
이론 SE: x1 = 0.1089, x2 = 0.0577, x3 = 0.1155
이론 E[시험 MSE] = 1 + 4/(200-4-1) = 1.0205

세 표준오차가 모두 맞는다. 이론 \(0.1089\) / \(0.0577\) / \(0.1155\)에 관측 \(0.105\) / \(0.056\) / \(0.113\)이다. 어긋남은 \(s\)가 \(\sigma = 1\)의 추정값(\(\hat s = 0.978\))이라는 점과, 실현된 \(X^\top X\)가 모집단 공분산의 \(n\)배와 꼭 같지는 않다는 점에서 온다. 세 값의 비는 이론과 사실상 같다.

시험 MSE는 이론 \(1.0205\)에 관측 \(0.942\)다. \(100\)개로 잰 MSE의 표준오차가 \(\text{MSE}\sqrt{2/100} = 0.14\)이므로 \(0.55\) 표준오차 차이다.

여기서 \(x_3\)은 \(x_1\)과 상관되어 있지만 \(y\)에 인과효과가 없다는 점에 주목하라. 추론 표에서 \(x_3\)의 계수는 \(+0.031\), \(t\) 값은 \(+0.28\)로 \(0\)과 구별되지 않는다(\(x_1\) 너머의 신호를 더하지 않음을 올바르게 짚어낸다). 대가는 \(x_1\)에서 나타난다. (1)에서 유도한 대로 \(x_1\)의 표준오차가 \(x_2\)의 \(\sqrt{3.56} = 1.89\)배로 부풀려졌고, 관측값 \(0.105\) 대 \(0.056\)이 그 비를 그대로 보여 준다.

반면 예측 쪽에서는 \(x_3\)을 빼도 시험 MSE의 기댓값이 \(1.0205\)에서 \(1.0153\)으로 \(0.005\) 줄 뿐이다. 쓸모없는 변수 하나가 추론에서는 표준오차를 두 배 가까이 부풀리지만 예측 성적에는 거의 흔적을 남기지 않는다. 그리고 인과적 결론은 어느 쪽에서도 달라지지 않는다.

연습문제

연습문제 1. 다음 각 연구 질문에서 주된 목표가 예측인지 추론인지 밝히고, 방법 선택에 어떤 함의가 있는지 설명하라.

(a) 능력과 가정 배경을 통제할 때 대학 학위가 평생 소득을 높이는 원인이 되는가? (b) 앞으로 30일 안에 이탈할 가능성이 가장 높은 고객은 누구인가? (c) 학급 규모가 학생의 시험 점수에 미치는 효과는 무엇인가? (d) 다음 달 지역 전력 수요를 얼마나 정확히 예측할 수 있는가? (e) 특정 유전 변이가 알츠하이머병 위험을 높이는가?

풀이

(a) 추론 — 인과효과를 추정하고 검정한다. 방법: 통제변수를 포함한 회귀, 도구변수, 자연실험. 해석가능성이 필수적이다. (b) 예측 — 위험 고객을 정확히 식별한다. 유연한 알고리즘(그래디언트 부스팅 트리, 신경망)이 적절하다. (c) 추론 — 인과 추정대상. 준실험적 방법(회귀 불연속, 학급 규모 무작위 실험)이 필요하다. (d) 예측 — 예측오차를 최소화한다. ARIMA, 가공된 시계열 특성에 대한 그래디언트 부스팅, 신경망 예측 모형 등. (e) 추론 — 집단 구조와 다른 교란요인을 통제하면서 효과 크기와 유의성을 추정한다. 본페로니나 FDR 통제를 적용한 GWAS 방법론.

연습문제 2. 어떤 팀이 관찰적 건강 자료로 XGBoost 모형을 학습시킨 뒤, "변수 중요도"에서 혈압이 뇌졸중의 가장 강한 예측변수로 나타났다고 보고한다. 이것이 왜 혈압을 낮추면 인과적으로 뇌졸중 위험이 줄어든다는 뜻이 아닌지 설명하라.

풀이

트리 앙상블의 변수 중요도는 예측적 개념이다. 어떤 특성이 여러 트리에 걸쳐 표본 내 손실을 줄이는 데 얼마나 기여했는지를 측정한다. 어떤 특성은 인과적이지 않으면서도 예측력이 아주 높을 수 있다.

  • 교란: 혈압과 뇌졸중은 많은 공통 원인(나이, 비만, 당뇨)을 공유한다. 모형은 혈압을 인과적 동인이 아니라 그 밑바탕 위험들의 대리변수로 쓴다.
  • 역인과: 진행 중인 심혈관 손상이 혈압을 높일 수 있으므로, 혈압은 부분적으로 하류 지표로서 뇌졸중과 상관된다.
  • 매개: 참된 인과 경로가 있더라도 혈압이 (예컨대) 나트륨 섭취의 효과를 일부 매개하고 있을 수 있으며, 혈압에 대한 개입이 자연 상태의 상관을 그대로 재현하지 않을 수 있다.

혈압 강하 개입의 인과효과는 관찰적 변수 중요도가 아니라 무작위 시험(예: SPRINT 시험)으로 확립된다. 그런 시험들은 실제로 효과가 있음을 확인해 주었지만, 개입으로 얻는 위험 감소폭과 관찰연구에서 보이는 연관의 크기가 같다고 볼 근거는 없다. "효과가 있다"와 "효과가 관찰된 연관만큼 크다"는 서로 다른 주장이다.

연습문제 3. 같은 훈련 자료로 두 모형을 만들었다. 하나는 \(R^2_{\text{train}} = 0.45\)인 선형회귀이고, 다른 하나는 \(R^2_{\text{train}} = 0.95\)인 랜덤 포레스트다. 왜 \(R^2_{\text{train}}\)으로 둘을 비교하는 것이 부적절한가? 적절한 비교는 무엇인가?

풀이

\(R^2_{\text{train}}\)은 표본 내 적합도의 척도다. 충분히 유연한 모형(랜덤 포레스트, 깊은 트리)은 훈련 자료를 외움으로써 원하는 만큼 잘 적합할 수 있고, 진짜 신호가 없어도 \(R^2_{\text{train}}\)을 1에 가깝게 밀어 올린다. 선형회귀는 엄격한 모수적 형태 때문에 그럴 수 없으므로 그 \(R^2_{\text{train}}\)은 참된 신호에 의해 제한된다.

적절한 비교는 떼어놓은 시험 집합에서의 \(R^2\)(또는 동등하게 \(k\)-겹 교차검증 \(R^2\))이다. 랜덤 포레스트의 시험 \(R^2\)도 0.95라면 진짜 신호를 포착한 것이고, 훈련은 0.95인데 시험이 0.30으로 떨어진다면 과적합한 것이며 표본 밖에서는 사실 선형모형보다 못한 것이다.

이는 1.3절 지도학습의 연습문제 6, 그리고 앞 절 두 패러다임의 강점과 한계의 연습문제 3·7과 같은 교훈이다. 정직한 평가를 위해 떼어놓은 시험 집합은 타협할 수 없는 요소다. 여기서 새로 더하는 점은 이 기준이 예측 쪽에만 있다는 것이다. 추론 쪽에는 대응하는 심판이 없고, 그래서 가정을 명시하는 일이 그 자리를 대신한다.

연습문제 4. 회귀계수에 대한 95% 신뢰구간이 명시적 가정(옳은 함수 형태, 누락된 교란요인 없음, 옳은 오차 구조) 아래에서만 의미를 갖는 반면, 95% 컨포멀 예측구간은 사실상 아무 가정도 요구하지 않는 이유를 설명하라. 이 가정 차이의 대가는 무엇인가?

풀이

회귀계수의 신뢰구간은 특정한 모집단 모수(다른 변수를 고정했을 때의 기울기)의 불확실성을 추정한다. 선형모형이 틀렸다면(교란요인 누락, 비선형성, 이분산성) 신뢰구간의 포함확률이 어긋날 수 있다. 표본 변동성 때문이 아니라 모형 오지정 때문이다. 타당성이 모형에 달려 있는 것이다.

컨포멀 예측구간은 훈련 자료와 시험 자료가 교환 가능하다는 가정만으로 "\(X = x\)일 때 \(Y\)가 어디쯤 있을까?"를 추정한다. 블랙박스 예측기를 포함해 어떤 밑바탕 모형에 대해서도 타당하다.

대가: 컨포멀 구간은 어떤 구조 모수가 아니라 \(X\)가 주어졌을 때 \(Y\)의 분포를 가리킨다. 가정이 약한 만큼 같은 포함확률에서 모수적 신뢰구간보다 넓다. 개입의 효과는 알려주지 못하며, 세상이 훈련 자료처럼 계속 움직인다면 나올 법한 결과의 범위만 알려준다.

모형을 신뢰하고 구조 모수의 해석을 원할 때는 모수적 신뢰구간을 쓰고, 유연한 예측기로부터 타당한 예측구간만 원할 때는 컨포멀 구간을 쓴다.

연습문제 5. 어떤 소매업체가 추천 알고리즘을 A/B 테스트해 사용자당 매출이 2% 상승함을 확인했다. 이제 (a) 전면 도입 시 추가 매출이 얼마나 될지, (b) 새 알고리즘이 왜 더 잘 작동하는지 알고 싶어 한다. 어느 질문이 예측이고 어느 것이 추론인지, 각각 어떤 분석이 필요한지 논하라.

풀이

(a) 예측: 전면 도입하면 매출이 얼마나 오를까? 이것은 예측 문제다. A/B 테스트가 불편인 점추정값(+2%)과 표집 불확실성을 이미 반영한 신뢰구간을 준다. 추가로 고려할 것은 규모 효과(테스트 모집단이 도입 대상 모집단과 다를 수 있음), 신기성 효과(짧은 테스트가 정상 상태의 상승분을 과장할 수 있음), 구성 변화(테스트가 특정 시즌에 이루어졌음)다. 이런 동학을 반영한 시계열 예측 모형을 도입하는 것이 적절하며, 목표는 다음 분기 매출을 정확히 맞히는 것이다.

(b) 추론(구체적으로는 인과 기제): 새 알고리즘은 왜 더 잘 작동할까? A/B 테스트는 효과를 확인해 주지만 기제는 알려주지 않는다. 가능한 설명으로는 더 나은 개인화, 롱테일 상품의 노출 증가, 마진이 높은 상품에의 노출, 결정 피로 감소 등이 있다. 이들을 구분하려면 제거 실험(구성요소를 하나씩 꺼가며 다시 A/B 테스트)과 행동 경로 분석(추천 후 구매 비율이 올랐는지, 아니면 무관한 탐색이 늘었는지)이 필요하다. 이것은 예측이라기보다 기제에 대한 과학적 추론에 가깝다.

연습문제 6. 자료생성 과정에 대한 가정이 추론에서는 핵심이지만 예측에서는 부차적인 이유는 무엇인가? 이를 이용해, 복잡하고 유연한 모형이 예측에서는 성공하면서도 추론 상황에서는 흔히 실패하는 실무적 역설을 설명하라.

풀이

추론은 자료생성 과정을 전제로 해서만 정의되는 양(모수 \(\theta\), 처리효과, 한계효과)을 겨냥한다. "\(Z\)를 통제했을 때 \(X\)가 \(Y\)에 미치는 효과"라고 말하려면 그런 효과가 존재하는 모형을 전제해야 한다. 추정량의 타당성은 그 모형이 대체로 옳다는 데 달려 있다.

예측은 구조 모수를 정의하지 않고 미래의 \(Y\) 값을 직접 겨냥한다. 정확한 예측을 내놓는 모형은 해석 가능한 구조가 전혀 없어도 유용하다.

역설: 복잡하고 유연한 모형은 그 패턴이 인과적이든 아니든 \((X, Y)\)의 풍부한 패턴을 포착하기 때문에 잘 예측한다. 그런데 "풍부한 패턴"에는 교란된 연관성, 역인과, 표본 선택 인공물 등 추론을 무효로 만드는 것들이 모두 포함된다. 어떤 신경망이 천 개의 관찰적 특성으로 심장질환을 완벽히 예측하면서도, 어느 특성에 개입해야 질병이 줄어드는지에 대해서는 아무 지침도 주지 못할 수 있다. 그 모형은 예측 정확도는 높고 인과적 타당성은 0이다.

교훈은 이렇다. 지금 유행하는 것이 아니라 질문에 따라 방법을 골라라. 예측 도구와 추론 도구는 서로 다른 질문에 답한다.

연습문제 7. 연습문제 4의 컨포멀 예측을 구현하라. 오차 분포가 정규가 아닐 때 모수적 예측구간과 어떻게 달라지는지 비교하라.

풀이

분할 컨포멀 절차. 자료를 학습·보정·시험으로 나눈다. 학습 자료로 모형을 적합하고, 보정 자료에서 잔차의 절댓값을 구해 그 \((1-\alpha)\) 분위수 \(q\)를 잡는다. 새 점의 예측구간은 \(\hat{y} \pm q\)다.

import numpy as np
import statsmodels.api as sm

rng = np.random.default_rng(0)

def compare(error_type):
    n = 2000
    x = rng.uniform(-2, 2, n)
    e = rng.normal(0, 1, n) if error_type == "정규" else rng.standard_t(2, n) * 0.7
    y = 1 + 2 * x + e

    tr, cal, te = np.split(rng.permutation(n), [1000, 1500])
    X = sm.add_constant(x)
    fit = sm.OLS(y[tr], X[tr]).fit()

    # 모수적 예측구간 — 정규 오차를 가정한다
    pi = fit.get_prediction(X[te]).summary_frame(alpha=0.1)
    cov_par = ((y[te] >= pi["obs_ci_lower"]) & (y[te] <= pi["obs_ci_upper"])).mean()
    w_par = (pi["obs_ci_upper"] - pi["obs_ci_lower"]).mean()

    # 분할 컨포멀 — 아무 분포도 가정하지 않는다
    resid = np.abs(y[cal] - fit.predict(X[cal]))
    q = np.quantile(resid, np.ceil(0.9 * (len(cal) + 1)) / len(cal))
    pred = fit.predict(X[te])
    cov_con = ((y[te] >= pred - q) & (y[te] <= pred + q)).mean()

    print(f"오차 {error_type:>4}:  모수적 포함률 {cov_par:.4f} (폭 {w_par:.3f})"
          f"   컨포멀 {cov_con:.4f} (폭 {2 * q:.3f})")

print("목표 포함률 0.90")
compare("정규")
compare("t(2)")

출력:

목표 포함률 0.90
오차   정규:  모수적 포함률 0.9000 (폭 3.325)   컨포멀 0.9200 (폭 3.450)
오차 t(2):  모수적 포함률 0.9440 (폭 5.615)   컨포멀 0.9040 (폭 4.130)
오차 모수적 컨포멀
정규 \(0.900\) (폭 \(3.33\)) \(0.920\) (폭 \(3.45\))
\(t(2)\) \(0.944\) (폭 \(5.62\)) \(0.904\) (폭 \(4.13\))

가정이 맞을 때는 모수적 구간이 조금 더 좁다. 가정이 틀리면 역전된다. \(t(2)\) 오차에서 모수적 구간은 포함률이 \(0.944\)로 목표를 넘기는 대신 폭이 \(36\%\) 더 넓다. 두꺼운 꼬리 때문에 추정된 \(\sigma\)가 부풀려졌기 때문이다. 컨포멀은 \(0.904\)로 목표를 정확히 맞춘다.

컨포멀이 요구하는 것은 교환가능성뿐이다. 자료가 i.i.d.(더 약하게는 교환가능)이기만 하면, 모형이 무엇이든 어떻게 틀렸든 유한표본에서 포함률이 보장된다. 형편없는 모형을 쓰면 구간이 넓어질 뿐 포함률은 지켜진다.

대가는 무엇인가.

  • 주변 포함률만 보장한다. 전체적으로 \(90\%\)일 뿐, \(x\)가 특정 영역인 점들에서 \(90\%\)라는 보장은 없다. 조건부 포함을 원하면 분위수 회귀 기반 컨포멀 같은 변형이 필요하다.
  • 모수에 대해서는 아무 말도 하지 않는다. "\(\beta_1\)이 얼마인가"에 답하지 못한다. 예측구간이지 신뢰구간이 아니다.
  • 자료를 나누어 써야 한다. 보정 자료만큼 학습 자료가 줄어든다.

이것이 이 절의 주제를 압축한다. 추론은 강한 가정을 지불하고 모수에 대한 진술을 얻고, 예측은 가정을 거의 지불하지 않는 대신 개별 관측에 대한 진술만 얻는다. \(\square\)

연습문제 8. 본문의 "서로 다른 복잡도의 최적점"을 수치로 보여라. 능형회귀가 예측을 개선하면서 동시에 계수를 편향시키는 것을 확인하라.

풀이
import numpy as np
from sklearn.linear_model import LinearRegression, Ridge

rng = np.random.default_rng(1)
n, p, B = 60, 20, 500
beta = np.zeros(p); beta[:5] = 1.0

results = {"OLS": ([], []), "능형 (alpha=30)": ([], [])}
for _ in range(B):
    X = rng.normal(0, 1, (n, p)); y = X @ beta + rng.normal(0, 3, n)
    Xt = rng.normal(0, 1, (5000, p)); yt = Xt @ beta + rng.normal(0, 3, 5000)
    for name, model in [("OLS", LinearRegression()), ("능형 (alpha=30)", Ridge(alpha=30))]:
        m = model.fit(X, y)
        results[name][0].append(m.coef_[0])
        results[name][1].append(((m.predict(Xt) - yt) ** 2).mean())

for name, (coefs, mses) in results.items():
    c = np.array(coefs)
    print(f"{name:>16}: 계수 평균 {c.mean():.4f} (참 1.0)"
          f"   편향 {c.mean() - 1:+.4f}   표준편차 {c.std():.4f}"
          f"   시험 MSE {np.mean(mses):.4f}")

출력:

             OLS: 계수 평균 1.0037 (참 1.0)   편향 +0.0037   표준편차 0.4850   시험 MSE 13.9593
   능형 (alpha=30): 계수 평균 0.6169 (참 1.0)   편향 -0.3831   표준편차 0.2709   시험 MSE 11.3603
계수 편향 계수 표준편차 시험 MSE
OLS \(+0.004\) \(0.485\) \(13.96\)
능형 \(\mathbf{-0.383}\) \(0.271\) \(\mathbf{11.36}\)

정확히 반대 방향의 승자가 나온다. 추론 기준(불편성)으로는 OLS가 이기고, 예측 기준(시험 MSE)으로는 능형이 \(19\%\) 차이로 이긴다.

왜 그런가. 능형은 계수를 \(0\) 쪽으로 수축시킨다. 그 대가로 편향 \(-0.383\)을 얻지만 표준편차가 \(0.485\)에서 \(0.271\)로 거의 절반이 된다. 예측오차는 편향의 제곱과 분산의 합이므로, 분산 감소가 편향 증가를 압도한다.

\[ \text{예측 MSE} = \underbrace{\text{편향}^2}_{0.147} + \underbrace{\text{분산}}_{\text{크게 감소}} + \underbrace{\sigma^2}_{\text{줄일 수 없음}} \]

함의가 실무적으로 중요하다. 능형·라소·부스팅 같은 방법의 계수를 효과크기로 읽으면 안 된다. 수축은 의도적인 편향이며, 그 편향의 크기는 \(\lambda\)와 자료에 따라 달라져 해석할 수 없다.

라소는 한 걸음 더 나아가 계수를 정확히 \(0\)으로 만드는데, 이는 "효과가 없다"는 뜻이 아니라 "이 표본에서 예측에 기여하지 않는다"는 뜻이다. 상관된 예측변수 중 하나만 살아남는 일이 흔하며, 어느 것이 살아남을지는 우연에 가깝다.

최적 복잡도가 목적에 따라 다르다는 것이 본문의 요점이고, 이 표가 그것을 한 줄로 보여 준다. \(\square\)

연습문제 9. "한쪽을 다른 쪽인 척하기"의 가장 흔한 형태를 수치로 보여라. 모형을 고른 뒤 같은 자료로 \(p\) 값을 보고하면 1종 오류가 어떻게 되는가?

풀이
import numpy as np
import statsmodels.api as sm

rng = np.random.default_rng(0)
K, B, n = 20, 4000, 100

naive = honest = 0
for _ in range(B):
    X = rng.normal(0, 1, (n, K))
    y = rng.normal(0, 1, n)                    # 참 효과가 하나도 없다

    pvals = np.array([sm.OLS(y, sm.add_constant(X[:, j])).fit().pvalues[1]
                      for j in range(K)])
    if pvals.min() < 0.05:                     # 가장 유의한 변수를 골라 보고
        naive += 1
    if sm.OLS(y, sm.add_constant(X)).fit().f_pvalue < 0.05:   # 전체 F 검정
        honest += 1

print(f"가장 유의한 변수 하나를 골라 p<0.05 로 보고: 1종 오류 {naive / B:.4f}")
print(f"전체 F 검정으로 정직하게 판정:              1종 오류 {honest / B:.4f}")

출력:

가장 유의한 변수 하나를 골라 p<0.05 로 보고: 1종 오류 0.6390
전체 F 검정으로 정직하게 판정:              1종 오류 0.0485

참 효과가 하나도 없는데 \(63.9\%\)의 경우에 "유의한 발견"이 나온다. 명목 수준의 \(13\)배다. 전체 \(F\) 검정은 \(0.0485\)로 정확하다.

왜 이렇게 심한가. 보고된 \(p\) 값은 "고정된 변수 하나를 검정했을 때"의 확률인데, 실제로 한 일은 \(20\)개 중 최솟값을 고른 것이다. 최솟값의 분포는 개별 \(p\) 값의 분포와 전혀 다르다.

이것이 왜 두 패러다임의 충돌인가. 변수를 자료로 고르는 것은 예측 패러다임의 정당한 절차다. 교차검증으로 평가하는 한 아무 문제가 없다. 문제는 그렇게 고른 모형에 대해 추론 패러다임의 산물(\(p\) 값, 신뢰구간)을 보고하는 것이다. 그 \(p\) 값은 선택 과정을 고려하지 않으므로 무의미하다.

같은 오류가 여러 이름으로 나타난다. 단계적 회귀 후의 \(p\) 값, 라소로 고른 변수에 대한 OLS \(p\) 값(순진한 재적합), 교차검증으로 초모수를 고른 뒤 같은 자료로 낸 신뢰구간.

처방.

  • 자료 분할. 선택용과 추론용을 나눈다. 가장 단순하고 확실하다.
  • 선택 후 추론. 선택 사건을 조건부로 하는 분포를 유도한다(선택적 추론, 라소의 polyhedral lemma).
  • 탈편향 라소. 라소 추정값의 편향을 명시적으로 보정해 타당한 신뢰구간을 만든다.
  • 가장 정직한 방법: 무엇을 자료로 골랐는지 밝히고, 그 \(p\) 값을 확증이 아니라 탐색적 서술로 보고한다. \(\square\)

연습문제 10. 연습문제 2가 "예측력이 높다고 인과효과가 아니다"를 다루었다면, 반대 방향도 성립한다. 아주 유의한 변수가 예측에는 거의 쓸모없을 수 있음을 보여라.

풀이
import numpy as np
import statsmodels.api as sm

rng = np.random.default_rng(1)
n = 100_000
x1 = rng.normal(0, 1, n)
x2 = rng.normal(0, 1, n)
y = 0.05 * x1 + 1.5 * x2 + rng.normal(0, 1, n)      # x1 의 참 효과는 아주 작다

full = sm.OLS(y, sm.add_constant(np.column_stack([x1, x2]))).fit()
print(f"x1: 계수 {full.params[1]:.4f}   p = {full.pvalues[1]:.3e}")
print(f"x2: 계수 {full.params[2]:.4f}   p = {full.pvalues[2]:.3e}")

reduced = sm.OLS(y, sm.add_constant(x2)).fit()
print(f"\nR^2:  x2 만 {reduced.rsquared:.6f}"
      f"   x1 을 넣으면 {full.rsquared:.6f}"
      f"   증가분 {full.rsquared - reduced.rsquared:.6f}")

출력:

x1: 계수 0.0486   p = 5.148e-53
x2: 계수 1.5014   p = 0.000e+00

R^2:  x2 만 0.693397   x1 을 넣으면 0.694116   증가분 0.000719

\(x_1\)의 \(p\) 값은 \(5 \times 10^{-53}\)이다. 압도적으로 유의하다. 그런데 \(x_1\)을 모형에 넣어 얻는 \(R^2\) 증가분은 \(0.0007\), 곧 설명력의 \(0.07\%\)다.

두 질문이 다른 것을 묻기 때문이다.

  • \(p\) 값은 "효과가 정확히 \(0\)인가" 를 묻는다. \(n = 10^5\)이면 \(0.05\)짜리 효과도 확실히 \(0\)이 아님을 보일 수 있다.
  • \(R^2\) 증가분은 "이 변수가 개별 예측을 얼마나 개선하는가" 를 묻는다. 잡음의 표준편차가 \(1\)인데 기여가 \(0.05\)면 사실상 보이지 않는다.

실무에서 이 구분이 중요한 곳.

상황 어느 쪽이 중요한가
약의 부작용이 존재하는지 판정 \(p\) 값 / 효과의 존재
개별 환자의 예후 예측 예측 개선
정책 변수의 총량 효과 추정 효과크기와 신뢰구간
특징을 모형에 넣을지 결정 예측 개선(과 비용)

유전체 연구가 전형적인 예다. 수백 개의 변이가 어떤 형질과 유의하게 연관되지만, 각각의 설명력은 \(0.1\%\) 미만이라 모두 합쳐도 개별 예측이 크게 나아지지 않는다. "통계적으로 유의한 위험인자"의 목록이 곧 쓸 만한 예측 모형이 되는 것은 아니다.

정리하면 이 절의 두 축이 서로 독립이다.

  • 예측에는 좋지만 인과효과가 없는 변수 (연습문제 2, 앞 절의 \(X2\))
  • 인과효과가 확실하지만 예측에는 무력한 변수 (이 문제)

하나의 분석으로 두 질문에 동시에 답할 수 없다. 무엇을 묻는지 먼저 정해야 한다. \(\square\)


정리하며

같은 자료, 같은 회귀식이라도 무엇을 하려는가에 따라 옳은 선택이 달라진다.

  • 예측은 표본 밖 손실을 최소화하는 것이 목표이고, \(\hat f\) 의 내부 구조는 부차적이다. 복잡한 모형도 환영이며, 주된 위협은 과적합이다.
  • 추론은 관계를 이해하는 것이 목표이고, 모수에 의미가 있어야 한다. 단순한 모형을 선호하며, 주된 위협은 모형 오지정과 교란이다.
  • 평가 기준이 다르다. 예측은 표본 밖 MSE·AUC 로, 추론은 신뢰구간·효과 크기로 판단한다.
  • 편향–분산 분해가 그 차이를 보여준다. 예측오차는 잡음 \(\sigma^2\) + 편향\(^2\) + 분산이며, 예측에서는 편향을 조금 들여 분산을 크게 줄이는 거래가 이득이다. 추론에서는 같은 거래가 계수를 체계적으로 왜곡하므로 손해다.

둘을 뒤섞는 것이 응용 실무에서 가장 흔한 혼란이다. 예측 성능이 좋다고 계수를 인과적으로 읽거나, 해석 가능성을 위해 예측력을 포기해 놓고 예측 문제라 부르는 일이 그렇다. 정칙화가 좋은 예다. 능형회귀는 예측을 개선하면서 계수를 0 쪽으로 당기므로, 그 계수를 효과 크기로 읽으면 체계적으로 과소평가하게 된다.

다음 절 통계 모형 대 학습 알고리즘은 이 구분이 도구의 선택으로 어떻게 이어지는지를 본다.