교차검증(Cross-Validation)
1. 개요
가. 정의
교차검증은 보유한 데이터를 여러 개의 학습용·검증용 분할로 번갈아 나누어 모델을 반복 학습·평가함으로써, 한 번의 분할에 의존하지 않고 모델의 일반화 성능을 더 안정적으로 추정하는 재표집(resampling) 기반 검증 기법이다.
머신러닝 모델의 목적은 학습에 쓰지 않은 미래 데이터에서도 잘 작동하는 것, 즉 일반화다. 그러나 우리가 가진 데이터는 유한하므로, 학습에 모든 데이터를 쓰면 성능을 검증할 표본이 남지 않고, 반대로 한 번만 떼어 둔 검증셋(holdout)으로 평가하면 그 성능 추정치가 어떤 데이터가 우연히 검증셋에 들어갔는지에 따라 크게 흔들린다. 교차검증은 이 딜레마를 "데이터를 돌려 쓰는" 방식으로 완화해, 모든 표본이 한 번씩 검증에 참여하도록 함으로써 추정의 분산을 낮추고 데이터를 효율적으로 활용한다.
나. 등장 배경 및 필요성
모델 개발은 알고리즘 선택, 하이퍼파라미터 조정, 피처 설계라는 수많은 의사결정의 연속이며, 이 선택들을 객관적으로 비교하려면 신뢰할 수 있는 성능 추정치가 필요하다. 단일 홀드아웃 분할은 간단하지만 두 가지 문제를 안는다. 첫째, 데이터가 적을수록 검증셋이 작아져 추정치의 변동성(분산)이 커진다. 둘째, 같은 검증셋을 반복해서 들여다보며 하이퍼파라미터를 고르면 그 검증셋에 모델이 은밀하게 과적합되어, 보고된 성능이 실제 운영 성능을 과대평가하게 된다.
교차검증은 이 문제를 데이터를 여러 번 재사용해 평가하는 방식으로 해결한다. 특히 데이터 확보 비용이 큰 의료·제조·금융 분야처럼 표본이 수백~수천 건에 불과한 경우, 교차검증은 제한된 데이터에서 통계적으로 더 믿을 만한 비교 근거를 제공한다는 점에서 사실상 표준 절차로 자리잡았다. 나아가 모델 선택과 성능 보고를 분리하는 중첩 교차검증은 "검증셋에 대한 과적합"이라는 함정을 구조적으로 막아 준다.
역사적으로 교차검증은 1970년대 통계학에서 모델 선택과 예측 오차 추정을 위한 재표집 기법으로 정립되었고, 부트스트랩·잭나이프와 함께 "유한 표본에서 분포 가정 없이 성능을 추정"하는 방법론 계열에 속한다. 오늘날에는 scikit-learn·caret 같은 라이브러리가 K-겹·계층적·시계열 분할을 표준 API로 제공하면서, 데이터 분석가라면 누구나 기본으로 적용하는 공통 언어가 되었다. 요컨대 교차검증은 "이 모델을 믿어도 되는가"라는 질문에 답하기 위한 가장 보편적이고 검증된 절차다.
다. 특징
- 재사용성: 모든 표본이 학습과 검증에 번갈아 쓰여 데이터 활용 효율이 높다.
- 분산 감소: 여러 분할의 성능을 평균하므로 단일 분할보다 추정이 안정적이다.
- 편향-분산 절충: 분할 수(k)와 검증셋 크기에 따라 추정의 편향과 분산이 상충한다.
- 적용 조건 의존성: 시계열·그룹·불균형 데이터에서는 단순 무작위 분할이 성능을 왜곡하므로 변형 기법이 필요하다.
2. 교차검증의 원리와 전체 구조
교차검증은 "데이터를 어떻게 나누어 돌려 쓰는가"에 따라 여러 변형으로 갈린다. 아래 구조도는 대표적인 기법들을 분할 방식과 데이터 특성을 기준으로 정리한 것이다.
flowchart TB
CV["교차검증(Cross-Validation)"] --> H["단순 분할<br/>Holdout"]
CV --> K["반복 분할<br/>K-Fold 계열"]
CV --> N["모델선택 분리<br/>Nested CV"]
K --> KF["기본 K-Fold"]
K --> SK["계층적 K-Fold<br/>Stratified"]
K --> LOO["LOOCV<br/>(k=N)"]
K --> RP["반복 K-Fold<br/>Repeated"]
CV --> S["데이터 특성별 변형"]
S --> TS["시계열<br/>TimeSeriesSplit"]
S --> GP["그룹<br/>GroupKFold"]
style CV fill:#e8f0fe,stroke:#2f6fed,stroke-width:2px
style S fill:#fef3e8,stroke:#ed922f,stroke-width:1px
교차검증을 관통하는 핵심 원리는 편향-분산 절충이다. 검증셋을 크게 떼면(학습셋이 작아지면) 모델이 데이터를 충분히 못 배워 성능을 낮게 편향되게 추정하고, 검증셋을 작게 떼면 추정의 분산이 커진다. 분할 수 k를 늘리면 각 회차의 학습셋이 전체에 가까워져 편향은 줄지만, 분할끼리 학습 데이터가 크게 겹쳐 성능 추정치들이 서로 상관되므로 분산 감소 효과는 한계가 있고 계산 비용만 늘어난다. 이 때문에 실무에서는 편향·분산·비용의 균형점으로 k=5 또는 k=10이 경험칙처럼 쓰인다.
또 하나의 원리는 정보 격리다. 검증셋은 "한 번도 보지 못한 미래"를 흉내 내야 하므로, 전처리(정규화·결측 대치·피처 선택)의 통계량은 반드시 학습 폴드에서만 계산해 검증 폴드에 적용해야 한다. 이 격리가 깨지면 검증셋 정보가 학습에 새어 들어가는 데이터 누수(data leakage)가 발생해, 교차검증이 주는 신뢰가 허상이 된다.
3. 주요 기법과 수행 절차
아래 프로세스 다이어그램은 가장 널리 쓰이는 K-겹 교차검증의 1회 반복과, 하이퍼파라미터 튜닝까지 포함하는 중첩(Nested) 교차검증의 흐름을 함께 보여 준다.
flowchart LR
subgraph OUTER["외부 루프 — 성능 추정"]
D["전체 데이터"] --> SP["K개 폴드로 분할"]
SP --> TR["K-1개 = 학습 폴드"]
SP --> VA["1개 = 검증 폴드"]
TR --> FIT["모델 학습<br/>(전처리는 학습 폴드에서만)"]
FIT --> EV["검증 폴드로 평가"]
EV --> AVG["K회 반복 후 성능 평균·표준편차"]
end
subgraph INNER["내부 루프 — 하이퍼파라미터 선택"]
TR --> HP["학습 폴드를 다시 K'겹 분할"]
HP --> GRID["하이퍼파라미터 탐색"]
GRID --> BEST["최적값 선택"]
BEST --> FIT
end
style OUTER fill:#e8f0fe,stroke:#2f6fed,stroke-width:1px
style INNER fill:#eafbea,stroke:#2faf5a,stroke-width:1px
가. 홀드아웃(Holdout)
가장 단순한 방법으로, 데이터를 보통 학습 7080%와 검증 2030%로 한 번 나누어 평가한다. 계산이 한 번뿐이라 빠르고 구현이 쉬우며, 수십만 건 이상의 대규모 데이터에서는 분할 변동이 작아 충분히 신뢰할 만하다. 실제로 ImageNet급 대규모 딥러닝에서는 교차검증의 반복 학습 비용이 막대하기 때문에, 고정된 학습·검증·테스트 분할(holdout)을 쓰는 것이 일반적이다.
그러나 데이터가 적을 때 홀드아웃은 치명적이다. 어떤 표본이 우연히 검증셋에 몰리느냐에 따라 성능 추정치가 수 %p씩 출렁이기 때문이다. 예컨대 500건짜리 의료 데이터에서 홀드아웃 한 번의 정확도가 82%로 나왔다 해도, 분할 시드를 바꾸면 76%나 88%가 나올 수 있어 모델 비교의 근거로는 위험하다. 이것이 소규모 데이터에서 교차검증이 필요한 직접적 이유다.
또한 홀드아웃은 데이터를 "학습에 쓸 것"과 "검증에 쓸 것"으로 한 번 갈라 버리므로, 검증에 쓰인 20~30%는 학습에 전혀 기여하지 못한다. 데이터가 귀한 상황에서 이 낭비는 모델 품질을 직접 떨어뜨린다.
나. K-겹 교차검증(K-Fold)
K-겹 교차검증은 데이터를 k개의 폴드로 나눈 뒤, 각 폴드를 한 번씩 검증셋으로 쓰고 나머지 k-1개를 학습셋으로 써서 총 k번 학습·평가를 반복하고 그 성능을 평균한다. 모든 표본이 정확히 한 번 검증에 쓰이므로 데이터를 버리지 않으며, k개의 성능값으로 평균과 표준편차를 함께 보고할 수 있어 "이 모델이 평균 얼마나 좋고, 얼마나 안정적인가"를 동시에 판단할 수 있다.
k의 선택은 편향-분산·비용의 절충이다. k가 작으면(예: k=3) 학습셋이 작아 성능이 비관적으로 편향되고, k가 크면(예: k=20) 학습셋은 전체에 가까워지지만 폴드 간 학습 데이터가 크게 겹쳐 추정치들이 상관되고 학습을 20번 돌려야 해 비용이 급증한다. 그래서 대부분의 실무는 이 균형점으로 k=5(약 20% 검증) 또는 k=10(약 10% 검증)을 채택한다.
| 분할 수 k | 1회 학습셋 비율 | 추정 편향 | 추정 분산 | 계산 비용 |
|---|---|---|---|---|
| k=2~3 | 50~67% | 큼(비관적) | 작음 | 낮음 |
| k=5 | 80% | 보통 | 보통 | 보통 |
| k=10 | 90% | 작음 | 보통 | 높음 |
| k=N (LOOCV) | ≈100% | 거의 없음 | 큼 | 매우 높음 |
표에서 보듯 k를 키운다고 무조건 좋아지는 것이 아니라, LOOCV처럼 극단으로 가면 편향은 사라지지만 분산과 비용이 폭증한다. 즉 지표를 "하나만 키우면 되는" 문제가 아니라, 데이터 크기와 계산 예산을 함께 고려한 설계 결정이다.
K-겹의 또 다른 실무적 가치는 성능의 불확실성을 함께 보고할 수 있다는 점이다. 예컨대 모델 A가 "정확도 평균 84%, 표준편차 2%p", 모델 B가 "평균 85%, 표준편차 9%p"라면, 평균만 보면 B가 낫지만 B는 분할에 따라 성능이 크게 출렁여 운영에서 위험할 수 있다. 교차검증은 이렇게 평균과 변동성을 동시에 제시해, "평균이 조금 낮더라도 더 안정적인 모델"을 고르는 근거를 제공한다. 이는 단일 홀드아웃이 결코 줄 수 없는 정보다.
다. 계층적·LOOCV·반복 교차검증
계층적 K-겹(Stratified K-Fold)은 각 폴드가 전체의 클래스 비율을 그대로 유지하도록 층화 추출한다. 분류 문제, 특히 양성이 5%뿐인 불균형 데이터에서 단순 무작위 분할을 쓰면 어떤 폴드에는 양성이 거의 없어 평가가 무의미해질 수 있는데, 계층적 분할은 모든 폴드에 양성을 고르게 배분해 이 왜곡을 막는다. 분류에서는 사실상 기본값으로 쓰인다.
LOOCV(Leave-One-Out)는 k=N인 극단으로, 표본 하나만 검증셋으로 두고 나머지 전부로 학습하는 것을 N번 반복한다. 학습셋이 거의 전체이므로 성능 추정의 편향은 가장 작지만, N번 학습해야 해 데이터가 수천 건만 되어도 비용이 비현실적이고, 추정치의 분산이 크다는 약점이 있다. 그래서 LOOCV는 표본이 수십~수백 건에 불과한 경우에 제한적으로 쓰인다.
반복 K-겹(Repeated K-Fold)은 폴드를 매번 다르게 섞어 K-겹 전체를 여러 번 반복하고 그 결과를 평균한다. 단 한 번의 K-겹에서 생길 수 있는 "운 좋은/나쁜 분할"의 영향을 더 줄여, 소규모 데이터에서 추정치의 분산을 한층 낮추고자 할 때 사용한다.
계층적 분할의 효과는 수치로 분명하다. 양성이 3%인 1,000건의 사기 탐지 데이터를 5겹으로 나눈다고 하면, 단순 무작위 분할에서는 폴드별 양성 수가 많게는 14건에서 적게는 3건까지 들쭉날쭉해 어떤 폴드에서는 재현율을 사실상 측정조차 할 수 없다. 반면 계층적 분할은 모든 폴드에 양성을 약 6건씩 고르게 배치해, 폴드 간 성능 편차 자체를 줄이고 평가를 공정하게 만든다. 소수 클래스가 귀한 데이터일수록 이 차이는 결정적이다.
라. 중첩 교차검증(Nested CV)
하이퍼파라미터 튜닝과 성능 보고를 같은 검증셋으로 하면, 모델이 그 검증셋에 맞춰 선택되므로 보고된 성능이 낙관적으로 부풀려진다. 중첩 교차검증은 이를 막기 위해 루프를 이중으로 둔다. 내부 루프에서 학습 폴드만 다시 쪼개 하이퍼파라미터를 고르고, 외부 루프에서는 그 선택 과정 전체를 하나의 "모델"로 보고 한 번도 보지 않은 외부 검증 폴드로 평가한다. 이렇게 하면 "튜닝을 포함한 전체 파이프라인"의 일반화 성능을 편향 없이 추정할 수 있다.
중첩 교차검증은 계산량이 외부·내부 분할 수의 곱(예: 5×5=25배 학습)으로 늘어나는 대신, 모델 비교를 논문·심사·규제 제출처럼 엄밀하게 보고해야 하는 상황에서 신뢰를 보장한다. 데이터가 적어 과적합 위험이 큰 바이오·의료 분야에서 특히 권장된다.
중첩 교차검증이 드러내는 핵심 통찰은 "하이퍼파라미터 탐색 자체가 하나의 학습 과정"이라는 점이다. 수백 개의 하이퍼파라미터 조합을 검증셋 점수로 고르면, 그 점수가 가장 높게 나온 조합은 실력과 함께 운(noise)까지 최적화한 결과일 수 있다. 예컨대 비중첩 방식으로 측정한 교차검증 정확도가 90%였는데 중첩 방식으로 재측정하니 86%로 떨어지는 경우가 흔하며, 이 4%p의 차이가 바로 "검증셋에 대한 과적합"의 크기다. 운영에 배포하면 결국 86%에 가까운 성능이 나타나므로, 중첩 검증은 배포 후 성능 쇼크를 사전에 드러내는 장치라 할 수 있다.
4. 특수 상황별 교차검증과 데이터 누수 방지
교차검증이 주는 신뢰는 "검증셋이 미래 데이터를 올바르게 흉내 낸다"는 전제 위에 있다. 이 전제가 깨지는 대표적 상황이 시계열과 그룹 구조 데이터이며, 여기서 단순 무작위 K-겹을 쓰면 성능을 심각하게 과대평가한다.
시계열 교차검증은 미래로 학습하고 과거로 평가하는 일을 금지해야 한다. 무작위 분할을 쓰면 미래 시점이 학습에 섞여 들어가 "미래를 알고 과거를 맞히는" 누수가 생기기 때문이다. 대신 TimeSeriesSplit처럼 시간 순서를 지켜 과거로 학습 → 바로 뒤 구간으로 평가하는 전진 검증(forward chaining)을 쓴다. 예컨대 수요예측 모델에서 무작위 K-겹으로는 MAPE 6%가 나왔지만, 시간 순서를 지킨 전진 검증으로는 11%가 나오는 식으로, 전자가 운영 성능을 크게 과대평가하는 경우가 흔하다.
그룹 교차검증(GroupKFold)은 같은 개체(환자·사용자·공장 설비)에서 나온 여러 표본이 학습과 검증에 동시에 들어가지 않도록 그룹 단위로 분할한다. 같은 환자의 여러 CT 영상이 학습과 검증에 나뉘어 들어가면, 모델이 "질병"이 아니라 "그 환자"를 외워 버려 검증 정확도가 95%로 보이지만 새 환자에게는 70%대로 추락하는 식의 누수가 발생한다. 그룹 분할은 이를 구조적으로 차단한다.
데이터 누수 방지는 특수 상황을 넘어 모든 교차검증의 공통 규칙이다. 표준화·결측 대치·피처 선택·오버샘플링(SMOTE) 같은 전처리는 반드시 각 회차의 학습 폴드에서만 적합(fit)하고 검증 폴드에는 변환(transform)만 적용해야 한다. 흔한 실수는 전체 데이터로 한 번 스케일링한 뒤 교차검증을 돌리는 것인데, 이러면 검증 폴드의 분포 정보가 전처리를 통해 학습에 새어 들어가 성능이 부풀려진다. scikit-learn의 Pipeline으로 전처리와 모델을 하나로 묶어 교차검증에 넣으면 이 격리가 자동으로 보장된다.
특히 피처 선택을 교차검증 바깥에서 먼저 수행하는 누수가 치명적이다. 전체 데이터로 타깃과 상관이 높은 상위 피처를 고른 뒤 그 피처로만 교차검증을 돌리면, 피처 선택 단계가 이미 검증 폴드의 정답을 들여다본 셈이어서, 사실은 무의미한 랜덤 피처로도 교차검증 정확도가 70~80%처럼 그럴듯하게 나오는 착시가 생긴다. 올바른 절차는 피처 선택을 각 폴드의 학습 데이터 안으로 넣어 교차검증 루프 안에서 반복하는 것이다. 이 원칙을 지키지 않은 성능 보고는 재현 단계에서 어김없이 무너진다.
5. 심화 — 최신 동향과 실무 적용
AutoML·하이퍼파라미터 최적화와의 결합: Optuna, Auto-sklearn 같은 자동화 도구는 내부적으로 교차검증 점수를 목적함수로 삼아 하이퍼파라미터를 탐색한다. 이때 탐색이 교차검증 점수를 과도하게 좇으면 검증셋에 대한 메타 과적합이 생기므로, 최종 성능은 반드시 탐색에 쓰지 않은 별도 테스트셋이나 중첩 교차검증으로 확인해야 한다는 점이 강조된다.
대규모 딥러닝에서의 현실적 절충: LLM·비전 파운데이션 모델처럼 한 번 학습에 수일~수주가 걸리는 경우 k-겹 반복은 사실상 불가능하다. 이 영역에서는 고정 홀드아웃(train/validation/test) 분할을 쓰되, 대신 데이터 규모가 커서 단일 분할의 분산이 작다는 점으로 신뢰를 확보한다. 즉 교차검증은 데이터가 작을수록 가치가 크고, 클수록 홀드아웃으로 대체되는 경향이 뚜렷하다.
모델 비교의 통계적 유의성: 두 모델의 교차검증 평균 성능 차이가 "우연인지 실제인지"를 판단하려면 단순 평균 비교를 넘어 통계 검정이 필요하다. 다만 교차검증의 폴드 성능들은 학습 데이터가 겹쳐 독립이 아니므로 일반 t-검정은 1종 오류를 부풀린다. 이를 보정한 수정 재표집 t-검정(corrected resampled t-test)이나 반복 교차검증 기반 검정이 권장된다. 이는 앞서 다룬 [[clt-t-z-test]]의 가정(독립성)이 깨질 때의 실무적 대응이라는 점에서 연계해 이해할 가치가 있다.
분포 변화(drift) 시대의 검증: 운영 환경의 데이터 분포가 시간에 따라 바뀌는 상황에서는, 과거 데이터로 측정한 교차검증 성능이 미래를 보장하지 못한다. 따라서 교차검증은 "배포 전 1회 검증"으로 끝나지 않고, 배포 후 [[data-quality-management]]·모니터링과 결합해 주기적으로 재검증하는 MLOps 수명주기의 일부로 자리잡는 추세다.
적대적·공정성 관점의 검증 확장: 최근에는 평균 성능뿐 아니라 집단별(성별·연령·지역) 성능 편차를 교차검증 과정에서 함께 측정해 공정성(fairness)을 점검하려는 흐름이 강하다. 예컨대 그룹별로 층화해 각 집단의 재현율 격차를 폴드마다 집계하면, 전체 정확도는 높지만 특정 소수 집단에서만 성능이 급락하는 모델을 배포 전에 걸러낼 수 있다. 이는 EU AI Act 등 규제가 요구하는 "집단 간 성능 평가"와 맞닿아 있어, 교차검증이 단순 성능 추정을 넘어 책임 있는 AI의 검증 도구로 확장되고 있음을 보여 준다.
6. 고려사항 및 시사점
기술사 관점에서 교차검증은 단순한 통계 기법이 아니라, 제한된 데이터로 신뢰할 수 있는 의사결정을 내리기 위한 설계 활동이다. 기법 선택과 운영에서 다음을 종합적으로 고려해야 한다.
- 데이터 규모에 따른 전략 분리: 수백~수천 건의 소규모 데이터는 K-겹·반복 교차검증으로 분산을 줄이고, 수십만 건 이상 대규모·고비용 학습(딥러닝)은 고정 홀드아웃으로 비용을 통제하는 등 규모에 맞는 절충이 핵심이다.
- 데이터 구조에 맞는 기법 선택(트레이드오프): 분류 불균형은 계층적 K-겹, 시계열은 전진 검증, 반복 측정·개체 중복은 그룹 분할을 적용해야 하며, 이를 무시한 무작위 분할은 성능을 과대평가해 운영 사고로 이어진다.
- 누수 차단을 파이프라인으로 제도화: 전처리의 통계량 적합을 학습 폴드로 한정하는 규칙을 개인의 주의에 맡기지 말고,
Pipeline·특징스토어·검증 자동화로 구조적으로 강제해야 재현성과 신뢰가 확보된다. - 모델 선택과 성능 보고의 분리: 튜닝에 쓴 검증셋으로 최종 성능을 보고하지 않도록 중첩 교차검증이나 별도 테스트셋을 두어 낙관 편향을 제거하고, 규제·감사 대상 모델일수록 엄격히 적용한다.
- 비용-신뢰의 균형과 전망: k·반복 수·중첩 여부는 모두 계산 비용과 추정 신뢰의 교환이므로, 과제의 위험 수준(의료·금융 등 고위험일수록 엄격)에 맞춰 설계한다. 향후에는 AutoML·분산 학습 인프라와 결합해 교차검증을 파이프라인에 내재화하고, 분포 변화에 대응하는 지속 검증으로 확장하는 방향이 유력하다.
참고자료
- scikit-learn, "Cross-validation: evaluating estimator performance" — https://scikit-learn.org/stable/modules/cross_validation.html
- scikit-learn, "Nested versus non-nested cross-validation" — https://scikit-learn.org/stable/auto_examples/model_selection/plot_nested_cross_validation_iris.html
한 줄 요약: 교차검증은 데이터를 여러 학습·검증 분할로 돌려 써서 일반화 성능을 안정적으로 추정하는 기법으로, 편향-분산·비용의 절충으로 k를 정하고(통상 5~10), 데이터 구조(불균형·시계열·그룹)에 맞는 변형과 누수 차단·중첩 검증을 통해 신뢰할 수 있는 모델 선택의 근거를 제공한다.