Spring

📘 2025년 3월 16일 교차 검증과 그리드 서치(Grid Search)로 최적의 모델 찾기

upwardtrend 2025. 3. 16. 23:43

 

안녕하세요! 오늘은 머신러닝 모델의 성능을 높이기 위해 꼭 알아야 하는 **교차 검증(cross-validation)**과 **하이퍼파라미터 튜닝(그리드 서치, 랜덤 서치)**에 대해 공부했어요. 그 과정과 코드를 이해하기 쉽게 블로그로 정리해볼게요.


🍷 데이터 준비하기

import pandas as pd
wine = pd.read_csv('https://bit.ly/wine_csv_data')

# 데이터와 타깃 분리
data = wine[['alcohol', 'sugar', 'pH']].to_numpy()
target = wine['class'].to_numpy()

📊 훈련/검증/테스트 세트 나누기

from sklearn.model_selection import train_test_split
train_input, test_input, train_target, test_target = train_test_split(
    data, target, test_size=0.2, random_state=42)

sub_input, val_input, sub_target, val_target = train_test_split(
    train_input, train_target, test_size=0.2, random_state=42)

print(sub_input.shape, val_input.shape)

🌳 결정 트리로 기본 모델 훈련하기

from sklearn.tree import DecisionTreeClassifier
dt = DecisionTreeClassifier(random_state=42)
dt.fit(sub_input, sub_target)

print('훈련 세트 점수:', dt.score(sub_input, sub_target))
print('검증 세트 점수:', dt.score(val_input, val_target))

🔄 교차 검증 (Cross-validation)

기본 교차 검증

from sklearn.model_selection import cross_validate
scores = cross_validate(dt, train_input, train_target)
print('기본 교차 검증 평균 점수:', scores['test_score'].mean())

계층적(Stratified) 교차 검증

from sklearn.model_selection import StratifiedKFold
scores = cross_validate(dt, train_input, train_target, cv=StratifiedKFold())
print('계층적 교차 검증 평균 점수:', scores['test_score'].mean())

교차 검증 셔플 적용

splitter = StratifiedKFold(n_splits=10, shuffle=True, random_state=42)
scores = cross_validate(dt, train_input, train_target, cv=splitter)
print('셔플 적용 교차 검증 평균 점수:', scores['test_score'].mean())

🛠️ 하이퍼파라미터 튜닝 (GridSearchCV)

from sklearn.model_selection import GridSearchCV

params = {'min_impurity_decrease': [0.0001, 0.0002, 0.0003, 0.0004, 0.0005]}

gs = GridSearchCV(DecisionTreeClassifier(random_state=42), params, n_jobs=-1)
gs.fit(train_input, train_target)

# 최적의 모델 평가
dt = gs.best_estimator_
print('훈련 세트 점수:', dt.score(train_input, train_target))
print('최적 하이퍼파라미터:', gs.best_params_)

🔬 더 자세한 하이퍼파라미터 튜닝

import numpy as np

params = {'min_impurity_decrease': np.arange(0.0001, 0.001, 0.0001),
          'max_depth': range(5, 20, 1),
          'min_samples_split': range(2, 100, 10)}

gs = GridSearchCV(DecisionTreeClassifier(random_state=42), params, n_jobs=-1)
gs.fit(train_input, train_target)

print('최적 하이퍼파라미터:', gs.best_params_)
print('최고 교차 검증 점수:', np.max(gs.cv_results_['mean_test_score']))

dt = gs.best_estimator_
print('테스트 세트 점수:', dt.score(test_input, test_target))

🎲 랜덤 서치(RandomizedSearchCV)로 효율적 튜닝

from scipy.stats import uniform, randint
from sklearn.model_selection import RandomizedSearchCV

params = {'min_impurity_decrease': uniform(0.0001, 0.001),
          'max_depth': randint(20, 50),
          'min_samples_split': randint(2, 25),
          'min_samples_leaf': randint(1, 25)}

gs = RandomizedSearchCV(DecisionTreeClassifier(random_state=42), params, n_iter=100, n_jobs=-1)
gs.fit(train_input, train_target)

print('최적 하이퍼파라미터:', gs.best_params_)
print('최고 교차 검증 점수:', np.max(gs.cv_results_['mean_test_score']))

dt = gs.best_estimator_
print('테스트 세트 점수:', dt.score(test_input, test_target))

📝 오늘의 핵심 정리

  • 교차 검증: 데이터를 여러 부분으로 나눠 다양한 상황에서 모델 성능을 검증하는 방법이에요.
  • 그리드 서치(Grid Search): 정해진 범위 내에서 모든 가능한 조합을 탐색해 최고의 하이퍼파라미터를 찾아요.
  • 랜덤 서치(Randomized Search): 무작위로 하이퍼파라미터를 설정하여 효율적으로 최적의 값을 찾는 방법이에요.

다음번엔 이 방법들을 더 다양한 데이터셋에서 활용해볼 예정이에요. 그럼 모두 공부 화이팅!