검증은 배포 환경의 시뮬레이션이다

모델 검증의 목적은 점수 하나를 얻는 것이 아니라, 아직 보지 못한 데이터에서의 성능을 추정하는 것이다. 시계열에서는 “아직 보지 못한 데이터”가 보통 미래를 뜻한다.

Random K-Fold는 관측치를 무작위로 섞는다. 그 결과 학습 집합에 8월 데이터가, 검증 집합에 3월 데이터가 들어갈 수 있다. 현실에서는 8월 정보를 이용해 3월을 예측하지 않으므로 검증 조건이 배포 조건과 달라진다.

누출이 생기는 세 지점

시간 자체의 누출

추세, 계절성, 제도 변화가 있는 데이터에서 미래 구간은 과거 구간에 대한 강력한 단서가 된다.

전처리의 누출

전체 기간으로 스케일러나 결측치 대체값을 학습하면 검증 기간의 분포가 학습 단계에 들어간다. 전처리는 각 fold의 학습 구간에서만 적합해야 한다.

파생 변수의 누출

rolling mean이나 lag 변수를 만들 때 현재 시점 이후의 값이 섞이지 않았는지 확인해야 한다. 특히 가운데 정렬된 이동 평균은 실수하기 쉽다.

Expanding window

가장 기본적인 방법은 학습 구간을 점차 늘리면서 다음 구간을 검증하는 것이다.

FoldTrainValidation
11월–3월4월
21월–4월5월
31월–5월6월
from sklearn.model_selection import TimeSeriesSplit

splitter = TimeSeriesSplit(n_splits=5)
for train_idx, valid_idx in splitter.split(X):
    X_train, X_valid = X[train_idx], X[valid_idx]

Gap과 horizon

실제 예측 시점과 데이터 수집 시점 사이에 지연이 있다면 학습 구간과 검증 구간 사이에 gap을 둬야 한다. 또한 하루 뒤를 예측하는 모델과 30일 뒤를 예측하는 모델은 같은 검증 설계를 쓰면 안 된다.

좋은 validation은 알고리즘보다 운영 상황을 먼저 묻는다. 언제 예측하고, 그때 어떤 정보가 실제로 사용 가능한가?

체크리스트

  • 정렬 기준이 이벤트 시간인지 확인한다.
  • 동일 개체의 가까운 시점이 train과 validation에 동시에 들어가는지 확인한다.
  • 모든 전처리를 fold 안에서 학습한다.
  • 실제 예측 horizon과 같은 길이로 평가한다.
  • 마지막 기간을 완전히 분리한 holdout으로 남긴다.