Skip to main content

학습/테스트 분할

데이터를 학습용과 평가용으로 적절히 나누는 것은 모델의 일반화 성능을 올바르게 추정하기 위한 첫 번째 단계입니다.

학습 목표

  • 학습/검증/테스트 분할의 목적과 비율을 이해합니다.
  • 계층적 분할(Stratified Split)의 필요성을 파악합니다.
  • 시계열 데이터의 특수한 분할 방법을 이해합니다.
  • 데이터 누수(Data Leakage)를 방지하는 원칙을 적용할 수 있습니다.

왜 중요한가

학습 데이터에서의 성능은 실제 성능을 과대 추정합니다. 모델이 본 적 없는 데이터에서 얼마나 잘 작동하는지 추정하려면, 학습에 사용하지 않은 별도의 데이터가 필요합니다.

핵심 개념

홀드아웃 방법 (Hold-out)

from sklearn.model_selection import train_test_split
from sklearn.datasets import load_iris

X, y = load_iris(return_X_y=True)

# 기본 분할: 80% 학습, 20% 테스트
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42
)
print(f"학습: {len(X_train)}, 테스트: {len(X_test)}")

# 3분할: 60% 학습, 20% 검증, 20% 테스트
X_temp, X_test, y_temp, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42
)
X_train, X_val, y_train, y_val = train_test_split(
    X_temp, y_temp, test_size=0.25, random_state=42  # 0.25 x 0.8 = 0.2
)
print(f"학습: {len(X_train)}, 검증: {len(X_val)}, 테스트: {len(X_test)}")

계층적 분할 (Stratified Split)

클래스 불균형 데이터에서 각 클래스의 비율을 유지하면서 분할합니다.
import numpy as np

# 불균형 데이터 예시
y_imbalanced = np.array([0]*900 + [1]*100)  # 90:10 비율

# stratify 없이 분할 → 비율이 깨질 수 있음
_, _, y_train, y_test = train_test_split(
    np.zeros((1000, 5)), y_imbalanced, test_size=0.2, random_state=42
)
print(f"일반 분할 - 테스트 양성 비율: {y_test.mean():.2%}")

# stratify 사용 → 비율 유지
_, _, y_train_s, y_test_s = train_test_split(
    np.zeros((1000, 5)), y_imbalanced, test_size=0.2,
    random_state=42, stratify=y_imbalanced
)
print(f"계층 분할 - 테스트 양성 비율: {y_test_s.mean():.2%}")

시계열 분할

시계열 데이터는 무작위 분할이 불가합니다. 시간 순서를 반드시 유지해야 합니다.
from sklearn.model_selection import TimeSeriesSplit

# 시계열 교차검증
tscv = TimeSeriesSplit(n_splits=5)
for fold, (train_idx, test_idx) in enumerate(tscv.split(X)):
    print(f"Fold {fold}: 학습 {len(train_idx)}건, 테스트 {len(test_idx)}건")
    print(f"  학습 범위: [{train_idx[0]}, {train_idx[-1]}]")
    print(f"  테스트 범위: [{test_idx[0]}, {test_idx[-1]}]")

데이터 누수 방지 원칙

원칙설명
분할 후 전처리전처리(스케일링, 인코딩)는 학습 데이터에서만 fit
특성 공학 주의타겟 변수에서 파생된 특성 사용 금지
시간 순서 존중미래 데이터로 과거 예측 불가
테스트 세트 격리테스트 세트는 최종 1회 평가에만 사용
검증 세트는 모델 선택과 하이퍼파라미터 튜닝에 사용됩니다 (여러 번 참조 가능). 테스트 세트는 최종 모델의 성능을 한 번만 평가하는 데 사용됩니다. 교차검증을 사용하면 별도의 검증 세트가 불필요합니다.
데이터가 적으면 홀드아웃 대신 교차검증을 사용하세요. 모든 데이터를 학습과 검증에 번갈아 사용하여 더 안정적인 성능 추정이 가능합니다.

체크리스트

  • 학습/검증/테스트 세트의 역할을 구분할 수 있다
  • stratify 옵션의 필요성을 판단할 수 있다
  • 시계열 데이터의 분할 원칙을 설명할 수 있다
  • 데이터 누수의 대표적인 사례를 식별할 수 있다

다음 문서