본문 바로가기
머신러닝 및 딥러닝

교차검증

by 너부리부리부 2023. 5. 14.

교차검증(cross-validation)은 머신러닝 모델의 성능을 측정하기 위해 데이터를 여러 개의 부분집합으로 나누어 각각의 부분집합을 사용해 모델을 학습하고 평가하는 방법입니다.

 

일반적으로 교차검증은 k-fold cross-validation 방법을 사용합니다. 이 방법에서는 데이터를 k개의 부분집합으로 나누어 각각의 부분집합을 순차적으로 테스트 데이터셋으로 사용하고 나머지 k-1개의 부분집합을 학습 데이터셋으로 사용하여 모델을 학습합니다. 이렇게 k번 반복하여 각각의 테스트 데이터셋에서 모델을 평가하고, 평가 점수의 평균을 모델의 성능으로 측정합니다.

이 방법을 사용하면, 데이터를 모델 학습에 모두 사용할 수 있어서 모델의 성능을 더 정확하게 측정할 수 있으며, 과적합(overfitting)을 방지하기 위한 검증 데이터셋이 따로 필요하지 않습니다. 또한, 일반적으로 교차검증의 성능 평가는 테스트 데이터셋을 단 한번 사용하는 것보다 더 신뢰성이 높습니다.

 

KFold

from sklearn.model_selection import KFold
import numpy as np

# iris 데이터셋을 불러와 DecisionTreeClassifier 모델 객체인 dt_clf 생성
iris = load_iris()
dt_clf = DecisionTreeClassifier(random_state=156)

# KFold 교차검증 객체 kfold 생성
# n_splites=5는 5개의 폴드(fold)로 데이터를 나누겠다는 것을 의미, 
# shuffle=False는 데이터를 섞지않고 순서대로 나누겠다는 것을 의미
# 각 폴드의 검증 성능(accuracy)을 담아둘 빈 리스트 생성
kfold = KFold(n_splits=5, shuffle=False)
cv_accuracy = []

# iris.target은 150개의 샘플들에 대한 레이블(타겟)정보 속성
print(iris.target.shape)

출력된 데이터를 보면 iris 데이터셋에 150개의 샘플 각각에 대한 레이블이 1차원 배열 형태로 저장되어있습니다.

# 반복 횟수를 추적하기 위한 변수 초기화
n_iter = 0

for train_index, test_index in kfold.split(iris.data):
    # 학습 데이터와 검증 데이터에 대한 입력 특성 할당
    x_train, x_test = iris.data[train_index], iris.data[test_index]
    
    # 학습 데이터와 검증 데이터에 대한 타깃 레이블 할당
    y_train, y_test = iris.target[train_index], iris.target[test_index]
    
    # 학습 데이터로 결정 트리 분류기 학습
    dt_clf.fit(x_train, y_train)
    
    # 학습된 모델을 사용하여 검증 데이터의 타깃 레이블 예측
    pred = dt_clf.predict(x_test)
    
    # 반복 횟수를 1씩 증가
    n_iter += 1
    
    # 모델의 정확도를 검증 데이터의 예측 레이블과 실제 레이블을 비교하여 계산. 소수점 넷째자리에서 반올림
    accuracy = np.round(accuracy_score(y_test,pred),4)
    
    # 학습 데이터 크기
    train_size = x_train.shape[0]
    
    # 검증 데이터 크기
    test_size = x_test.shape[0]
    
    # 각 반복에서 모델의 정확도, 학습 데이터 크기, 검증 데이터 크기 출력
    print(f'{n_iter} 교차 검증 정확도 : {accuracy}, 학습데이터 크기: {train_size}, 검증데이터 크기 : {test_size}')
    
    # 각 반복에서 검증 데이터 인덱스 출력
    print(f'검증데이터 인덱스:{test_index}')
    
    # 현재 반복에서 계산된 정확도를 cv_accuracy 리스트에 추가
    cv_accuracy.append(accuracy)
    
# 모든 반복에서 계산된 정확도의 평균값 출력
print(f'평균 정확도:{np.mean(cv_accuracy)}')

 

5-fold 교차검증을 수행한 결과로 1번부터 5번까지의 교차 검증 정확도는 각각 1.0, 0.9667, 0.8667, 0.9333, 0.7333입니다.

마지막 5번의 교차검증 정확도의 평균값이 0.9이므로 예측성능은 평균적으로 90%정도라고 해석 할 수 있습니다.

corss_val_score()

교차검증을 좀 더 편리하게 수행할 수 있게 해주는 API를 제공합니다.

# sklearn.model_selection 모듈에서 cross_val_score() 함수를 import하고, 
# DecisionTreeClassifier를 사용하여 붓꽃 데이터(iris dataset)를 교차검증(cross-validation)
from sklearn.model_selection import cross_val_score

# DecisionTreeClassifier 클래스 객체를 생성. 이때, random_state 매개변수 지정하여 항상 같은 결과 나오도록 설정
dt_clf = DecisionTreeClassifier(random_state=156)

# 교차검증 수행 함수
# estimator : 분류기 모델 객체 입력(위에 dt_clf), x : 독립변수 데이터셋, y : 종속변수 데이터셋
# cv : 교차검증 분할 수(cv=3은 3개의 폴드(fold)를 사용하여 교차검증)
# scoring : 평가 지표 지정, verbose : 실행 과정을 출력할 지 여부 결정(0이면 출력x, 1이상의 정수면 해당 값을 주기마다 출력)
cross_val_score(df_clf, 
                iris.data, 
                iris.target,
                cv=3,
                scoring='accuracy',
                verbose=0)
print('교차 검증별 정확도:', np.round(scores,4))
print('평균 검증 정확도:', np.round(np.mean(scores),4))

위코드 실행결과 3개의 교차검증에서 얻은 정확도는 각각 0.98, 0.92, 0.98이며, 이들의 평균값은 0.96입니다.

따라서 위 모델은 평균적으로 약 96%의 정확도를 보인다고 해석 할 수 있습니다.

댓글