머신러닝 파이프라인에서 데이터 누수 방지

Source: raw/articles/2026-04-26-data-leakage-prevention-ml-pipeline.md Type: article By: Towards Data Science + Kaggle Discussions Valid as of: 2026-04-26

핵심 Takeaway

  • 데이터 누수(Data Leakage): 훈련 단계에서 테스트 정보가 모델에 유출 → 현실보다 높은 성능 보임
  • 주 원인 2가지:
    1. 잘못된 fit_transform 사용 (전체 데이터로 학습 후 분할)
    2. 분할 순서 오류 (분할 전에 특성 공학 수행)
  • fit_transform vs transform: fit은 train만, transform은 train의 통계로 test도 변환
  • 올바른 순서: 분할 → (train으로 fit) → (both로 transform) → 모델 학습
  • 시계열 특수성: TimeSeriesSplit 사용 (무작위 분할 금지)
  • 자동 방지: sklearn Pipeline으로 누수 자동 방지
  • 검출 방법: 훈련/테스트 성능 격차 < 5% 확인

학습 목표 연계

Lecture Plan 20265-3: Data Leakage 방지 (Bloom L4-Analyze)

학습목표증거상태
Behavior: fit_transform vs transform 차이 이해내부 동작 코드 + 문제점 분석
Condition: train-test 분할 후 파이프라인 구성올바른/잘못된 방법 비교 + 순서도
Degree: 성능 격차 < 5%훈련/테스트 성능 비교 + 교차검증

내용 구성

1. 데이터 누수의 정의와 심각성

  • 현상: 모의 성능 vs 실제 성능 괴리
  • 원인: 테스트 정보가 훈련에 유출
  • 결과: 배포 후 모델 신뢰도 붕괴

2. 원인 1: fit_transform 오용

  • ❌ 나쁜 방법: 분할 전 fit_transform (전체 데이터로 학습)
  • ✅ 올바른 방법: fit(train만) → transform(train+test)
  • fit_transform 내부 동작 분석
  • 평균·분산이 train+test의 혼합 통계가 되는 문제

3. 원인 2: 특성 공학 순서 오류

  • ❌ 나쁜: 분할 전 특성 공학 (전체 데이터로 계산)
  • ✅ 올바름: 분할 후 train으로만 통계 계산, test도 같은 통계 적용

4. 특수 케이스: 시계열 데이터

  • 문제: 무작위 분할로 미래 정보가 과거에 노출
  • 현상: “과거를 회상”하는 모델 (예측 아님)
  • 해결: TimeSeriesSplit (시간 순서 보존)

5. Pipeline으로 자동 방지

  • sklearn Pipeline의 구조: fit → predict
  • 내부 동작: fit_transform(train) → transform(test)
  • 자동으로 데이터 누수 방지

6. 검출 방법

  • 기술 1: 훈련/테스트 성능 격차 비교 (< 5% 목표)
  • 기술 2: K-fold Cross-Validation (일관성 확인)
  • 기술 3: Permutation Importance (특성 검증)

7. 모범 사례 체크리스트 (10개 항목)

  • 분할 먼저, fit_transform 올바르게, Pipeline 사용 등

8. 실제 사례 분석

  • Kaggle 사례: fillna 누수
  • 통계 누수: 이상치 제거

관련 개념

다른 Module 5 학습목표와의 연계

실전 구현 흐름

# Step 1: 분할 (가장 먼저!)
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
 
# Step 2: Pipeline 구성 (자동 누수 방지)
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
 
pipeline = Pipeline([
    ('scaler', StandardScaler()),
    ('model', LogisticRegression())
])
 
# Step 3: Train만 fit
pipeline.fit(X_train, y_train)
 
# Step 4: Test는 predict (자동으로 train 통계 사용)
y_pred = pipeline.predict(X_test)
 
# Step 5: 성능 검증 (< 5% 격차)
from sklearn.metrics import accuracy_score
train_score = pipeline.score(X_train, y_train)
test_score = pipeline.score(X_test, y_test)
assert abs(train_score - test_score) < 0.05

성능 격차 해석 표

격차의미조치
< 1%✅ 매우 좋음그대로 진행
1-5%✅ 정상그대로 진행
5-10%⚠️ 약간 과적합모니터링, 정규화 고려
10-20%🔴 심각한 과적합데이터 누수 조사!
> 20% or 음수🔴🔴 즉시 중단확실한 누수 또는 버그

교차검증으로 검증

from sklearn.model_selection import cross_val_score
 
cv_scores = cross_val_score(pipeline, X_train, y_train, cv=5)
print(f"CV: {cv_scores.mean():.4f} ± {cv_scores.std():.4f}")
 
# CV와 Test 성능이 일치하면 → 데이터 누수 없음 ✅
# CV가 높지만 Test가 낮으면 → 데이터 누수 의심 🔴

시계열 데이터 주의사항

from sklearn.model_selection import TimeSeriesSplit
 
# ❌ 금지:
X_train, X_test = train_test_split(X_time_series)
 
# ✅ 권장:
tscv = TimeSeriesSplit(n_splits=5)
for train_idx, test_idx in tscv.split(X_time_series):
    # train_idx < test_idx (시간 순서 보존!)
    pass

선행 개념

이 개념을 배우기 전에 필수로 알아야 할 것:

  1. Module 5-1 → ml-pipelines-sas-beginner-guide: Pipeline의 기초 개념
    • 왜?: “Pipeline이 왜 데이터 누수를 자동으로 방지하는가?”를 이해하려면 Pipeline의 구조를 먼저 알아야 함
  2. Module 5-2 → sklearn-pipelines-medium-advanced: GridSearchCV와 교차검증
    • 왜?: 교차검증 중 누수가 발생하지 않는 메커니즘을 이해해야 함

후속 개념 (이 개념이 선행)

이 개념을 배운 후 다음 단계:

  1. Module 6 (MLOps): 훈련된 모델을 프로덕션에 배포할 때
    • 예: “프로덕션의 새로운 데이터에 대해 fit_transform이 아닌 transform만 사용해야 함”
  2. Module 7-1 (Mini-project): 실제 프로젝트에서 누수 방지 검증
    • 체크리스트: “Train/Test 성능 격차 < 5%?”

마지막 체크

프로덕션 배포 전 반드시 확인:

  • Train/Test 성능 격차 < 5%?
  • Pipeline으로 전처리 일관성 보장?
  • 교차검증 일치성 확인?
  • 시계열 데이터는 TimeSeriesSplit 사용?
  • 새 데이터(운영 데이터)로 최종 테스트?