교차검증(Kfold)이란?

2024. 12. 5. 01:15·AI/Machine Learing
728x90
반응형

교차 검증 이란?

  • 과적합 : 모델이 학습 데이터에마 과도하게 최적화된 현상. 그로인해 일반화된 데이터에서는 예측 성능이 과하게 떨어지는 현상
  • 지난번 와인 맛 평가에서 훈련용 데이터의 Acc는 72.94, 테스트용 데이터는 Acc가 71.61%였는데, 누가 이결과가 정말 괜찮은 것인지 묻는다면?
  • 나에게 주어진 데이터에 적용한 모델의 성능을 정확히 표현하기 위해서도 유용하다
  • train 데이터를 다시 나누어 validation 데이터로 사용함으로써 과적합을 막는 방법
  • 검증이 끝나면 다시 train데이터로 학습 한 뒤 test로 마지막 결과를 확인한다

교차 검증 구현하기

Simple Example

import numpy as np
from sklearn.model_selection import KFold

X = np.array([[1, 2], [3, 4], [1, 2], [3, 4]])
y = np.array([1, 2, 3, 4])
kf = KFold(n_splits=2)

print(kf.get_n_splits(X))
print(kf)
for train_idx, test_idx in kf.split(X):
    print('-----idx')
    print(train_idx, test_idx)
    print('-----train data')
    print(X[train_idx])
    print('-----test data')
    print(X[test_idx])
2
KFold(n_splits=2, random_state=None, shuffle=False)
-----idx
[2 3] [0 1]
-----train data
[[1 2]
 [3 4]]
-----test data
[[1 2]
 [3 4]]
-----idx
[0 1] [2 3]
-----train data
[[1 2]
 [3 4]]
-----test data
[[1 2]
 [3 4]]
  • Kfold는 sklearn에 포함되어 있음.

와인 데이터

와인맛 분류

import pandas as pd


red_wine = pd.read_csv(red_url, sep = ';')
white_wine = pd.read_csv(white_url, sep = ';')

red_wine['color'] = 1
white_wine['color'] = 0

wine = pd.concat([red_wine, white_wine])

데이터 정리

wine['taste'] = [1. if grade > 5 else 0. for grade in wine['quality']]

X = wine.drop(['taste', 'quality'], axis = 1)
y = wine['taste']

의사결정 나무

from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score

X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=13)

wine_tree = DecisionTreeClassifier(max_depth=2, random_state=13)
wine_tree.fit(X_train, y_train)

y_pred_tr = wine_tree.predict(X_train)
y_pred_test = wine_tree.predict(X_test)

print('Train Acc : ', accuracy_score(y_train, y_pred_tr))
print('Test Acc : ', accuracy_score(y_test, y_pred_test))
Train Acc :  0.7294593034442948
Test Acc :  0.7161538461538461
  • Kfold를 진행하지 않고 바로 train으로 데이터를 학습 한뒤 결과를 도출해냄
  • 데이터를 train_test_split으로 랜덤하게 분리하는게 맞는것인지? 혹은 이것이 최선인건가?
  • 또한, 저 acc는 신뢰할수 있는지에 대한 검증이 필요함

KFold

from sklearn.model_selection import KFold

kfold = KFold(n_splits=5)
wine_tree_cv = DecisionTreeClassifier(max_depth=2, random_state=13)
  • Kfold를 만들고, 분류기도 다시 생성
  • cv = cross validation의 약자

Index 반환

for train_idx, test_idx in kfold.split(X):
    print(len(train_idx), len(test_idx))
5197 1300
5197 1300
5198 1299
5198 1299
5198 1299

Fold Acc

cv_accuracy = []
for train_idx, test_idx in kfold.split(X):
    X_train, X_test = X.iloc[train_idx], X.iloc[test_idx]
    y_train, y_test = y.iloc[train_idx], y.iloc[test_idx]
    wine_tree_cv.fit(X_train, y_train)
    pred = wine_tree_cv.predict(X_test)
    cv_accuracy.append(accuracy_score(y_test, pred))

cv_accuracy
[0.6007692307692307,
 0.6884615384615385,
 0.7090069284064665,
 0.7628945342571208,
 0.7867590454195535]
np.mean(cv_accuracy)
0.709578255462782

StratifiedKFold

from sklearn.model_selection import StratifiedKFold

skfold = StratifiedKFold(n_splits= 5)
wine_tree_cv = DecisionTreeClassifier(max_depth=2, random_state=13)

cv_accuracy = []

for train_idx, test_idx in skfold.split(X, y):
    X_train, X_test = X.iloc[train_idx], X.iloc[test_idx]
    y_train, y_test = y.iloc[train_idx], y.iloc[test_idx]
    wine_tree_cv.fit(X_train, y_train)
    pred = wine_tree_cv.predict(X_test)
    cv_accuracy.append(accuracy_score(y_test, pred))

cv_accuracy
[0.5523076923076923,
 0.6884615384615385,
 0.7143956889915319,
 0.7321016166281755,
 0.7567359507313318]

Acc 평균이 안좋음

np.mean(cv_accuracy)
0.6888004974240539
  • 인덱스를 반환하기 때문에 for문으로 각각 데이터를 validation하였다.
  • 하지만 이렇게 불편하게 코드를 하나하나 짜가면서 해야하는것일까?

2.11 cross validation을 보다 더 간편하게

Cross Validation을 더 간편하게(w. Scikit Learn)

from sklearn.model_selection import cross_val_score

skfold = StratifiedKFold(n_splits=5)
wine_tree_cv = DecisionTreeClassifier(max_depth=2, random_state=13)

cross_val_score(wine_tree_cv, X, y , scoring=None, cv=skfold)
array([0.55230769, 0.68846154, 0.71439569, 0.73210162, 0.75673595])
  • 위의 예제처럼 for문 코드를 짜서 돌리는것이 아닌 이미 Sklean에 cross_val_score로 한다
  • sklearn에 cross_val_score에 분류기, X, y, Fold객체를 넣어주면된다
  • skfold의 n_splits = 5는 데이터를 5개로 나누어 validation한다는 뜻

Depth가 높다고 정확도가 높지 않음

from sklearn.model_selection import cross_val_score

skfold = StratifiedKFold(n_splits=5)
wine_tree_cv = DecisionTreeClassifier(max_depth=5, random_state=13)

cross_val_score(wine_tree_cv, X, y, scoring=None, cv=skfold)
array([0.50076923, 0.62615385, 0.69745958, 0.7582756 , 0.74903772])
  • 의사결정 나무의 max_depth를 늘려서 accuracy를 보았으나, 무조건 높아지는것도 아님을 확인

Train Score

from sklearn.model_selection import cross_validate
cross_validate(wine_tree_cv, X, y, scoring=None, cv=skfold, return_train_score= True)
{'fit_time': array([0.01485896, 0.01390481, 0.01378489, 0.01321983, 0.0129869 ]),
 'score_time': array([0.00206208, 0.00191903, 0.00187325, 0.00179911, 0.00170922]),
 'test_score': array([0.50076923, 0.62615385, 0.69745958, 0.7582756 , 0.74903772]),
 'train_score': array([0.78795459, 0.78045026, 0.77568295, 0.76356291, 0.76279338])}
  • cross_validate의 return_train_score를 쓰면됨
  • train과 test의 격차를 보니 과적합이 있는듯 하다.
728x90
반응형

'AI > Machine Learing' 카테고리의 다른 글

PCA, t-SNE, LDA으로 알아보는 차원 축소  (0) 2024.11.17
'AI/Machine Learing' 카테고리의 다른 글
  • PCA, t-SNE, LDA으로 알아보는 차원 축소
Data Include Me
Data Include Me
AI, LLM, 머신러닝, 파이썬 등 최신 정보와 튜토리얼을 제공하는 데이터 사이언스 전문 블로그입니다.
  • Data Include Me
    Data Include Me
    Data Include Me
  • 전체
    오늘
    어제
    • 전체 (35)
      • AI (16)
        • Machine Learing (2)
        • Deep Learning (0)
        • Natural Language Processing (4)
        • Large Language Model (7)
        • Computer Vision (3)
      • Data Science (10)
        • Data Analysis (1)
        • Statistics & Math (3)
        • Data Engineering (6)
        • Data Visualization (0)
      • Programming Challenges (2)
        • Baekjoon (0)
        • Programmers (2)
        • HackerRank (0)
      • Development (7)
        • Cloud & DevOps (5)
        • Project (2)
  • 인기 글

  • 태그

    LangChain
    Crawling
    integral
    티스토리챌린지
    Python
    llm
    오블완
    sympy
    mcp
    Cloud Computing
  • 링크

    • Github
    • Linkedin
  • 반응형
  • hELLO· Designed By정상우.v4.10.1
Data Include Me
교차검증(Kfold)이란?
상단으로

티스토리툴바