머신러닝 파이프라인에서 데이터 누수 방지
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가지:
- 잘못된 fit_transform 사용 (전체 데이터로 학습 후 분할)
- 분할 순서 오류 (분할 전에 특성 공학 수행)
- fit_transform vs transform: fit은 train만, transform은 train의 통계로 test도 변환
- 올바른 순서:
분할 → (train으로 fit) → (both로 transform) → 모델 학습 - 시계열 특수성: TimeSeriesSplit 사용 (무작위 분할 금지)
- 자동 방지: sklearn Pipeline으로 누수 자동 방지
- 검출 방법: 훈련/테스트 성능 격차 < 5% 확인
학습 목표 연계
Lecture Plan 2026 — 5-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 누수
- 통계 누수: 이상치 제거
관련 개념
- ml-pipeline — ML 파이프라인 설계
- exploratory-data-analysis-eda — EDA에서의 누수 방지
다른 Module 5 학습목표와의 연계
- 5-1 ml-pipelines-sas-beginner-guide — 파이프라인 기초
- 5-2 sklearn-pipelines-medium-advanced — GridSearchCV + 파이프라인
- 5-3 data-leakage-prevention-ml ← 현재 문서 (데이터 누수 방지)
실전 구현 흐름
# 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선행 개념
이 개념을 배우기 전에 필수로 알아야 할 것:
- Module 5-1 → ml-pipelines-sas-beginner-guide: Pipeline의 기초 개념
- 왜?: “Pipeline이 왜 데이터 누수를 자동으로 방지하는가?”를 이해하려면 Pipeline의 구조를 먼저 알아야 함
- Module 5-2 → sklearn-pipelines-medium-advanced: GridSearchCV와 교차검증
- 왜?: 교차검증 중 누수가 발생하지 않는 메커니즘을 이해해야 함
후속 개념 (이 개념이 선행)
이 개념을 배운 후 다음 단계:
- Module 6 (MLOps): 훈련된 모델을 프로덕션에 배포할 때
- 예: “프로덕션의 새로운 데이터에 대해 fit_transform이 아닌 transform만 사용해야 함”
- Module 7-1 (Mini-project): 실제 프로젝트에서 누수 방지 검증
- 체크리스트: “Train/Test 성능 격차 < 5%?”
마지막 체크
프로덕션 배포 전 반드시 확인:
- Train/Test 성능 격차 < 5%?
- Pipeline으로 전처리 일관성 보장?
- 교차검증 일치성 확인?
- 시계열 데이터는 TimeSeriesSplit 사용?
- 새 데이터(운영 데이터)로 최종 테스트?