ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [scikit-learn] KFold 알아보기 ( cross validation )
    AI-ML 2024. 4. 28. 09:11
    728x90
    반응형

     

    - 목차

     

    들어가며.

    이번 글에서는 sckit-learn 의 KFold Class 의 사용법에 대해서 알아보려고 합니다.

    데이터 학습을 수행하는 경우에 Cross Validation 기법 중의 하나로써 KFold 기법을 수행하곤 합니다.

     

    출처 : https://scikit-learn.org/stable/modules/cross_validation.html

     

    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]

     

    반응형
Designed by Tistory.