Machine Learning/Machine Learning

Cross Validation(CV, 교차검증)

데이터 세상 2022. 10. 31. 20:02

Cross Validation(CV, 교차검증)

Training set과 Validation 을 여러번 나눈 뒤 모델의 학습을 검증하는 방식

데이터를 학습용/평가용 데이터 세트로 여러 번 나눈 것의 평균적인 성능을 계산하면, 한 번 나누어서 학습하는 것에 비해 일반화된 성능을 얻을 수 있다.

  • 데이터를 일정한 규칙에 따라 훈련 데이터와 테스트 데이터로 나누어 테스트 데이터에 대한 예측 정확도를 평가하는 방법
  • 교차검증을 사용하여 테스트 데이터에 대해 예측 정확도를 평가하고, 정확도가 최대가 되는 변수의 조합을 선택하는 것
  • '파라미터 추정 ~ 정확도 평가' 반복으로 인해 계산량이 많아지는 단점이 있음

 

Cross Validation 효과 및 사용 이유

모든 데이터 셋을 평가에 활용하기 때문에 데이터셋이 부족할 때 적용

별도로 Validation set으로 빼두었던 데이터도 다시 학습에 재활용되기 때문에, 전체 데이터가 학습/검증으로 한번에 나누기 작은 경우 위와 같이 여러번 데이터를 나누고 각 교차검증마다의 모델 성능을 비교하는 방식으로 학습을 진행하면 된다. 

 

K개의 성능 결과를 통합하여 하나의 결과를 도축하기 때문에 보다 일반화된 모델 성능 평가 가능

하나의 학습/ 검증 데이터로 이루어진 모델은 해당 학습데이터에만 과적합되었을 가능성이 높다.

하지만 여러차례 나누는 교차검증 방식을 통해 전체 데이터 전 범위를 학습하고, 검증 데이터로 성능을 평가함으로써

보다 일반화된 모델을 생성할 수 있다. 

 

k-fold cross validation(k-겹 교차검증)

가장 널리 사용되는 교차 검증 방법의 하나

데이터를 k개로 분할한 뒤, k-1개를 학습용 데이터 세트로, 1개를 평가용 데이터 세트로 사용

이 방법을 k번 반복하여 k개의 성능 지표를 얻어내는 방법

출처: http://ethen8181.github.io/machine-learning/model_selection/model_selection.html

from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import cross_val_score , cross_validate
from sklearn.datasets import load_iris

iris_data = load_iris()
dt_clf = DecisionTreeClassifier(random_state=156)

data = iris_data.data
label = iris_data.target

# 성능 지표는 정확도(accuracy) , 교차 검증 세트는 3개 
scores = cross_val_score(dt_clf , data , label , scoring='accuracy',cv=3)
print('교차 검증별 정확도:',np.round(scores, 4))
print('평균 검증 정확도:', np.round(np.mean(scores), 4))

 

Stratified k-fold cross validation (계층별 k-겹 교차 검증)

데이터 클래스가 불균형한 경우 클래스 별 분포를 고려해서 데이터 폴드 세트는 만드는 방법

출처: https://huidea.tistory.com/30

금융거래 사기 분류 모델에서 전체 데이터중 정상 거래 건수는 95% 사기인 거래건수는 5%라면,

일반적인 교차 검증으로 데이터를 분할했을 때, 사기 거래 건수가 고루 분할되지 못하고 한 분할에 몰릴 수 있다.

각 데이터 폴드마다 정상 거래건수, 사기 거래건수가 고루 들어갈 수 있도록 데이터 클래스별 분포를 고려한 분할 방식

from sklearn.model_selection import StratifiedKFold

skf = StratifiedKFold(n_splits=3)
n_iter=0

for train_index, test_index in skf.split(iris_df, iris_df['label']):
    n_iter += 1
    label_train= iris_df['label'].iloc[train_index]
    label_test= iris_df['label'].iloc[test_index]
    print('## 교차 검증: {0}'.format(n_iter))
    print('학습 레이블 데이터 분포:\n', label_train.value_counts())
    print('검증 레이블 데이터 분포:\n', label_test.value_counts())

 


Hold-Out

데이터셋을 훈련셋과 테스트셋으로 분리

훈련셋과 테스트셋으로만 나눠서 모델의 성능을 평가하다보면, 테스트셋이 모델의 파라미터 설정에 큰 영향을 미치게 된다.

-> 모델이 테스트셋에 오버피팅될 가능성이 높아진다.

 

데이터셋을 훈련셋, 검증셋, 테스트셋 세개로 나누는 것을 권장

  • 훈련셋을 이용해서 모델을 훈련
  • 검증셋으로 모델의 최적 파라미터들을 찾음
  • 테스트셋을 이용해서 모델의 성능을 평가

테스트셋은 모델의 훈련과 성능을 높여주는 과정과는 무관하기 때문에 좀 더 나은 검증방법이라고 볼 수 있다.


References

반응형