앞선 문제를 회피 혹은 감수 하면서도 검증의 원래 의미를 살리는 평가를 진행하는 방법 :
교차 검증 (Cross Validation)

전체 데이터 세트를 총 K개의 덩어리(폴드, Fold)로 나누고, 각 덩어리(폴드)를 순차적으로 검증 데이터로 사용하는 방법

K-Fold CV와 유사하지만, 각 폴드에서 클래스의 비율을 원본 데이터셋의 클래스 비율과 유사하게 유지
남성이 80% 여자가 20%였던 데이터가 있다면
k-fold처럼 데이터를 나눠서 검증을 하지만!
비율을 맞춰서 나눈다.

과정
• 클래스 별로 데이터를 분할
• 각 클래스 데이터를 K 개의 폴드로 나눔
• 각 클래스에 존재하는 K 개의 폴드를 하나씩 조합 → K 개의 조합 생성
• 이후 과정은 K-Fold CV 와 동일
의미
• K-Fold의 장점과 더불어
• 클래스 사이의 불균형이 있는 경우의 편향까지 고려
한 번에 하나의 데이터 포인트만을 검증 데이터로 사용

이전에 사용했던 선형 분류 모델을 사용할 예정이다.

기존에는 Random Split을 활용해 정확도를 추정했었다.
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=seed)
logistic_reg.fit(X_train, y_train)
y_pred = logistic_reg.predict(X_test)
accuracy_random_split = accuracy_score(y_test, y_pred)
print(f'Random Split 결과 정확도 : {accuracy_random_split*100:.2f} %')
출력값:
Random Split 결과 정확도 : 92.00 %
이후 각 교차 검증 방법으로 검증을 해보자.
from sklearn.model_selection import cross_val_score
k_fold_score = np.mean(cross_val_score(logistic_reg, X, y, cv=5))
print(f'K-Fold CV 결과 정확도 : {k_fold_score*100:.2f} %')
출력값:
K-Fold CV 결과 정확도 : 93.20 %
from sklearn.model_selection import cross_val_score, StratifiedKFold
stratified_cv_score = np.mean(cross_val_score(logistic_reg, X, y, cv=StratifiedKFold(5)))
print(f'Stratified CV 결과 정확도 : {stratified_cv_score*100:.2f} %')
출력값:
Stratified CV 결과 정확도 : 93.20 %
from sklearn.model_selection import cross_val_score, LeaveOneOut
loocv_score = np.mean(cross_val_score(logistic_reg, X, y, cv=LeaveOneOut()))
print(f'LOOCV 결과 정확도 : {loocv_score*100:.2f} %')
출력값:
LOOCV 결과 정확도 : 93.20 %
해당 모델은 잘 분류되어있는 모습이기 때문에 정확도가 전체적으로 높게 나오는 것을 볼 수 있다.
일반적으로 실무에서는 불균형이 심한경우는 Stratified CV를, 그렇지 않으면 K-Fold CV를 사용한다고 한다.