알파카징징이 알파카징징이 코딩하는 알파카

혼공머_5_2 교차 검증과 그리드 서치

» writing

혼자공부하는머신러닝+딥러닝 수업을 참고하여 작성하였습니다

5_2_교차 검증과 그리드 서치

정의


교차 검증과 그리드 서치

1. 검증세트
   : 테스트 세트를 사용하지 않고 이를 측정하는 방법
   : 훈련세트를 또 나누기
   : 전체 데이터 = 훈련 60 + 검증 20 + 테스트 20
import pandas as pd
wine = pd.read_csv('https://bit.ly/wine-date')

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)
# test_size -> test의 사이즈 (20%)

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)
# (4157, 3) (1040, 3)

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))
# 0.9971133028626413
# 0.864423076923077
2. 교차검증
    : 검증 세트를 떼어 내어 평가하는 과정을 여러번 반복
    : 이 점수를 평균하여 최종 검증 점수 얻기
    * k-폴드 교차 검증
        : k 부분으로 나누어서 교차 검증 수행
from sklearn.model_selection import cross_validate
scores = cross_validate(dt, train_input, train_target)
# cross_validate : 먼저 평가할 모델 객체를 첫번째
# 매개변수로 전달, 앞에서처럼 직접 검증 세트 떼어내지 않고
# 훈련 세트 전체를 cross_validate 에 전달
print(scores)
# {'fit_time': array([0.00818205, 0.00707316, 0.00745201, 0.00763822, 0.00757003]), 'score_time': array([0.00083613, 0.00069308, 0.00074124, 0.00078893, 0.00074649]), 'test_score': array([0.86923077, 0.84615385, 0.87680462, 0.84889317, 0.83541867])}
import numpy as np
print(np.mean(scores['test_score']))
# 0.855300214703487
3. 분할기(splitter)를 사용한 교차검증
    : cross_validate는 회귀모델 경우 KFold 분할기
    : 분류모델 경우 타깃클래스를 골고루 나누는 StratifiedKFold 사용
from sklearn.model_selection import StratifiedKFold

# 1 StratifiedKFold
scores = cross_validate(dt, train_input, train_target, cv = StratifiedKFold())
print(np.mean(scores['test_score']))
# 0.855300214703487

# 2 splitter
splitter = StratifiedKFold(n_splits = 10, shuffle = True, random_state = 42)
scores = cross_validate(dt, train_input, train_target, cv = splitter)
print(np.mean(scores['test_score']))
# 0.8574181117533719
4. 그리드 서치
    : 하이퍼파라미터 탐색과 교차 검증 한번에 수행
    * 하이퍼파라미터
        : 사용자 지정 파라미터 
    1) 먼저 탐색할 매개변수 지정
    2) 훈련세트에서 그리드 서치 수행, 최상의 평균 검증점수가
    나오는 매개변수 조합 찾기 (이 조합은 그리드 서치 객체에 저장)
    3) 그리드 서치는 최상의 매개변수에서 전체 훈련세트를
    사용해 최종 모델 훈련 (그리드 서치 객체에 저장)
    * 매개변수
        - min_impurity_decrease : 노드 분할하기 위한
                                불순도 감소 최소량 지정 
        - max_depth : 트리의 깊이 제한
        - min_sample_split : 노드 나누기 위한 최소샘플수 고르기
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))
# 0.9615162593804117

print(gs.best_params_)
print(gs.cv_results_['mean_test_score'])
# {'min_impurity_decrease': 0.0001}
# [0.86819297 0.86453617 0.86492226 0.86780891 0.86761605]

#best_index = np.argmax(gs.cv_results_['mean_test_score'])
print(gs.cv_results_['params'][best_index])
# {'min_impurity_decrease': 0.0001}
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']))
# {'max_depth': 14, 'min_impurity_decrease': 0.0004, 'min_samples_split': 12}
# 0.8683865773302731

# 최상의 교차 검증 점수
print(np.max(gs.cv_results_['mean_test_score']))
# 0.8683865773302731
5. 랜덤 서치
    : 매개변수 값의 목록을 전달x
    : 매개변수를 샘플링할 수 있는 확률 분포 객체 전달
    - randint : 정수값 뽑기
    - uniform : 실수값 뽑기
        -> 균등분포에서 샘플링한다
from scipy.stats import uniform, randint

rgen = randint(0,10)
rgen.rvs(10)
# array([3, 6, 4, 8, 6, 0, 6, 7, 5, 1])

np.unique(rgen.rvs(1000), return_counts = True)
# (array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]),
#  array([107, 104, 106, 107,  97,  82, 110,  89,  96, 102]))
ugen = uniform(0,1)
ugen.rvs(10)
# array([0.3409424 , 0.39960849, 0.38990399, 0.10233974, 0.19886937,
#        0.77002928, 0.40426844, 0.87554215, 0.19462306, 0.28794574])
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),
          }

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

print(gs.best_params_)
print(np.max(gs.cv_results_['mean_test_score']))
# {'max_depth': 39, 'min_impurity_decrease': 0.00034102546602601173, 'min_samples_leaf': 7, 'min_samples_split': 13}
# 0.8695428296438884

dt = gs.best_estimator_
print(dt.score(test_input, test_target))
# 0.86
6. 최적의 모델을 위한 하이퍼파라미터 탐색
    1) GridSearchCV : 교차검증으로 하이퍼파라미터 탐색
            최상 모델 찾은후 훈련세트 전체 사용해 최종모델 훈련 
    2) RandomizedSearchCV : 교차검증으로 랜덤한 하이퍼파라미터 탐색
            최상 모델 찾은후 훈련세트 전체 사용해 최종모델 훈련