-
[scikit-learn] KFold 알아보기 ( cross validation )AI-ML 2024. 4. 28. 09:11728x90반응형
- 목차
들어가며.
이번 글에서는 sckit-learn 의 KFold Class 의 사용법에 대해서 알아보려고 합니다.
데이터 학습을 수행하는 경우에 Cross Validation 기법 중의 하나로써 KFold 기법을 수행하곤 합니다.
Training Dataset 을 고정된 비율로 Sub-Training Dataset 과 Sub-Validation Dataset 으로 나누는 방식이죠.
즉, 하나의 데이터셋이 Training Dataset 과 Test Dataset 으로 나뉘고,
이 Training Dataset 은 또다시 Sub-Training Dataset 과 Sub-Validation Dataset 로 나뉩니다.
그림으로 표현하면 아래와 같습니다.
KFold 는 이러한 "Sub Training Dataset * Sub Validation Dataset" 을 정해진 갯수만큼 생성합니다.
만약 KFold 의 n_splits 값이 10 이라면 "Sub Training Dataset * Sub Validation Dataset" 은 10개가 생성되죠.
KFold.
"scikit-learn" 의 KFold 객체를 생성하고 활용해도록 하겠습니다.
from sklearn.model_selection import KFold import pandas as pd rows = [(1, 2, 3, 4) for _ in range(1, 10000 + 1)] columns = ["first", "second", "third", "fourth"] df = pd.DataFrame(rows, columns=columns) kf: KFold = KFold(n_splits=3, shuffle=True) folds = kf.split(df) cur_try = 1 for fold in folds: print(f" try {cur_try}") print(f" train {fold[0][0:10]}") print(f" test {fold[1][0:10]}") cur_try += 1
Pandas DataFrame 의 모습을 아래와 같습니다.
단순하게 first, second, third, fourth 라는 4개의 칼럼을 가지고,
각 칼럼의 값을 동일하고, DataFrame 의 크기는 1만개입니다.
first second third fourth 0 1 2 3 4 1 1 2 3 4 2 1 2 3 4 3 1 2 3 4 4 1 2 3 4 ... ... ... ... ... 9995 1 2 3 4 9996 1 2 3 4 9997 1 2 3 4 9998 1 2 3 4 9999 1 2 3 4 [10000 rows x 4 columns]
그리고 KFold 객채를 생성합니다.
n_splits 는 총 Cross-Validation 을 위한 Training-Validation 데이터셋의 총 갯수입니다.
아래와 같이 n_splits 이 3 인 경우에는 3개의 "Sub Training Dataset * Sub Validation Dataset" 이 생성됩니다.
kf: KFold = KFold(n_splits=3, shuffle=True)
KFold.Split .
KFold 객체는 split 함수를 가집니다.
그리고 split 함수는 yield 키워드를 사용하여 Generator 를 생성하는데요.
Generator 를 사용하기 때문에 n_splits 갯수만큼 메모리를 잡아먹지 않습니다.
그리고 반복문 내부에서 하나의 "Sub Training Dataset * Sub Validation Dataset" 를 통한 학습을 수행할 수 있죠.
shuffle.
아래 코드를 통해서 KFold 객체가 train & test Dataset 이 어떻게 표현하는지 알아보겠습니다.
아래의 결과처럼 KFold 는 Train 과 Test 로 데이터를 분리합니다.
이는 Shuffled 또는 랜덤한 형태이구요.
분리된 각 데이터를 Pandas DataFrame 의 Index 정보를 담습니다.
folds = kf.split(df) cur_try = 1 for fold in folds: print(f" try {cur_try}") print(f" train {fold[0][0:10]}") print(f" test {fold[1][0:10]}") cur_try += 1
try 1 train [ 0 3 4 5 6 7 8 10 12 13] test [ 1 2 9 11 15 19 25 26 29 36] try 2 train [ 0 1 2 3 4 9 10 11 12 13] test [ 5 6 7 8 16 20 21 23 24 27] try 3 train [ 1 2 5 6 7 8 9 11 15 16] test [ 0 3 4 10 12 13 14 17 18 22]
만약 Pandas DataFrame 의 Index 가 변경된다면 어떻게 될까요 ?
아래와 같이 DataFrame 의 index 가 변경됩니다.
그래서 index 의 범위는 0 ~ 9999 가 아닌 10000 ~ 19999 로 변경됩니다.
from sklearn.model_selection import KFold import pandas as pd rows = [(1, 2, 3, 4) for _ in range(1, 10000 + 1)] columns = ["first", "second", "third", "fourth"] df = pd.DataFrame(rows, columns=columns) df.index += 10000 kf: KFold = KFold(n_splits=3, shuffle=True) # folds = kf.split(df) cur_try = 1 for fold in folds: print(f" try {cur_try}") print(f" train {fold[0][0:10]}") print(f" test {fold[1][0:10]}") cur_try += 1
< Pandas DataFrame >
first second third fourth 10000 1 2 3 4 10001 1 2 3 4 10002 1 2 3 4 10003 1 2 3 4 10004 1 2 3 4 ... ... ... ... 19995 1 2 3 4 19996 1 2 3 4 19997 1 2 3 4 19998 1 2 3 4 19999 1 2 3 4 [10000 rows x 4 columns]
하지만 KFold 에 의해서 출력되는 결과는 0 ~ 9999 범위의 Index 를 가집니다.
따라서 Pandas 의 DataFrame Index 가 아닌 실질적인 배열의 Index 값을 가진다는 점에 주의해야합니다.
try 1 train [ 0 2 3 4 8 9 13 14 16 17] test [ 1 5 6 7 10 11 12 15 22 23] try 2 train [ 1 5 6 7 8 9 10 11 12 13] test [ 0 2 3 4 17 18 19 21 28 29] try 3 train [ 0 1 2 3 4 5 6 7 10 11] test [ 8 9 13 14 16 20 24 25 27 34]
반응형'AI-ML' 카테고리의 다른 글
[scikit-surprise] SVD Model 알아보기 ( Singular Value Decomposition ) (0) 2024.05.07 [seaborn] Count Plot 그리기 ( sns.countplot, sns.catplot ) (0) 2024.05.06 [torchvision] datasets.MNIST 데이터 내려받기 (0) 2024.04.24 [torchvision] RGB to Grayscale Image (0) 2024.03.31 [scikit-learn] LabelEncoder 알아보기 (0) 2024.03.29