머신러닝 모델을 평가할 때 일반적으로 데이터를 훈련(training)과 테스트(test) 세트로 나누는 방식이 사용됩니다.
하지만 이렇게 하면 데이터의 일부만 학습에 사용되기 때문에 모델이 데이터 분할에 따라 성능이 달라질 수 있습니다.
또, 테스트 셋이 하나이기 때문에 정해진 테스트 셋에 모델이 오버피팅 될 가능성도 존재하죠.
데이터 하나 하나가 귀할 때 테스트 셋은 모델의 훈련에 쓰일 수 없다는 점도 아쉬운 부분입니다.

이번 포스팅에서는 이러한 문제들을 해결할 수 있는 방법인 K겹 교차 검증(K-Fold Cross Validation)에 대해 알아보도록 하겠습니다.
K-Fold Cross Validation이란?
K-Fold Cross Validation은 데이터를 K개의 폴드(fold)로 나누어 모델을 여러 번 학습 및 평가하는 방법입니다.
전체 프로세스는 다음과 같습니다.
- 데이터를 K개의 동일한 크기의 부분집합(fold)으로 분할합니다.
- K번 반복하면서, 각 반복에서 한 개의 폴드를 검증 데이터로 사용하고 나머지 K-1개의 폴드를 학습 데이터로 사용하여 모델을 훈련합니다.
- 각 폴드에서 얻은 성능을 평균 내어 최종 모델의 성능을 평가합니다.

이 방법은 데이터의 모든 부분을 학습과 검증에 골고루 활용할 수 있어 모델의 일반화 성능을 높이는 데 도움이 됩니다.
K-Fold 교차 검증의 장점
- 데이터 활용 극대화: 모든 샘플이 학습과 검증에 모두 사용되므로 데이터 손실이 없습니다.
- 일반화 성능 향상: 단순한 홀드아웃(hold-out) 방식보다 모델의 성능을 안정적으로 평가할 수 있습니다.
- 과적합 방지: 특정 데이터 분할에 의존적인 모델이 되는 것을 방지합니다.
K-Fold 교차 검증 구현
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Input
from sklearn.model_selection import KFold
import pandas as pd
# 깃허브에 준비된 데이터를 가져옵니다.
!git clone https://github.com/taehojo/data.git
# 광물 데이터를 불러옵니다.
df = pd.read_csv('./data/sonar3.csv', header=None)
# 음파 관련 속성을 X로, 광물의 종류를 y로 저장합니다.
X = df.iloc[:,0:60]
y = df.iloc[:,60]
# 몇 겹으로 나눌 것인지를 정합니다.
k=5
# KFold 함수를 불러옵니다. 분할하기 전에 샘플이 치우치지 않도록 섞어 줍니다.
kfold = KFold(n_splits=k, shuffle=True)
# 정확도가 채워질 빈 리스트를 준비합니다.
acc_score = []
def model_fn():
model = Sequential() # 딥러닝 모델의 구조를 시작합니다.
model.add(Dense(24, input_dim=60, activation='relu'))
model.add(Dense(10, activation='relu'))
model.add(Dense(1, activation='sigmoid'))
return model
# K겹 교차 검증을 이용해 k번의 학습을 실행합니다.
for train_index , test_index in kfold.split(X): # for 문에 의해서 k번 반복합니다. spilt()에 의해 k개의 학습셋, 테스트셋으로 분리됩니다.
X_train, X_test = X.iloc[train_index,:], X.iloc[test_index,:]
y_train, y_test = y.iloc[train_index], y.iloc[test_index]
model = model_fn()
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
history=model.fit(X_train, y_train, epochs=200, batch_size=10, verbose=0)
accuracy = model.evaluate(X_test, y_test)[1] # 정확도를 구합니다.
acc_score.append(accuracy) # 정확도 리스트에 저장합니다.
# k번 실시된 정확도의 평균을 구합니다.
avg_acc_score = sum(acc_score)/k
# 결과를 출력합니다.
print('정확도:', acc_score)
print('정확도 평균:', avg_acc_score)

fold간 정확도 차이가 매우 크네요.
이런 상황에서 홀드아웃 방식을 사용했다면 올바른 정확도를 도출할 수 없었을 것 같습니다.
'Study > AI' 카테고리의 다른 글
[AI] 전이학습(Transfer Learning)에 대하여 (0) | 2025.03.05 |
---|---|
[AI] 딥러닝 개발을 위한 CPU, GPU, 메모리 이해하기 (3) | 2025.02.07 |
[AI] ReLU vs Leaky ReLU (0) | 2025.02.07 |
[AI] 배치 정규화(Batch Normalization)란? (0) | 2025.02.07 |