교차 검증
전체 데이터 세트의 샘플 개수가 많지 않을 때 검증 세트와 훈련 세트를 분리하여 사용하느라 훈련이 제대로 이루어지지 않을 결루도 있다.
이때, 교차 검증(cross validation)은 이런 경우에 사용하면 좋다.
교차 검증의 원리
교차 검증은 훈련 세트를 작은 덩어리로 나누어 다음과 같이 진행한다.
이때 훈련 세트를 나눈 작은 덩어리를 '폴드'라고 한다.
폴드를 1번씩 검증에 사용하며 훈련한다.
교차 검증 과정
- 훈련 세트를 k개의 폴드(fold)로 나눈다.
- 첫 번째 폴드를 검증 세트로 사용하고 나머지 폴드(k-1개)를 훈련 세트로 사용한다.
- 모델을 훈련한 다음에 검증 세트로 평가한다.
- 차례대로 다음 폴드를 검증 세트로 사용하여 반복한다.
- k개의 검증 세트로 k번 성능을 평가한 후 계산된 성능의 평균을 내어 최종 성능을 계산한다.
훈련 세트를 k개의 폴드로 나누는 특징 때문에 k-폴드 교차 검증이라 한다.
훈련 세트 사용
각 폴드의 검증 점수를 저장하기 위한 validation_scores 리스트를 정의한다.
validation_scores = []
k-폴드 교차 검증 구현
k = 10
bins = len(x_train) // k
for i in range(k):
start = i * bins
end = (i+1) * bins
val_fold = x_train_all[start:end]
val_target = y_train_all[start:end]
train_index = list(range(0,start)) + list(range(end, len(x_train)))
train_fold = x_train_all[train_index]
train_target = y_train_all[train_index]
train_mean = np.mean(train_fold, axis=0)
train_std = np.std(train_fold, axis=0)
train_fold_scaled = (train_fold - train_mean) / train_std
val_fold_scaled = (val_fold - train_mean) / train_std
lyr = SinleLayer(l2=0.01)
lyr.fit(train_fole_scaled, train_target, epochs=50)
score = lyr.score(val_fold_scaled, val_target)
validation_scores.append(score)
print(np.mean(validation_scores))
k개로 이루어진 폴드를 만들어 폴드 수만큼 훈련을 진행한다.
사이킷런 교차 검증
사이킷런의 model_selection 모듈에는 교차 검증을 위한 cross_validate( ) 함수가 있다.
Pipeline 클래스 사용
사이킷런은 검증 폴드가 전처리 단계에서 누설되지 않도록 전처리 단계와 모델 클래스를 하나로 연결해 주는
Pipeline 클래스를 제공한다.
먼저 표준화 전처리 단계와 SGDClassifier 클래스 객체를 Pipeline 클래스로 감싸 cross_validate() 함수에 전달한다.
그러면 cross_validate() 함수는 훈련 세트를 훈련 폴드와 검증 폴드로 나누기만 하고 전처리 단계와 SGDClassifier 클래스 객체의 호출은 Pipeline 클래스 객체에서 이뤄진다.
이렇게 하면 검증 폴드가 전처리 단계에서 누설되지 않게 된다.