Cross-Validation
교차 검증은 하나의 데이터셋을 k개의 분할로 번갈아 사용해 모델을 학습하고 평가하여 일반화 성능을 추정합니다. K-겹 교차 검증의 단계와 변형, 데이터 누수, 코드 예제를 다룹니다.
교차 검증은 동일한 데이터셋을 여러 분할로 나누어 모델을 여러 차례 학습 및 평가하고 점수를 결합함으로써, 모델이 보지 못한 데이터에서 얼마나 잘 작동할지 추정합니다. k-겹 교차 검증에서는 데이터를 폴드라고 부르는 k개의 동일한 부분으로 나누고, 각 폴드를 한 번씩 검증 데이터로 사용하며 모델은 나머지 k − 1개 폴드로 학습합니다. k개 점수의 평균은 성능을 추정하고, 점수의 분산은 검증 세트에 어떤 예제가 포함되었는지에 따라 추정치가 얼마나 달라지는지 보여줍니다. 데이터가 너무 적어 단일 홀드아웃 분할로 신뢰할 만한 점수를 얻기 어려운 경우 교차 검증은 표준 평가 방법입니다. 또한 테스트 데이터에 손대지 않고 알고리즘을 비교하고 하이퍼파라미터를 조정하는 데 널리 사용됩니다.
K-겹 교차 검증의 작동 방식#
데이터셋을 한 번 섞은 다음 k개의 폴드로 나누며, 보통 k는 5 또는 10입니다. k회 반복할 때마다 새 모델을 학습합니다. k − 1개 폴드로 학습하고 나머지 폴드로 점수를 계산하므로, 모든 예제는 정확히 한 번 검증에 사용되고 k − 1번 학습에 사용됩니다. k개 점수의 평균을 계산해 표준 편차와 함께 보고합니다. 교차 검증으로 모델 또는 하이퍼파라미터 집합을 선택한 뒤에는 일반적으로 해당 설정을 사용해 전체 학습 데이터로 최종 모델을 다시 학습합니다. 리브원아웃 교차 검증은 k가 예제 수와 같은 극단적인 경우로, 각 반복에서 학습 데이터를 최대한 많이 사용하지만 예제 수만큼 모델을 학습해야 합니다.
교차 검증 점수 읽기#
폴드 간 분산은 평균만큼 많은 정보를 제공합니다. 아래 scikit-learn 스크립트는 함께 제공되는 유방암 데이터셋에 5-겹 교차 검증을 수행합니다.
from sklearn.datasets import load_breast_cancer
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import StratifiedKFold, cross_val_score
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
# 569 labeled tumor samples with 30 features each
X, y = load_breast_cancer(return_X_y=True)
# The scaler sits inside the pipeline, so each round fits it on that round's training folds only
model = make_pipeline(StandardScaler(), LogisticRegression(max_iter=1000))
# 5 stratified folds: each sample is validated exactly once
folds = StratifiedKFold(n_splits=5, shuffle=True, random_state=0)
scores = cross_val_score(model, X, y, cv=folds)
print("Fold accuracies:", scores.round(3))
print(f"Mean {scores.mean():.3f} +/- {scores.std():.3f}")다섯 가지 폴드 정확도는 0.956에서 1.000 사이이며, 평균은 0.979, 표준 편차는 0.014입니다. 단일 80/20 분할을 사용했다면 이 다섯 값 중 하나가 보고되었을 것이며 값의 범위는 4.4%포인트입니다. 파이프라인 내부에 스케일러를 배치하면 검증 폴드가 데이터 전처리 통계에 포함되지 않습니다. 먼저 전체 데이터셋을 스케일링하면 각 검증 폴드의 정보가 학습에 유입되어 데이터 누수가 발생합니다.
교차 검증 변형 선택하기#
일반 k-겹 교차 검증은 예제들이 서로 독립적이며 서로 바꿔 쓸 수 있다고 가정합니다. 그렇지 않은 경우 무작위 분할은 정보를 누출하거나 작업을 제대로 반영하지 않는 폴드를 만들 수 있습니다.
- 계층화 k-겹: 각 폴드의 클래스 비율이 전체 데이터셋의 클래스 비율과 같도록 유지합니다. 그렇지 않으면 폴드에서 드문 클래스가 누락될 수 있는 경우 중요합니다.
- 그룹 k-겹 교차 검증: 환자, 동영상, 현장과 같은 그룹 하나의 모든 예제를 동일한 폴드에 배치하므로 모델이 학습 이미지와 거의 중복된 이미지로 검증되지 않습니다. 계층화 그룹 k-겹 교차 검증은 두 제약을 함께 적용합니다.
- 시계열 분할: 과거 데이터로만 학습하고 그 뒤에 이어지는 기간의 데이터로 검증하며, 각 반복에서 학습 구간을 확장합니다. 시간순 데이터의 순서를 섞으면 모델이 미래 데이터를 보게 되기 때문입니다.
- 중첩 교차 검증: 각 바깥쪽 폴드 안에서 하이퍼파라미터를 조정하는 안쪽 교차 검증 루프를 실행하므로, 보고 대상인 동일한 폴드에 맞춰 조정해 바깥쪽 점수가 부풀려지지 않습니다.
딥러닝을 위한 교차 검증#
딥 네트워크를 k회 학습하면 컴퓨팅 비용도 k배가 됩니다. 따라서 ImageNet 및 COCO와 같은 대규모 데이터셋은 점수가 안정적일 만큼 충분히 큰 단일 고정 검증 분할을 사용합니다. 검증 분할에 각 클래스의 예제가 몇 개밖에 포함되지 않을 수 있는 수백~수천 장 규모의 소규모 비전 데이터셋에서는 교차 검증이 유용합니다. Ultralytics K-겹 교차 검증 가이드는 탐지 데이터셋을 scikit-learn의 KFold으로 다섯 개 폴드로 나누고, 각 폴드의 학습 및 검증 이미지 목록과 데이터셋 YAML을 작성한 다음, 폴드마다 YOLO26 모델 하나를 학습합니다. 탐지 이미지에는 일반적으로 여러 클래스가 포함되므로 단일 레이블로 계층화할 수 없습니다. 따라서 이 가이드에서는 폴드마다 각 클래스의 검증 레이블 대 학습 레이블 비율도 기록합니다.
교차 검증과 관련 용어 비교#
- 홀드아웃 검증: 80/20과 같은 단일 분할을 한 번 평가합니다. 학습 실행 한 번이면 되며 대규모 데이터셋에 적합하지만, 점수는 검증 분할에 어떤 예제가 들어갔는지에 따라 달라집니다.
- 부트스트래핑: 복원 추출로 학습 세트를 만들고, 각 모델의 추출에 포함되지 않은 예제로 점수를 계산합니다. k-겹 교차 검증은 복원 추출 없이 데이터를 분할하므로 각 예제는 정확히 한 폴드에 속합니다.
- 테스트 세트 평가: 교차 검증으로 모델과 설정을 선택합니다. 모든 폴드에서 제외된 별도의 테스트 세트를 사용하면 선택한 모델의 최종 추정치를 얻을 수 있습니다.










