데이터셋을 학습용(train), 검증용(validation), 테스트용(test)으로 나누는 도구 또는 알고리즘입니다.
올바른 분할은 모델 성능의 신뢰도와 일반화 능력 평가에 매우 중요합니다.
대표 예
train_test_split
KFold, StratifiedKFold
GroupKFold
TimeSeriesSplit (시계열)
모델 성능 검증
하이퍼파라미터 튜닝 결합
GridSearchCV, RandomizedSearchCV 등은 내부적으로 Splitter를 활용합니다.클래스 불균형 해결
Stratified 옵션을 적용하면 적은 클래스가 과소표본되는 문제를 완화할 수 있음.시계열 예측
TimeSeriesSplit을 사용해야 함.train_test_split
가장 널리 사용되는 기본 분할기
무작위 샘플링으로 단순하고 빠름
옵션: test_size, train_size, random_state, stratify
KFold
데이터를 K개의 폴드로 나누고 번갈아 테스트셋으로 사용
단점: 클래스 불균형 환경에서 성능 왜곡 가능
StratifiedKFold
K-Fold에 계층화(stratify) 개념이 추가된 형태
분류 문제에서 가장 널리 사용
GroupKFold
하나의 그룹이 train과 test에 동시에 들어가는 것을 방지
예: 한 사용자의 데이터가 두 세트로 나뉘면 안 되는 경우
TimeSeriesSplit
시간 순서를 보존하면서 학습/검증 데이터 생성
미래 정보가 과거로 새어 들어가는 data leakage 방지
무작위 분할로 인한 데이터 편향
특히 소수 클래스가 있는 분류 문제 → stratify=y 필수
데이터 누수(Data Leakage) 방지
스케일링, 인코딩 같은 전처리는 반드시 학습용 데이터로만 fit, 테스트에는 transform 해야 함.
Pipeline 사용 권장.
시계열 데이터는 절대 random split 금지
그룹 데이터 주의 (한 고객·한 환자)
고객 단위로 분리해야 데이터 누수 방지 가능
예: 고객 1의 구매 이력 일부가 train, 일부가 test → 안 됨
train_test_split 함수로 데이터를 무작위로 분할
stratify=y 옵션으로 클래스 비율을 유지
random_state=42로 결과를 재현 가능하게 설정
분류(Classification) 문제에서 클래스 비율이 중요한 경우
무작위 분할(random split)이 허용되는 일반적인 머신러닝 상황
이미지, 탭울러 데이터, 텍스트 등 대부분의 정형 데이터
from sklearn.model_selection import train_test_split
X = [[1], [2], [3], [4], [5], [6]]
y = [0, 1, 0, 1, 0, 1]
X: 특징(feature)
y: 레이블(label)
0과 1 클래스가 번갈아 나오므로 불균형 문제는 없지만, stratify 테스트 목적에 적합한 데이터
X_train, X_test, y_train, y_test = train_test_split(
X,
y,
test_size=0.33,
random_state=42,
stratify=y
)
test_size=0.33: 전체의 33%를 테스트셋으로 사용
stratify=y
y의 0과 1 비율을 train과 test에 동일하게 유지
예: 전체에서 0:3, 1:3 이라면 train과 test에서도 동일한 비율로 분배
random_state=42: 결과가 재현 가능하도록 난수 시드 고정
print("Train:", X_train, y_train)
print("Test:", X_test, y_test)
분류(Classification) 문제에서는 반드시 stratify 사용하는 것이 안정적으로 일반적인 성능 측정 가능
train/test에 클래스 비율이 다르면 모델 성능이 왜곡될 수 있음
random_state를 고정하면 협업/배포 환경에서 재현성 확보됨
TimeSeriesSplit은 데이터를 시간 순서대로 증가시키며 분할
과거 데이터로 학습하고 미래 데이터로 테스트하는 구조
시계열 예측에서 반드시 사용해야 하는 split 방식
시간 흐름이 중요한 시계열 데이터(Time Series)
예: 매출 예측, 주가 예측, 센서 데이터, 사용자 로그 데이터
미래 정보를 과거 모델 학습에 사용하면 안 되는 경우 → 데이터 누수 방지
from sklearn.model_selection import TimeSeriesSplit
import numpy as np
tscv = TimeSeriesSplit(n_splits=3)
data = np.arange(10)
n_splits=3: 학습/검증을 3번 반복
data = np.arange(10) → 시계열 데이터를 0~9의 숫자로 가정
for train_index, test_index in tscv.split(data):
print("Train:", train_index, " Test:", test_index)
출력 구조는 예를 들어 다음과 같습니다:
1번째 split
Train: [0,1]
Test: [2]
2번째 split
Train: [0,1,2,3]
Test: [4]
3번째 split
Train: [0,1,2,3,4,5]
Test: [6]
(데이터 길이에 따라 달라질 수 있음)
항상 과거 데이터 → 미래 데이터 순서
train이 점점 커지는 expanding window 방식
무작위가 아니라 시간순으로 고정된 split
시계열 예측에서는 절대 train_test_split(random) 사용 금지
→ 미래 데이터가 훈련 데이터에 섞여 성능이 거짓으로 높아지는 데이터 누수 발생
TimeSeriesSplit은 모델의 미래 예측 능력을 실제처럼 평가할 수 있음
| 방식 | 목적 | 특징 | 사용 사례 |
|---|---|---|---|
| train_test_split + stratify | 일반 ML 분류 | 무작위 분할, 클래스 비율 유지 | 이미지, 탭울러, 일반 데이터 |
| TimeSeriesSplit | 시계열 ML | 시간 순서 유지, expanding 검증 | 매출 예측, 경제지표, IoT 센서 |