교차 검증 반복자(iterators) 로서 KFold, StratifiedKFold를 많이 사용합니다.
비슷하면서도 다른점 있습니다.
https://scikit-learn.org/stable/modules/cross_validation.html#cross-validation
0. 교차 검증 반복자(iterators)란
교차 유효성 검사 전략에 따라 데이터 집합을 생성하는 데 사용할 수 있는 인덱스를 생성하는 도구 입니다.https://scikit-learn.org/stable/modules/cross_validation.html#cross-validation-iterators
1. KFold
먼저 KFold 입니다.그림을 보면 4일때 아래와 같은 그림 형태로 Testing set과 Traing set으로 나뉩니다.
https://scikit-learn.org/stable/modules/cross_validation.html#k-fold
소스
소스로 구현하면 아래와 같습니다.import numpy as np from sklearn.model_selection import StratifiedKFold from sklearn.model_selection import KFold X=np.array([ [ 1, 2, 3, 4], [11,12,13,14], [21,22,23,24], [31,32,33,34], [41,42,43,44], [51,52,53,54], [61,62,63,64], [71,72,73,74] ]) y=np.array([0,0,0,0,0,0,0,0]) kfold = KFold(n_splits=4,random_state=0,shuffle=False) print(X.shape, y.shape) print("\nKFold**************") for train_index, validate_index in kfold.split(X): print("train index:", train_index, "validate index:", validate_index) X_train, X_validate = X[train_index], X[validate_index] y_train, y_validate = y[train_index], y[validate_index] print("train data") print(X_train, y_train) print("validate data") print(X_validate, y_validate)
실행결과
(8, 4) (8,)
KFold************** train index: [2 3 4 5 6 7] validate index: [0 1] train data [[21 22 23 24] [31 32 33 34] [41 42 43 44] [51 52 53 54] [61 62 63 64] [71 72 73 74]] [0 0 0 0 0 0] validate data [[ 1 2 3 4] [11 12 13 14]] [0 0] train index: [0 1 4 5 6 7] validate index: [2 3] train data [[ 1 2 3 4] [11 12 13 14] [41 42 43 44] [51 52 53 54] [61 62 63 64] [71 72 73 74]] [0 0 0 0 0 0] validate data [[21 22 23 24] [31 32 33 34]] [0 0] train index: [0 1 2 3 6 7] validate index: [4 5] train data [[ 1 2 3 4] [11 12 13 14] [21 22 23 24] [31 32 33 34] [61 62 63 64] [71 72 73 74]] [0 0 0 0 0 0] validate data [[41 42 43 44] [51 52 53 54]] [0 0] train index: [0 1 2 3 4 5] validate index: [6 7] train data [[ 1 2 3 4] [11 12 13 14] [21 22 23 24] [31 32 33 34] [41 42 43 44] [51 52 53 54]] [0 0 0 0 0 0] validate data [[61 62 63 64] [71 72 73 74]] [0 0]
소스 설명
아래 함수에 의해 나누는 수치를 결정합니다.kfold = KFold(n_splits=4,random_state=0,shuffle=False)
kfold.split(X) 함수에 의해 나뉘어 집니다.
2. StratifiedKFold
비슷하면서도 다릅니다.https://scikit-learn.org/stable/modules/cross_validation.html#stratified-k-fold
아래 그림에서 보면 계층적으로 나뉩니다.
나뉠때 정보가 필요하기 때문에 인자로 y를 추가로 받습니다.
다음은 예제 입니다.
소스
import numpy as np from sklearn.model_selection import StratifiedKFold from sklearn.model_selection import KFold X=np.array([ [ 1, 2, 3, 4], [11,12,13,14], [21,22,23,24], [31,32,33,34], [41,42,43,44], [51,52,53,54], [61,62,63,64], [71,72,73,74] ]) y=np.array([0,0,0,0,0,0,0,0]) stratifiedkfold = StratifiedKFold(n_splits=4,random_state=0,shuffle=False) print(X.shape, y.shape) print("\nStratifiedKFold**************") for train_index, validate_index in stratifiedkfold.split(X,y): print("train index:", train_index, "validate index:", validate_index) X_train, X_validate = X[train_index], X[validate_index] y_train, y_validate = y[train_index], y[validate_index] print("train data") print(X_train, y_train) print("validate data") print(X_validate, y_validate)
결과
(8, 4) (8,) StratifiedKFold************** train index: [2 3 4 5 6 7] validate index: [0 1] train data [[21 22 23 24] [31 32 33 34] [41 42 43 44] [51 52 53 54] [61 62 63 64] [71 72 73 74]] [0 0 0 0 0 0] validate data [[ 1 2 3 4] [11 12 13 14]] [0 0] train index: [0 1 4 5 6 7] validate index: [2 3] train data [[ 1 2 3 4] [11 12 13 14] [41 42 43 44] [51 52 53 54] [61 62 63 64] [71 72 73 74]] [0 0 0 0 0 0] validate data [[21 22 23 24] [31 32 33 34]] [0 0] train index: [0 1 2 3 6 7] validate index: [4 5] train data [[ 1 2 3 4] [11 12 13 14] [21 22 23 24] [31 32 33 34] [61 62 63 64] [71 72 73 74]] [0 0 0 0 0 0] validate data [[41 42 43 44] [51 52 53 54]] [0 0] train index: [0 1 2 3 4 5] validate index: [6 7] train data [[ 1 2 3 4] [11 12 13 14] [21 22 23 24] [31 32 33 34] [41 42 43 44] [51 52 53 54]] [0 0 0 0 0 0] validate data [[61 62 63 64] [71 72 73 74]] [0 0]
소스 설명
아래 부분은 KFold와 동일합니다.stratifiedkfold = StratifiedKFold(n_splits=4,random_state=0,shuffle=False)
stratifiedkfold.split(X,y): y값을 추가 인자로 받습니다.
주의점
사용시 주의해야 할점이 있습니다.간혹 아래와 같은 에러가 발생하는 경우가 있습니다.
ValueError: n_splits=XX cannot be greater than the number of members in each class.
에러 발생 예제
y=np.array([1,2,3,4,5,6,0,0]) print("\nStratifiedKFold**************") for train_index, validate_index in stratifiedkfold.split(X,y): print("train index:", train_index, "validate index:", validate_index) X_train, X_validate = X[train_index], X[validate_index] y_train, y_validate = y[train_index], y[validate_index] print("train data") print(X_train, y_train) print("validate data") print(X_validate, y_validate)
ValueError: n_splits=4 cannot be greater than the number of members in each class.
사유
y 입력 값을 보면 값 범위가 여러개입니다.(7개 : 0,1,2,3,4,5,6) 우리가 원하는 n_splits=4개로 나누고자 할때 문제가 있어서 오류를 발생하는것입니다. 해결을 위해서는 n_splits 수치를 올려주던가, KFold를 써야 합니다.참조 링크
https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.StratifiedKFold.htmlhttps://scikit-learn.org/stable/modules/cross_validation.html#cross-validation
https://scikit-learn.org/stable/modules/cross_validation.html#cross-validation-iterators
https://scikit-learn.org/stable/modules/cross_validation.html#k-fold
https://scikit-learn.org/stable/modules/cross_validation.html#stratified-k-fold