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