본문 바로가기
C.W.K.
Stream
Lesson 01 of 07 · published

Cross-Validation

~28 min · cv, validation, model-selection

Level 0Scout
0 XP0/48 lessons0/11 achievements
0/120 XP to next level120 XP to go0% complete

분할 한 번은 운이 너무 많이 섞여

검증 자료를 한 번만 나누면 어떤 사례가 우연히 검증 쪽에 들어갔는지에 따라 점수가 달라져. 자료가 작거나 양성이 드물수록 이 흔들림은 후보 모델의 실제 차이보다 클 수 있어. K겹 교차검증은 자료를 K개 조각으로 나누고 매번 한 조각을 검증에, 나머지를 학습에 써 여러 점수를 얻어. 평균은 전반적 성능을, 폴드 간 차이는 불확실성을 보여줘.

모든 전처리를 폴드 안에 넣어

결측 대치, 스케일링, 인코딩, 특성 선택, 재표본을 교차검증 전에 전체 자료에 맞추면 검증 폴드 정보가 학습으로 새어. 원시 행을 받는 파이프라인 전체를 교차검증에 넘겨야 각 폴드에서 변환기가 학습 부분만 보게 돼. 교차검증은 누출을 자동으로 없애는 주문이 아니라 경계를 지킬 때만 유효한 절차야.

분류에는 층화 분할

StratifiedKFold는 각 폴드의 목표 범주 비율을 전체와 비슷하게 유지해. 드문 양성이 특정 폴드에 거의 없어서 지표가 정의되지 않는 일을 줄여주지. 그래도 양성 수가 K보다 적다면 폴드 수를 줄이거나 자료를 더 모아야 해. 층화는 독립성이나 시간 문제를 해결하지 않는다는 점도 기억해.

연결된 행은 집단으로 묶어

한 사용자, 환자, 세션, 문서에서 여러 행이 나왔다면 같은 집단을 학습과 검증에 나눠 넣지 마. GroupKFold로 집단 전체를 한 폴드에 둬야 새 집단에 대한 일반화를 측정할 수 있어. 범주 비율과 집단 제약을 함께 지켜야 한다면 StratifiedGroupKFold를 검토해.

시간 문제는 과거에서 미래로

TimeSeriesSplit은 앞선 기간으로 학습하고 뒤 기간으로 검증해 실제 배포 순서를 흉내 내. 무작위 섞기는 미래 정책과 계절을 과거 학습에 넣을 수 있어. 특성의 관찰 창과 목표의 예측 창이 겹치지 않도록 경계 사이에 간격을 두어야 하는 문제도 있어. 시간 폴드별 점수 추세는 환경 변화까지 보여줘.

평균과 표준편차를 함께 읽어

평균 점수만 한 줄로 보고하지 말고 각 폴드 점수, 평균, 표준편차를 보여줘. 후보 모델 차이가 흔들림보다 작다면 우열을 증명하지 못한 거야. 폴드 수나 반복 씨앗을 늘리고도 겹치면 동률로 취급해 더 단순한 모델을 고를 수 있어. 표준편차가 큰 폴드의 실제 사례를 읽으면 특정 기간이나 집단의 실패가 드러나기도 해.

최종 시험 자료는 여전히 따로야

교차검증으로 모델 종류와 초매개변수를 고르는 동안 팀의 선택은 그 점수에 맞춰져. 모든 결정을 끝낸 뒤 얼린 시험 자료에서 한 번 확인해야 해. 교차검증 평균을 시험 점수 대신 쓰거나 시험 자료까지 폴드에 섞으면 마지막 독립 추정치를 잃어.

Code

표준편차를 포함한 층화 5겹 교차검증·python
from sklearn.model_selection import StratifiedKFold, cross_val_score
import numpy as np

cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=7)
scores = cross_val_score(pipe, X, y, cv=cv, scoring="average_precision")
print(f"PR-AUC = {scores.mean():.3f} ± {scores.std():.3f}")
사용자마다 행이 묶일 때 집단 단위 교차검증·python
from sklearn.model_selection import GroupKFold

gkf = GroupKFold(n_splits=5)
scores = cross_val_score(pipe, X, y, cv=gkf, groups=df["user_id"], scoring="roc_auc")
예측을 위한 시간 순서 교차검증·python
from sklearn.model_selection import TimeSeriesSplit

tscv = TimeSeriesSplit(n_splits=5, gap=14)  # 14-day gap to avoid leakage
scores = cross_val_score(pipe, X_sorted, y_sorted, cv=tscv, scoring="neg_root_mean_squared_error")

External links

Exercise

문제에 맞는 층화, 집단, 시간 교차검증을 선택해 5개 폴드의 개별 점수, 평균, 표준편차를 보고해. 가능한 경우 10개 폴드와 비교하고 0.5% 차이인 두 모델을 구분할 만큼 안정적인지 판단해.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.