콘텐츠로 이동

교차검증과 람다 조율

개요

정칙화 모수 \(\lambda\)는 능형회귀, 라쏘, 엘라스틱넷에서 벌점의 강도를 조절한다. \(\lambda\)를 잘 고르는 일은 결정적이다. 너무 작으면 모형이 과적합하고, 너무 크면 과소적합한다. 교차검증(CV)은 표본 밖 예측오차를 추정함으로써 \(\lambda\)를 자료에 근거해 원리적으로 선택하는 방법이다.

조율 문제

어떤 벌점회귀에서든 표본 내 손실은 \(\lambda\)가 0으로 줄어들수록 단조적으로 감소한다(정칙화가 약할수록 훈련자료에 더 잘 맞는다). 그러나 표본 밖 예측오차는 대개 U자 곡선을 그린다.

\[ \text{CV}(\lambda) = \frac{1}{K}\sum_{k=1}^{K} \text{MSE}^{(-k)}(\lambda), \]

여기서 \(\text{MSE}^{(-k)}\)는 나머지 \(K - 1\)개 겹으로 모형을 적합했을 때 겹 \(k\)에서의 평균제곱오차다. 최적 \(\lambda\)는 이 곡선을 최소화한다.

K-겹 교차검증

표준 절차는 다음과 같다.

  1. 자료를 크기가 거의 같은 \(K\)개의 겹으로 무작위 분할한다.
  2. 격자 \(\{\lambda_1, \dots, \lambda_M\}\)의 각 후보 \(\lambda\)에 대해:
    • \(k = 1, \dots, K\)에 대해 겹 \(k\)를 남겨 두고 나머지 자료로 모형을 적합한 뒤 겹 \(k\)에서 예측오차를 계산한다.
    • \(K\)개의 예측오차를 평균하여 \(\text{CV}(\lambda)\)를 얻는다.
  3. \(\hat{\lambda} = \arg\min_\lambda \text{CV}(\lambda)\)를 선택한다.

\(K = 5\) 또는 \(K = 10\)이 흔히 쓰인다.

람다 격자

후보 \(\lambda\) 격자는 보통 로그 척도로 잡는다.

\[ \lambda_1 > \lambda_2 > \cdots > \lambda_M, \quad \text{where } \lambda_m = 10^{a + (b-a)\frac{m-1}{M-1}} \]

여기서 \([a, b]\)는 적당한 범위다(예: \(a = -4\), \(b = 2\)). 실무에서는 다음과 같이 잡는다.

  • \(\lambda_{\max}\)는 모든 라쏘 계수를 0으로 만드는 가장 작은 값 \(\lambda_{\max} = \frac{1}{n}\|X^\top y\|_\infty\)이다.
  • 격자는 \(\lambda_{\max}\)에서 시작해 그 작은 배수 \(\epsilon \cdot \lambda_{\max}\)까지 내려간다 (예: \(\epsilon = 10^{-4}\)).

코드: 기본 교차검증 시연

보기 1. 교차검증과 1-표준오차 규칙. \(n = 100\), \(p = 20\)이고 참 계수는 앞의 셋만 \((3, -2, 1.5)\), 잡음은 \(N(0,1)\)이다. 라쏘의 \(\lambda\)를 \(10^{0.5}\)에서 \(10^{-2.5}\)까지 25점으로 훑으며 \(5\)-겹 교차검증을 한다.

(1) 이 자료에서 교차검증 곡선이 내려갈 수 없는 바닥과 올라갈 수 있는 천장을 각각 수로 구하시오.

(2) 교차검증을 실제로 돌려 (1)의 두 값을 확인하고, 최소 규칙과 1-표준오차 규칙이 고른 모형을 견주시오.

풀이

(1) 해석적으로. 새 관측 \((x_0, y_0)\)에서 \(y_0 = x_0^\top\beta + \varepsilon_0\)이고 \(\varepsilon_0\)은 훈련자료와 독립이다. 어떤 추정량 \(\hat\beta\)를 쓰든

\[ E\!\left[(y_0 - x_0^\top\hat\beta)^2\right] = E\!\left[(\varepsilon_0 + x_0^\top(\beta - \hat\beta))^2\right] = \sigma^2 + E\!\left[(x_0^\top(\beta-\hat\beta))^2\right] \;\ge\; \sigma^2 \]

이다. 교차항은 \(\varepsilon_0\)이 \(\hat\beta\)와 독립이고 평균이 0이라 사라진다. 바닥은 \(\sigma^2 = 1\)이고, 이는 \(\beta\)를 완벽히 알아도 줄일 수 없는 몫이다.

천장은 반대쪽 끝에 있다. \(\lambda \ge \lambda_{\max} = \lVert X^\top y\rVert_\infty / n\)이면 라쏘 해가 영벡터이므로(연습문제 1) 예측값이 절편뿐이고, 그때의 예측오차는 \(y\)의 분산 \(\operatorname{Var}(y) = \beta^\top\Sigma\beta + \sigma^2\)이 된다. 설계가 독립 표준정규이므로 \(\Sigma = I\)이고

\[ \operatorname{Var}(y) \approx 3^2 + (-2)^2 + 1.5^2 + 1 = 17.25 \]

다. 격자의 왼쪽 끝은 영모형, 오른쪽 끝은 최소제곱이며 교차검증 곡선은 그 사이 어딘가에서 바닥을 친다.

(2) 수치적으로. 1-표준오차 규칙은

\[ \hat\lambda_{1\text{SE}} = \max\{\lambda : \mathrm{CV}(\lambda) \le \mathrm{CV}(\hat\lambda_{\min}) + \mathrm{SE}(\hat\lambda_{\min})\} \]

이다. 코드의 격자 lambdas 가 큰 값에서 작은 값으로 내려가므로 np.where(cv_mean <= threshold)[0][0] 이 집는 첫 번째 자리가 곧 조건을 만족하는 가장 큰 \(\lambda\)다.

import numpy as np
from sklearn.linear_model import Lasso
from sklearn.model_selection import KFold

rng = np.random.default_rng(42)

# 참으로 쓰이는 변수는 앞의 셋뿐이고 나머지 열일곱은 잡음이다.
n, p = 100, 20
X = rng.normal(size=(n, p))
beta_true = np.zeros(p)
beta_true[:3] = [3.0, -2.0, 1.5]
y = X @ beta_true + rng.normal(0, 1, n)

# lambda 격자는 로그 눈금으로 잡는다. 벌점의 효과가 곱셈으로 작동하므로
# 등간격보다 등비간격이 알맞다.
lambdas = np.logspace(0.5, -2.5, 25)

kf = KFold(n_splits=5, shuffle=True, random_state=0)

# 겹마다의 MSE 를 따로 남긴다. 평균만 구하면 1-표준오차 규칙을 쓸 수 없다.
fold_mse = np.zeros((5, len(lambdas)))
for k, (tr, va) in enumerate(kf.split(X)):
    for i, lam in enumerate(lambdas):
        model = Lasso(alpha=lam, max_iter=10000).fit(X[tr], y[tr])
        fold_mse[k, i] = np.mean((y[va] - model.predict(X[va])) ** 2)

cv_mean = fold_mse.mean(axis=0)
cv_se = fold_mse.std(axis=0, ddof=1) / np.sqrt(5)

i_min = int(np.argmin(cv_mean))

# 1-표준오차 규칙: 최솟값에서 1 표준오차 안에 드는 lambda 중 가장 큰 것을
# 고른다. CV 곡선의 최소점은 그 자체가 흔들리는 추정값이므로, 조금 더
# 단순한 모형 쪽으로 물러서는 편이 안전하다는 생각이다.
threshold = cv_mean[i_min] + cv_se[i_min]
i_1se = int(np.where(cv_mean <= threshold)[0][0])

for name, i in [("최소 CV", i_min), ("1-표준오차", i_1se)]:
    beta = Lasso(alpha=lambdas[i], max_iter=10000).fit(X, y).coef_
    print(f"{name:>10}: lambda = {lambdas[i]:.4f}, "
          f"CV MSE = {cv_mean[i]:.3f} (SE {cv_se[i]:.3f}), "
          f"0 이 아닌 계수 = {np.sum(np.abs(beta) > 1e-8)}개")
print("참으로 0 이 아닌 계수: 3개")

# --- (1) 의 바닥과 천장을 확인한다 ---
print(f"잡음분산 sigma^2 = 1 이므로 CV MSE 의 하한은 1.000")
print(f"최소 CV MSE = {cv_mean[i_min]:.4f}  ->  하한 위로 {cv_mean[i_min] - 1:+.4f}")
print(f"1-SE 문턱 = {cv_mean[i_min]:.4f} + {cv_se[i_min]:.4f} = {threshold:.4f}")
print(f"격자 첫 값 lambda = {lambdas[0]:.4f},  이론 lambda_max = |X'y|_inf/n = "
      f"{np.abs(X.T @ (y - y.mean())).max() / n:.4f}")
print(f"가장 큰 lambda 에서의 CV MSE = {cv_mean[0]:.4f}  (영모형: Var(y) = {y.var():.4f})")

출력:

     최소 CV: lambda = 0.1000, CV MSE = 1.001 (SE 0.044), 0 이 아닌 계수 = 9개
    1-표준오차: lambda = 0.1778, CV MSE = 1.038 (SE 0.083), 0 이 아닌 계수 = 5개
참으로 0 이 아닌 계수: 3개
잡음분산 sigma^2 = 1 이므로 CV MSE 의 하한은 1.000
최소 CV MSE = 1.0014  ->  하한 위로 +0.0014
1-SE 문턱 = 1.0014 + 0.0441 = 1.0455
격자 첫 값 lambda = 3.1623,  이론 lambda_max = |X'y|_inf/n = 3.1113
가장 큰 lambda 에서의 CV MSE = 17.4719  (영모형: Var(y) = 17.5023)

바닥이 맞는다. 최소 CV MSE가 \(1.0014\)로 유도한 하한 \(\sigma^2 = 1\)보다 겨우 \(0.0014\) 높다. 표준오차가 \(0.044\)이니 이 차이는 재어 낼 수도 없는 크기다. \(n = 100\)에 참 변수가 셋뿐이라 라쏘가 \(\beta\)를 거의 완벽히 되찾았다는 뜻이다.

천장도 맞는다. 격자의 첫 값 \(3.1623\)이 이론적 \(\lambda_{\max} = 3.1113\)보다 크므로 거기서 라쏘 해는 영벡터이고, 실제 CV MSE가 \(17.4719\)로 \(\operatorname{Var}(y) = 17.5023\)과 사실상 같다. (1)에서 어림한 \(17.25\)와도 가깝다. 둘의 작은 차이는 \(n = 100\)에서 \(X\)의 표본공분산이 \(I\)와 꼭 같지는 않기 때문이다. 겹을 나누어 적합했으므로 완전히 같아질 이유도 없다.

최소 CV 규칙은 잡음 변수를 여섯 개나 남겼지만, 1-표준오차 규칙은 다섯 개만 남겼다. 참으로 쓰인 변수가 셋임을 생각하면 뒤쪽이 더 나은 선택이다. 다만 CV가 겨냥하는 것은 예측오차이지 올바른 변수집합이 아니다. 둘 다 과다선택을 한 것은 CV가 실패했기 때문이 아니라, 계수가 거의 0인 잡음변수를 하나 더 넣어도 예측오차가 거의 늘지 않기 때문이다.

1-표준오차 규칙

\(\hat{\lambda}\)를 CV 곡선의 정확한 최소점으로 잡는 대신, CV 오차가 최솟값으로부터 1 표준오차 이내인 \(\lambda\) 중 가장 큰 것을 고르는 보수적 규칙이 널리 쓰인다.

\[ \hat{\lambda}_{1\text{SE}} = \max\left\{ \lambda : \text{CV}(\lambda) \le \text{CV}(\hat{\lambda}) + \text{SE}(\hat{\lambda}) \right\}. \]

이 규칙은 예측오차를 거의 늘리지 않으면서 더 단순한(더 강하게 정칙화된) 모형을 선호한다.

다섯 겹 각각의 교차검증 곡선과 그 평균, 그리고 두 선택 규칙

위 보기의 fold_mse 행렬을 평균내기 전에 그려 본 것이다. 굵은 파란 선이 우리가 보통 보는 5겹 평균이고, 가는 회색 선 다섯 개가 그 평균을 이루는 겹별 곡선이다. 역삼각형은 각 겹이 혼자서 골랐을 최적 \(\lambda\)다.

회색 곡선들이 얼마나 다른지 보라. 다섯 겹의 최적 \(\lambda\)는 \(0.042,\ 0.056,\ 0.075,\ 0.133,\ 0.237\)로 가장 작은 것과 가장 큰 것이 5.6배 차이난다. 최저 오차도 \(0.718\)에서 \(1.130\)까지 흩어진다. 같은 자료를 어떻게 다섯 조각으로 나누느냐에 따라 "최적"이 이만큼 움직인다는 뜻이다. 평균 곡선의 최소점 \(\lambda_{\min} = 0.100\)은 이 다섯 의견의 타협일 뿐이며, 소수점까지 믿을 근거가 없다.

이 흔들림을 숫자로 요약한 것이 표준오차 \(0.044\)이고, 회색 점선이 그 문턱 \(1.001 + 0.044 = 1.045\)다. 문턱 아래에 머무는 가장 큰 \(\lambda\)가 \(\lambda_{1\text{SE}} = 0.178\)이다. 두 \(\lambda\) 사이의 곡선이 평평하다는 점이 1-SE 규칙의 전부다. 평균 곡선이 그 구간에서 \(1.001\)에서 \(1.038\)로 4% 오를 뿐이라면, 통계적으로 구별되지 않는 모형들 중 가장 단순한 것을 고르는 편이 낫다.

그 선택이 실제로 무엇을 바꾸는지는 계수를 세어 보면 안다. \(\lambda_{\min}\)은 변수 9개를, \(\lambda_{1\text{SE}}\)는 5개를 남긴다. 참으로 쓰인 변수는 3개이므로 둘 다 과다선택이지만 후자가 진실에 가깝다. 예측 정확도를 마지막 한 자리까지 다투는 상황이 아니라면, 곡선이 평평한 구간에서는 오른쪽 끝을 고르는 것이 합리적이다.

실무상의 고려사항

  • 표준화. 교차검증 전에 항상 설명변수를 표준화하라. 단, 표준화에 쓰는 평균과 표준편차는 전체 자료가 아니라 훈련 겹에서만 계산해야 자료 누설을 피할 수 있다.
  • 중첩 교차검증. 최종 모형의 일반화 오차까지 추정하려면 중첩(이중) 교차검증을 쓴다. 바깥 루프가 검정오차를 추정하고 안쪽 루프가 \(\lambda\)를 선택한다.
  • 계산 비용. 온기 시작(직전 \(\lambda\)의 해에서 좌표하강을 시작하는 것)은 경로 계산을 극적으로 빠르게 한다.
  • 무작위 분할. 분할 전에 섞거나 반복 교차검증을 쓰면 특정 분할에 대한 민감도가 줄어든다.

해석

  • CV 곡선은 U자(적어도 비단조) 모양이어야 한다. 가장 작은 \(\lambda\)에서도 여전히 감소 중이라면 격자를 더 작은 쪽으로 넓혀라.
  • 가장 큰 \(\lambda\)에서도 여전히 감소 중이라면 그 자료에는 정칙화가 필요 없을 수도 있다.
  • 1SE 규칙은 예측오차를 조금 희생하는 대신 더 희소하고 해석하기 좋은 모형을 준다.

연습문제

연습문제 1. 라쏘에 대해 \(\lambda_{\max} = \frac{1}{n}\|X^\top y\|_\infty\)를 유도하라. 즉 \(\lambda \ge \lambda_{\max}\)이면 라쏘 해가 \(\hat{\beta} = 0\)임을 보여라.

풀이

라쏘 목적함수는 \(f(\beta) = \frac{1}{2n}\|y - X\beta\|_2^2 + \lambda\|\beta\|_1\)이다. \(\beta = 0\)에서의 부분미분은

\[ \partial f(0) = \left\{-\frac{1}{n}X^\top y + \lambda s : s \in \partial\|\cdot\|_1(0)\right\} = \left\{-\frac{1}{n}X^\top y + \lambda s : s_j \in [-1,1]\right\} \]

이다. 최적성 조건 \(0 \in \partial f(0)\)은 \(|s_j| \le 1\)인 어떤 \(s\)에 대해 \(\frac{1}{n}X^\top y = \lambda s\)가 성립할 것을 요구한다. 이는 모든 \(j\)에 대해 \(\frac{1}{n}|X_j^\top y| \le \lambda\)일 때, 그리고 그때에만 가능하다. 즉 \(\lambda \ge \frac{1}{n}\|X^\top y\|_\infty = \lambda_{\max}\)이다. \(\square\)

연습문제 2. 교차검증 전에 전체 자료로 설명변수를 표준화하면 왜 자료 누설이 생기는지 설명하고, 올바른 절차를 서술하라.

풀이

검증 겹까지 포함한 전체 자료에서 \(\bar{x}_j\)와 \(s_j\)를 계산해 표준화하면, 검증 겹의 자료가 자기 자신에게 적용되는 변환에 영향을 미친다. 결국 모형이 훈련 과정에서 검증 겹의 정보를 간접적으로 "본" 셈이 되어 CV 오차 추정이 낙관적으로 편향된다.

올바른 절차: 각 CV 반복 안에서 훈련 겹만으로 평균과 표준편차를 계산한 뒤, 같은 변환을 남겨 둔 겹에 적용한다.

import numpy as np
from sklearn.model_selection import KFold

rng = np.random.default_rng(0)
X = rng.normal(5, 3, (100, 4))          # 평균과 척도가 0/1이 아닌 자료
y = X @ np.array([1.0, -1.0, 0.5, 0.0]) + rng.normal(0, 1, 100)

for k, (train_idx, val_idx) in enumerate(KFold(5).split(X)):
    X_train, X_val = X[train_idx], X[val_idx]
    mu = X_train.mean(axis=0)
    sigma = X_train.std(axis=0)
    X_train_s = (X_train - mu) / sigma
    X_val_s = (X_val - mu) / sigma
    # 훈련자료로 적합하고 검증자료에서 잰다
    if k == 0:
        print("훈련 겹 평균:", np.round(X_train_s.mean(axis=0), 4))
        print("검증 겹 평균:", np.round(X_val_s.mean(axis=0), 4))

출력:

훈련 겹 평균: [-0.  0. -0. -0.]
검증 겹 평균: [-0.1022  0.1113  0.5175  0.243 ]

이렇게 하면 검증 겹이 진정으로 미관측 상태로 남는다. \(\square\)

연습문제 3. 1-표준오차 규칙을 구현하라. 배열 lambdas, cv_mean, cv_se(각 \(\lambda\)의 CV MSE 평균과 표준오차)가 주어졌을 때 \(\hat{\lambda}_{1\text{SE}}\)를 반환하는 함수를 작성하라.

풀이
def one_se_rule(lambdas, cv_mean, cv_se):
    """
    Select the largest lambda whose CV error is within
    one SE of the minimum CV error.
    """
    best_idx = np.argmin(cv_mean)
    threshold = cv_mean[best_idx] + cv_se[best_idx]

    # 교차검증 오차가 문턱 이하인 lambda 중 가장 큰 것을 고른다
    candidates = np.where(cv_mean <= threshold)[0]
    best_1se_idx = candidates[np.argmax(lambdas[candidates])]
    return lambdas[best_1se_idx]

이 함수는 최소 CV 오차를 찾아 1 표준오차를 더해 문턱값을 만들고, 그 문턱값 이내에서 가장 강하게 정칙화된 모형(가장 큰 \(\lambda\))을 고른다.

흔한 함정

후보 인덱스에서 곧바로 candidates.max()나 candidates.min()을 쓰면 안 된다. lambdas 배열이 오름차순인지 내림차순인지에 따라 정반대 결과가 나오기 때문이다. sklearn.linear_model.lasso_path가 돌려주는 alphas는 내림차순이라 candidates.max()는 가장 작은 \(\lambda\)를 고르게 되어 규칙의 취지와 반대가 된다. 위처럼 \(\lambda\) 값 자체에 argmax를 취하면 정렬 순서와 무관하게 항상 옳다.

\(\square\)

연습문제 4. 인공자료(\(n = 200\), \(p = 30\), 참 계수 중 5개만 0이 아님)에 대해 로그 등간격 \(\lambda\) 50개 위에서 라쏘의 5-겹 교차검증을 수행하라. 오차막대(\(\pm 1\) SE)를 포함한 CV 곡선을 그리고 \(\hat{\lambda}_{\min}\)과 \(\hat{\lambda}_{1\text{SE}}\)를 모두 표시하라.

풀이
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import Lasso
from sklearn.model_selection import KFold
from sklearn.preprocessing import StandardScaler

np.random.seed(42)
n, p = 200, 30
X = np.random.randn(n, p)
beta_true = np.zeros(p)
beta_true[:5] = [3, -2, 4, -1, 2]
y = X @ beta_true + np.random.randn(n)

X_s = StandardScaler().fit_transform(X)
lambdas = np.logspace(1, -3, 50)
kf = KFold(n_splits=5, shuffle=True, random_state=42)

mse_folds = np.zeros((len(lambdas), 5))
for fold_idx, (tr, va) in enumerate(kf.split(X_s)):
    mu, sig = X_s[tr].mean(0), X_s[tr].std(0)
    Xtr = (X_s[tr] - mu) / sig
    Xva = (X_s[va] - mu) / sig
    for i, lam in enumerate(lambdas):
        m = Lasso(alpha=lam, max_iter=10000).fit(Xtr, y[tr])
        mse_folds[i, fold_idx] = np.mean((y[va] - m.predict(Xva))**2)

cv_mean = mse_folds.mean(axis=1)
cv_se = mse_folds.std(axis=1) / np.sqrt(5)

best_idx = np.argmin(cv_mean)
lam_min = lambdas[best_idx]
lam_1se = one_se_rule(lambdas, cv_mean, cv_se)

plt.errorbar(np.log10(lambdas), cv_mean, yerr=cv_se, fmt='o-', ms=4)
plt.axvline(np.log10(lam_min), color='red', ls='--', label='lambda_min')
plt.axvline(np.log10(lam_1se), color='blue', ls='--', label='lambda_1SE')
plt.xlabel('log10(lambda)')
plt.ylabel('CV MSE')
plt.legend()
plt.show()

교차검증 오차 곡선

실행하면 \(\hat{\lambda}_{\min} = 0.0518\)에서 CV MSE는 \(1.0154\)(SE \(= 0.0611\))이고, 1SE 규칙은 \(\hat{\lambda}_{1\text{SE}} = 0.1099\)를 고르며 그때 CV MSE는 \(1.0637\)이다. 전체 자료에 다시 적합하면 \(\hat{\lambda}_{\min}\)은 0이 아닌 계수를 16개 남기지만 \(\hat{\lambda}_{1\text{SE}}\)는 10개만 남긴다. 즉 예측오차가 5% 가까이 늘어나는 대신 모형이 훨씬 희소해진다. 곡선은 특징적인 U자 모양이며, 잡음변수 25개 중 상당수가 여전히 선택된다는 점은 교차검증이 예측을 최적화할 뿐 변수선택을 최적화하지는 않음을 보여준다. \(\square\)

연습문제 5. 능형회귀의 하나 남기기 교차검증(LOOCV)이 닫힌 형태 \(\text{CV}_{\text{LOO}} = \frac{1}{n}\sum_{i=1}^{n}\left(\frac{y_i - \hat{y}_i}{1 - h_{ii}}\right)^2\) 로 계산됨을 증명하라. 여기서 \(H = X(X^\top X + \lambda I)^{-1}X^\top\)는 능형 모자행렬이고 \(h_{ii}\)는 그 \(i\)번째 대각원소다.

풀이

관측치 \(i\)를 제거하면 나머지 \(n-1\)개로 적합한 능형 모형이 예측 \(\hat{y}_{(-i), i}\)를 준다. 셔먼-모리슨 공식에 의해, \(X\)에서 \(i\)번째 행과 \(y\)에서 \(i\)번째 원소를 빼고 다시 적합하는 것은

\[ \hat{y}_{(-i), i} = x_i^\top (X_{(-i)}^\top X_{(-i)} + \lambda I)^{-1} X_{(-i)}^\top y_{(-i)} \]

와 같다. 선형모형의 표준 결과(OLS의 LOOCV 지름길을 확장한 것)에 따르면 능형회귀의 LOO 잔차는

\[ y_i - \hat{y}_{(-i),i} = \frac{y_i - \hat{y}_i}{1 - h_{ii}} \]

를 만족한다. 여기서 \(\hat{y}_i = h_i^\top y\)는 전체 자료로 적합한 능형 예측값이고 \(h_{ii}\)는 모자행렬 \(H = X(X^\top X + \lambda I)^{-1}X^\top\)의 \((i,i)\) 원소다.

따라서

\[ \text{CV}_{\text{LOO}} = \frac{1}{n}\sum_{i=1}^{n}\left(\frac{y_i - \hat{y}_i}{1 - h_{ii}}\right)^2 \]

이다. 이 식은 전체 모형을 한 번 적합하고 \(H\)의 대각만 구하면 되므로, 순진한 방법의 \(O(n^2 p^2)\) 대신 \(O(np^2)\)에 계산된다. \(\square\)


정리하며

\(\lambda\) 선택은 교차검증으로 한다.

  • U 자 곡선의 최소점을 찾는다. \(\lambda\) 가 작으면 과적합, 크면 과소적합이며 그 사이에 최적점이 있다.
  • 1-표준오차 규칙이 널리 쓰인다. 최소 오차에서 1 표준오차 안에 드는 가장 큰 \(\lambda\) 를 고르며, 더 단순하고 더 안정적인 모형을 얻는다.
  • 격자를 로그 등간격으로 잡는다. \(\lambda_{\max}\) 에서 시작해 여러 자릿수를 훑는 것이 표준이다.
  • 자료 누출을 피한다. 표준화를 각 겹 안에서 해야 하며, 전체 자료로 먼저 표준화하면 검증자료가 새어든다. 13장에서 강조한 점이다.
  • 겹 배정과 온기 시작. 경로를 따라가며 이전 해를 출발값으로 쓰면 계산이 빨라지고, 겹 배정을 고정해야 \(\lambda\) 들 사이의 비교가 공정하다.

다음 절 주성분회귀로 넘어간다.