MLOps 부트캠프 by 한경+토스뱅크/Machine Learning

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

나니니 2024. 8. 25. 21:08

k겹 교차 검증(k-fold cross validation)은 머신 러닝 모델의 성능을 조금 더 정확하게 평가할 수 있는 방법이다. 

머신 러닝 알고리즘을 만들 때, training set은 모델이 인풋 변수를 잉용하여 아웃풋 변수를 예측할 수 있도록 학습시키는데 사용하고, test set은 학습시킨 모델이 얼마나 예측을 잘 하는지, 즉 모델의 성능이 얼마나 좋은지를 파악하기 위해 사용한다. 

 

이렇게 모델의 성능을 파악하면 어떤 문제가 생길 수 있을까?

test set에서만 성능이 좋은 걸 수도 있고, 반대로 test set에서만 성능이 좋지 않게 나올 수도 있다. 

 

교차 검증은 이런 문제를 해결해 주는 방법이다.

k-겹 교차 검증

k-겹 교차 검증은 먼저 전체 데이터를 k개의 같은 사이즈로 나눈 후, 반복적으로 훈련하고 평가하는 방법이다. 

예를 들어보자.

먼저 전체 데이터를 k개의 같은 사이즈로 나눈다. k=5이고 1,000개의 데이터가 있다면 이 데이터를 200개씩 5개의 데이터 셋으로 나누는 것이다. 

이 데이터 셋들을 이용해서 모델의 성능을 여러 번 검증하게 되는데, 아래 이미지와 같이 가장 위에/앞에 있는 데이터 셋을 test set으로 사용하고 나머지를 training set으로 사용했으면 다음은 두 번째 데이터 셋을 test set으로 사용한다. 이 과정을 모든 데이터 셋에 반복해주게 되는데 그러면 5개의 테스트 셋에 대한 성능의 평균을 모델의 성능으로 간주하는 것이다.

모델의 성능을 여러 번 다른 데이터로 검증하기 때문에 평가에 대한 신뢰가 올라가는 것으로 본다. 

k 고르기

k는 데이터가 몇 개 있느냐에 따라 다르지만 가장 일반적으로 사용하는 숫자는 5이다. 또, 데이터가 많을수록 우연히 test set에서만 성능이 다르게 나올 확률이 적기 때문에 작은 k를 사용해도 된다. 

 

cross_val_score

k겹 교차 검증을 한번에 해주는 함수로, 주어진 데이터 셋을 k개로 나눈 후에 각 데이터 셋을 사용해서 모델을 학습하고 평가해준다. 

# 필요한 라이브러리 불러오기
from sklearn import datasets
from sklearn.model_selection import cross_val_score
from sklearn.linear_model import LogisticRegression

import numpy as np
import pandas as pd

import warnings
warnings.simplefilter(action='ignore', category=FutureWarning)

# datasets의 붓꽃 데이터 사용
iris_data = datasets.load_iris()

# X, y를 판다스 데이터프레임으로 저장
X = pd.DataFrame(iris_data.data, columns=iris_data.feature_names)
y = pd.DataFrame(iris_data.target, columns=['Class'])

# 로지스틱 회귀 모델 생성
logistic_model = LogisticRegression(max_iter=2000)

# k겹 교차 검증 시행으로 train_test_split 시행하지 않음
# k겹 교차 검증 시행 -> cross_val_score
cross_val_score(logistic_model, X, y.values.raval(), cv=5) 
# logistic_model: k겹 교차 검증을 할 모델
# X: 입력 변숫
# y: 목표 변수(경고 메시지를 막기 위해 values.raval() 추가)
# 옵셔널 파라미터 cv: k를 정하는 파라미터

# 출력결과
# array([0.96666667, 1.        , 0.93333333, 0.96666667, 1.        ])
 # np.average를 통해 해당 성능의 평균을 확인함
np.average(cross_val_score(logistic_model, X, y.values.ravel(), cv=5))

# 출력 결과
# 0.9733333333333334

예제

입력 변수 취향을 가지고 성별을 예측할 때 로지스틱 회귀 모델의 성능을 k-겹 교차 검증을 사용해서 파악해 볼게요. 아래 나와 있는 내용들을 코드로 구현해 보세요!

로지스틱 회귀 모델을 정의하세요. (옵셔널 파라미터는 solver='saga', max_iter=2000로 설정하세요.)
sklearn.model_selection 모듈의 cross_val_score()을 사용해서 정의한 로지스틱 회귀 모델의 성능을 5-겹 교차 검증 성능을 파악하세요. 이때 numpy 라이브러리의 average() 메소드를 사용해서 평균 성능을 구해주시면 됩니다. (이 데이터는 k_fold_score 변수에 저장하세요)

from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import cross_val_score

import numpy as np
import pandas as pd

GENDER_FILE_PATH = './datasets/gender.csv'

# 데이터 셋 불러오기
gender_df = pd.read_csv(GENDER_FILE_PATH)

X = pd.get_dummies(gender_df.drop(['Gender'], axis=1)) # 입력 변수를 one-hot encode한다
y = gender_df[['Gender']].values.ravel()

# 로지스틱 회귀 모델 정의
logistic_model = LogisticRegression(solver='saga', max_iter=2000)
	# solver:  매개변수는 로지스틱 회귀 모델을 학습할 때 사용되는 최적화 알고리즘을 지정
    # saga
    	# Stochastic Average Gradient 알고리즘을 사용합니다. 이 방법은 대규모 데이터셋에서 효율적이며, 특히 L1 및 L2 정규화를 지원합니다.
		# 장점: 매우 큰 데이터셋에서도 잘 작동하며, 규제된 손실 함수에서 좋은 성능을 보입니다.

# sklearn.model_selection모듈의 cross_val_score() 사용
k_fold_score = np.average(cross_val_score(logistic_model, X, y, cv=5))
	# numpy의 average()메소드를 이용해 평균 성능 구하기
    # k_fold_score 변수에 저장
k_fold_score