#!/usr/bin/env python3
다양한 교차 검증 방법
1. LOOCVLeave-one-out cross-validation
LOOCV 교차 검증은 폴드 하나에 샘플 하나만 들어 있는 k-겹 교차 검증
각 반복에서 하나의 데이터 포인트를 선택해 테스트 세트로 사용
특히 데이터셋이 클 때는 시간이 매우 오래 걸리지만, 작은 데이터셋에서는 좋은 결과를 만들어냄
# library load
from sklearn.datasets import load_iris
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import LeaveOneOut, cross_val_score, KFold
# dataset
iris = load_iris()
# create object
logreg = LogisticRegression() # model
loo = LeaveOneOut() # LeaveOneOut model
# test validation
# LOOCV
scores_loo = cross_val_score(logreg, iris.data, iris.target, cv=loo)
# K-fold(5)
kfold = KFold(n_splits=5, random_state=0, shuffle=True)
scores_fold = cross_val_score(logreg, iris.data, iris.target, cv=kfold) # model, train, target, cross validation
# cv result
print('iris.data.shape \n{}'.format(iris.data.shape))
print('cv number of partition \n{}'.format(len(scores_loo)))
print('mean score_loocv \n{:.3f}'.format(scores_loo.mean()))
print('mean score_kfold \n{:.3f}'.format(scores_fold.mean()))
cv result
>> LOOCV가 K-fold보다 성능이 더 좋음을 알 수가 있음
2. shuffle-split cross-validation임의 분할 교차 검증
shuffle-split cross-validation에서는
train_size만큼의 포인트로 train set를 만들고, test_size만큼(train set와 중첩되지 않는) 포인트로 test set를 만들도록 분할함
이 분할은 n_splits 횟수만큼 반복됨
# load library
import mglearn
import matplotlib.pyplot as plt
import matplotlib
# matplotlib 설정
matplotlib.rc('font', family='AppleGothic') # 한글출력
plt.rcParams['axes.unicode_minus'] = False # 축 -
mglearn.plots.plot_shuffle_split()
plt.show()
10개의 데이터 포인트에 train_size=5, test_size=2와 n_splits=4를 적용한 ShuffleSplit
>> train_size와 test_size에 정수를 입력하면 데이터포인트의 절대 갯수를
실수를 입력하면 전체 데이터에서의 비율을 의미
# iris데이터를 이용하여 shuffle-split cross-validation
# load library
from sklearn.model_selection import ShuffleSplit
# create object
shuffle_split = ShuffleSplit(test_size=0.5, train_size=0.5, n_splits=10) # ShuffleSplit 객체 생성
# cv test
scores = cross_val_score(logreg, iris.data, iris.target, cv=shuffle_split)
# cv test result
print('cv test score \n{}'.format(scores))
cv test score
>> 임의 분할 교차 검증은 반복 횟수를 훈련 세트나 테스트 세트의 크기와 독립적으로 조절해야 할때 유용함
또한 train_size와 test_size의 합을 전체와 다르게 함으로써 전체 데이터의 일부만 사용할 수 있음
이렇게 데이터를 subsampling부분 샘플링방식은 대규모 데이터셋으로 작업할 때 유용함
3. 그룹별 교차 검증
# load library
mglearn.plots.plot_group_kfold()
plt.show()
레이블에 기반한 GroupKFold분할
>> 이 그림에서 볼 수 있듯이 각 분할에서 한 그룹 전체가 훈련 세트 아니면 테스트 세트에 있음
그룹별 교차 검증의 자세한 정보는 아래 링크 참조
http://scikit-learn.org/stable/modules/cross_validation.html
데이터 안에 매우 연관된 그룹이 있을 때도 교차 검증을 널리 사용함
<<얼굴 사진에서 표정을 인식하는 시스템을 만들기 위해 100명의 사진을 모았다고 가정>>
한 사람을 찍은 여러 장의 사진이 각기 다른 표정을 담고 있음 ==>
이 데이터셋에 없는 사람의 표정을 정확히 구분할 수 있는 분류기를 만드는 것이 목표
같은 사람의 사진이 훈련 세트와 테스트 세트에 모두 나타날 수 있으므로 그룹별 교차겸증을 하는것이 타당함
새 얼굴에 대한 일반화 성능을 더 정확하게 평가하려면
훈련 세트와 테스트 세트에 서로 다른 사람의 사진이 들어가도록 해야함
이를 위해 사진의 사람이 누구인지 기록한 배열을
groups 매개변수로 전달 받을 수 있는 GroupKFold를 사용할 수 있음
groups 배열은 훈련 세트와 테스트 세트를 만들 때 분리되지 않아야 할 그룹을 지정하는 것이라 클래스 레이블과는 다름
데이터에 그룹에 있는 예로는 의료분야가 일반적
여기서는 같은 환자로부터 얻은 여러 샘플을 가지고 새로운 환자에게 일반화하는 것이 목적
비슷하게 음성 인식에서도 데이터셋에 같은 사람의 목소리가 여러 개 녹음되어 있을 수 있으며,
관심사항은 새로운 사람의 대화를 인식하는 것
# load library
from sklearn.model_selection import GroupKFold
from sklearn.datasets import make_blobs
# datasets
x, y = make_blobs(n_samples=12, random_state=0)
plt.scatter(x[:, 0], x[:, 1], c=y)
plt.xlabel('feature 0')
plt.ylabel('feature 1')
plt.show()
make_blobs로 만든 인위적 데이터
>> 인위적으로 만든 데이터셋에 group 배열로 그룹을 지정하는 방법
데이터셋은 12개의 포인트로 이뤄져 있고 groups는 각 데이터 포인트에 대해 각 포인트가 어떤그룹(ex. 환자)에
속하는지를 나타냄
4개의 그룹을 나타내고 있으며 처음 3개의 샘플을 첫번째 그룹, 다음 4개는 두번째 그룹을 나타내는 식
샘플 데이터를 그룹으로 정렬할 필요는 없음
# create object
gkfold = GroupKFold(n_splits=3) # GroupKFold
groups = [0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3, 3] # group class
# cv test
scores = cross_val_score(logreg, x, y, groups, cv=gkfold)
# cv test result
print('cv test score \n{}'.format(scores))
cv test score
'모델 평가와 성능 향상 > 교차 검증' 카테고리의 다른 글
scikit-learn에서의 cross-validation(교차검증) (1) | 2018.04.03 |
---|---|
cross-validation (0) | 2018.04.02 |