Machine Learning/Fundamentals

Cross-Validation (concepts + w/code)

metamong 2022. 4. 17.

* 머신러닝을 위해서 무.조.건. 알아야 하는 CROSS-VALIDATION! 간단히 개념만 알아보ZA *

* concepts>

- 2번 과정 - model selection에서 주로 많이 쓰이는 cross-validation 기법 -

 

🧐 PURPOSE?

'The purpose of cross–validation is to test the ability of a machine learning model to predict new data.

 

Q. 그러면 CV(Cross-Validation)에서는 무엇을 가지고 여러 모델의 성능을 평가할 수 있을까?

 

A. 두 가지 필요 - train data & test data (from the dataset)

 

1) estimate the parameters for ML methods (estimating parameters = training the algorithm) <TRAIN>

→ 즉, 직접 train data로 학습시켜 모델을 만든다는 뜻

2) evaluate how well the ML methods work (evaluating mehod = testing the algorithm) <TEST>

→ 즉, 이제 만들어진 model을 가지고 test data를 이용해 model의 성능을 평가!

 

🙋🏽‍♂️ 여기서 꼭 짚고 넘어가야 할 train & test data 선별! 🙋🏽‍♂️

 

① 주어진 data를 모조리 train data에 쓴다? ❌

→ 그럼 test할 data가 없음 ㅠ

 

② 그럼 train data를 가지고 그대로 test data로도 쓴다? 

→ 우리가 모델을 만드는 이유가 학습되지 않은 새로운 data에 대한 학습능력을 평가하는 건데 train data를 그대로? 말이 안됨

 

③ 그러면 전체 dataset의 일부는 train data로, 나머지는 test data로 쓰는 건? ⭕

→ Good. train & test 간의 중복도 없고 실제 model을 test하기에 딱 좋은 환경 조성 ok = CV 핵심

 

- MATLAB 출처 -

 

- 위 예에서는 training set : test set의 비율을 3 : 1로 두었다 - (주로 test set보다 training set 비중이 높음)

 

→ 이미 어떤 종류의 model을 할 지는 정해진 상황! 이제 관건은 해당 종류를 쓸 건지 말 건지 model selection만 진행하면 됨!

→ Fold1) training set으로 해당 model을 완성하고 그 model에 test set을 대입해 모델의 성능 파악

→ Fold2) 이젠 다른 data로 똑같이 진행

 

→ 위 예의 경우 총 4번을 진행했고 우리는 이걸 Four-Fold CV라 부른다 (즉, n번 진행하면 N-Fold CV)

→ 극단적 케이스로 모든 data마다 block을 나누어 한 block을 test set으로 일일이 실험하는 경우 Leave One Out CV라 부른다

 

'Cross-Validation allows us to compare different ML methods and get a sense of how well they will work in practice'

 

* dataset 자체의 크기가 작을 경우 역시 모델링하기가 어렵다.

이 때 dataset에서 training set과 test set을 여러 번 번갈아 나누어 자체 testing 하자

 

'When the amount of labeled data available is small, it may not be feasible to construct training and test sets.

In that case, use cross validation: divide the dataset into ten parts of (roughly) equal size,

then for each of these ten parts, train the classifier on the other nine and test on the held-out part.'

 

 

※ 추가적으로 (grid search를 이용한) model selection이 아니라 model의 tuning parameter를 고를 때도 CV 진행할 수 있다 ※

 

→ model에 들어갈 인자 value를 어떤 값으로 정해야 model의 최적의 성능이 나올 지 고르는 것이다

→ 이 때, 위에서는 model 종류별로 각각 CV를 실행했다면, 내가 정한 parameter value 별로 각각 CV를 실행해 볼 수 있다 

 

↗ ex) ridge와 lasso에서 penalty라는 tuning parameter 구할 때 주로 CV 기법을 사용

 

 

Q. the dangers of CV?

 

A. 'However, the problem with cross-validation is that it is rarely applicable to real world problems, for all the reasons describedin the above sections. Cross-validation only works in the same cases where you can randomly shuffle your data to choose a validation set.'

→ 즉 CV를 사용한다는 건 모든 data가 validation set에도 사용 가능하다는 뜻. 예를 들어 시계열 data같은 경우 너무 오래된 data를 검증 data로 쓴다면 오히려 모델 성능이 떨어질 수 있기에. 정말로 data자체가 랜덤으로 섞여 서로서로 검증이거나 훈련이거나 상관없을 때. 하지만 실제 세계 data에서는 랜덤성이 보장되는 경우가 거의 없기에 CV기법을 지양한다는 뜻.


* w/code>

* 이미 만들어진 iris target과 iris data를 이용해 cross-validation을 적용해보자

* 적용 모델은 linear kernel SVM(모델 곧 다룰 예정!)

 

clf = svm.SVC(kernel='linear', C=100)
scores = cross_validation.cross_val_score(clf, iris.data, iris.target, cv=5) #5-fold CV

scores
#array([ 1.  ...,  0.96...,  0.9 ...,  0.96...,  1.  ...])

 

* 추가로 CV의 결과로 결정지을 scoring method를 사용자 지정으로 바꿀 수 있다.

 

from sklearn import metrics

cross_validation.cross_val_score(clf, iris.data, iris.target, cv=5, score_func=metrics.f1_score)

! 종류>

① K-Fold

→ 가장 흔하게 쓰이는 CV 기법. 주어진 dataset을 K등분(똑같은 간격으로 등분)하여 1개는 test, 나머지 (K-1)개는 train용으로 등분된 data 모두 번갈아 test용으로 쓴다.

 

예) 2-Fold (kFold()의 두 번째 인자를 설정)

 

import numpy as np
from sklearn.cross_validation import KFold
X = np.array([[0., 0.], [1., 1.], [-1., -1.], [2., 2.]])
Y = np.array([0, 1, 0, 1])

kf = KFold(len(Y), 2, indices=False) #2-Fold
print kf
#sklearn.cross_validation.KFold(n=4, k=2)

for train, test in kf:
	print train, test
#[False False  True  True] [ True  True False False]
#[ True  True False False] [False False  True  True]

 

② stratified K-Fold

→ 위 K-Fold에서 불균형한 dataset 문제점을 보완하기 위해 균등하게 학습시키는 함수이다. 

→ 직접 학습시킬 label값을 집어넣어주면(이 때 균일한 %로 배분된 label을 넣어주어야 해당 비율에 맞게 K-Fold를 시행해줌), label의 분포에 따른 K-Fold를 진행한다.

 

 예) stratified 2-Fold (StratifiedKFold()에 lables값을 넣어줌)

 

from sklearn.cross_validation import StratifiedKFold

X = [[0., 0.], [1., 1.], [-1., -1.], [2., 2.], [3., 3.], [4., 4.],[0., 1.]]
Y = [0, 0, 0, 1, 1, 1, 0]

skf = StratifiedKFold(Y, 2)

print skf
#sklearn.cross_validation.StratifiedKFold(labels=[0 0 0 1 1 1 0], k=2)

 

Leave-One-Out(LOO)

→ 위 K-Fold에서 n개의 data가 존재한다면 K-fold의 K가 n하고 동일한 경우의 CV기법이다. 

→ 즉 모든 data 한 개씩 test set으로 사용된다는 뜻.

주로 data 개수가 작을 때 충분히 test할 횟수가 적게 판단되므로 이럴 상황에서 LOO 사용

 

from sklearn.cross_validation import LeaveOneOut
X = np.array([[0., 0.], [1., 1.], [-1., -1.], [2., 2.]])
Y = np.array([0, 1, 0, 1])

loo = LeaveOneOut(len(Y))
print loo
#sklearn.cross_validation.LeaveOneOut(n=4)

 

Leave-P-Out(LPO)

→ 위 LOO기법과 달리 LPO기법은 한 개가 아니라 P개의 dataset을 test set으로 사용한다.

→ 전체 n개 중 P개를 뽑아 총 ${}_n C_P$번의 validation을 거치므로 굉장히 많은 validation이 진행된다. 따라서 크기가 큰 data에서는 권장되지 않음

 

→ 예) Leave-2-out

 

from sklearn.cross_validation import LeavePOut

X = [[0., 0.], [1., 1.], [-1., -1.], [2., 2.]]
Y = [0, 1, 0, 1]


lpo = LeavePOut(len(Y), 2)
print lpo #p - 2
#sklearn.cross_validation.LeavePOut(n=4, p=2)

 

- (위) LPO / (아래) LOO -

 

⑤ Random Permutation CV (Shuffle & Split)

→ 애초에 K-fold는 label이 불균형할 경우 치우친 결과를 보여 잘못해석할 확률이 매우 높은데, 애초에 random하게 섞인 sample이라면 랜덤성에 의해 해당 불균형 문제를 걱정안해도 된다. (random_state 값을 임의의 값으로 설정해 랜덤 seed 고정)

n_iteration 인자로 몇 번 validate할 지 (K) 임의로 설정가능하고, 또한 test_fraction 인자로 얼마의 비율로 test set과 train set으로 나눌 지도 임의로 설정 가능하다. (K-Fold의 경우 n_iteration과 test_fraction이 동일해 따로 설정을 못했으나 ShuffleSplit()은 자유롭게 설정 가능)

 

ss = cross_validation.ShuffleSplit(5, n_iterations=3, test_fraction=0.25, random_state=0)

print ss                                            
#ShuffleSplit(5, n_iterations=3, test_fraction=0.25, indices=True, ...)
#3 Folds, 4/5 length of test set, total of 5 datasets

 


* 출처1) https://www.fast.ai/2017/11/13/validation-sets/

* 출처2) https://kr.mathworks.com/discovery/cross-validation.html (MATLAB)

* 출처3) https://www.youtube.com/watch?v=fSytzGwwBVw (by StatQuest🤸🏿‍♀️)

* 출처4) https://ogrisel.github.io/scikit-learn.org/sklearn-tutorial/tutorial/text_analytics/general_concepts.html#notable-implementations-of-clustering-models

* 출처5) Cross-Validation 개념 설명 https://ogrisel.github.io/scikit-learn.org/sklearn-tutorial/modules/cross_validation.html

* 출처6) CV 해석 블로그 https://woolulu.tistory.com/70

* 출처7) LOO - LPO 차이 https://velog.io/@kkamz/Leave-p-Out-Cross-Validation-Leave-One-Out-Cross-Validation-%EC%9D%B4%EB%9E%80

* 출처6) https://ogrisel.github.io/scikit-learn.org/sklearn-tutorial/tutorial/text_analytics/general_concepts.html#machine-learning-101-general-concepts

댓글