728x90
반응형

교차 검증(cross validation)

  • 전체 데이터 세트의 샘플 개수가 많지 않을 때 검증 세트를 훈련 세트에서 분리하느라 훈련 세트의 샘플 개수가 줄어들어 모델을 훈련시킬 데이터가 부족해지는 경우
  • 훈련 세트를 작은 덩어리로 나누고 이 작은 덩어리를 '폴드'라고 부른다.

[그림1] 폴드

  • 8:2로 나누고 8에 해당하는 훈련 세트 다시 5개 작은 덩어리로 나눈다. 그 후 작은 덩어리를 1번씩 검증에 사용하고 나머지 덩어리를 훈련에 사용

 

 

교차 검증 과정

  1. 훈련 세트를 k개의 폴드(fold)로 나눈다.
  2. 첫 번째 폴드를 검증 세트로 사용하고 나머지 폴드(k-1)를 훈련 세트로 사용한다.
  3. 모델을 훈련한 다음에 검증 세트로 평가한다.
  4. 차례대로 다음 폴드를 검증 세트로 사용해 반복한다.
  5. k개의 검증 세트로 k번 성능을 평가한 후 계산된 성능의 평균을 내어 최종 성능을 계산한다.

 

k-폴드 교차 검증

  • 훈련 세트를 k개의 폴드로 나누는 특징이 있으므로 k-폴드 교차 검증이라고 부른다.
  • 기존의 훈련 방법보다 더 많은 데이터 훈련 가능
  • k가 10이면 10개의 폴드가 생김 90% 샘플 훈련 사용
  • 기존 6:2:2 훈련보다 30% 정도 더 많은 데이터로 훈련 가능
  • 훈련 세트를 동일한 크기의 폴드가 k개가 되도록 나눈다.
  • 각 폴드를 검증 세트로, 나머지 폴드를 훈련 세트로 사용한다.

 

1. 훈련 세트 사용

  • 8:2비율 훈련 세트 테스트 세트 - 기존 방식 그 후 훈련 세트 8:2 훈련 세트 검증 세트
  • 검증 세트가 훈련 세트에 포함된다.
  • 전체 데이터 세트를 다시 훈련 세트와 테스트 세트로 1번만 나눈 x_train_all, y_train_all을 훈련과 검증 사용
  • 각 폴드의 검증 점수를 저장하기 위한 validation_scores 리스트 정의 - 리스트가 값 평균해 최종 검증 점수 계산
# 1. 훈련 세트 사용하기
validation_scores = []

 

2. k-폴드 교차 검증 구현하기

  • start와 end는 각각 검증 폴드 샘플 시작과 끝
# 2. k-폴드 교차 검증 구현

k = 10 
bins = len(x_train_all) // 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 = SingleLayer(l2=0.01)
    lyr.fit(train_fold_scaled, train_target, epochs=50)
    score=lyr.score(val_fold_scaled, val_target)
    validation_scores.append(score)
    
print(np.mean(validation_scores))

[그림2] k-폴드 교차 검증 결과

 

  • 훈련 데이터의 표준화 전처리를 폴드를 나눈 후에 수앵한다.
  • 폴드를 나누기 전에 전체 훈련 데이터를 전처리한다면 검증 폴드의 정보를 누설하게 되는 셈이다.

[그림3] 검증 폴드

 

 

사이킷런으로 교차 검증

  • model_selection모듈에는 교차 검증을 위한 cross_validate() 함수가 있다.

 

1. cross_validate() 함수로 교차 검증 점수 계산하기

  • cross_validate() 함수는 매개변수 값으로 교차 검증을 하고 싶은 모델의 객체와 훈련 데이터, 타깃 데이터를 전달하고 cv 매개변수에 교차 검증을 수행할 폴드 수를 지정하면 된다.
  • cv의 기본값은 3이지만 사이킷런 0.22 버전부터 5로 바뀔 예정
# 사이킷런으로 교차 검증

from sklearn.model_selection import cross_validate
sgd = SGDClassifier(loss='log', penalty='l2', alpha=0.001, random_state=42)
scores = cross_validate(sgd, x_train_all, y_train_all, cv=10)
print(np.mean(scores['test_score']))
# 표준화 전처리를 수행하지 않아 평균 점수 85%로 낮다.

 

전처리 단계 포함해 교차 검증 수행

  • 이전에는 교차 검증 구현 시 폴드를 나눈 후에 훈련 폴드의 통계치(평균, 표준편차)로 검증 폴드를 전 처리했다.
  • 검증 폴드가 전처리 단계에서 누설되면 안 되기 때문
  • 훈련 세트 전체 전처리 후 cross_validate() 함수에 매개변수 값으로 전달하면 검증 폴드가 표준화 전처리 단계에서 누설된다.

Pipeline 클래스 사용해 교차 검증 수행

  • 검증 폴드가 전처리 단계에서 누설되지 않도록 Pipeline 클래스 제공
# Pipeline 클래스 사용해 교차 검증 수행

from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
pipe = make_pipeline(StandardScaler(), sgd)
scores = cross_validate(pipe, x_train_all, y_train_all, cv=10, return_train_score=True)
print(np.mean(scores['test_score']))

[그림4] Pipeline 클래스 사용해 검증

 

print(np.mean(scores['train_score']))

[그림5] 훈련 폴드 점수

728x90
반응형
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기