728x90

이번 장에서는 하이퍼파라미터를 머신 러닝을 이용하여 찾을 수 있다는 것이 핵심으로 보인다.

 

검증세트: 하이퍼파라미터 튜닝을 위한 모델 평가 시, test set을 이용하지 않기 위해 훈련세트에서 다시 떼어낸 data set

교차검증: 훈련세트를 여러개의 폴드로 나누고, 하나는 검증세트로 사용하고 나머지는 훈련세트로 사용한다. 교차검증은 이러한 방식으로 검증세트를 바꿔가며 모든 폴드에 대해 검증 점수를 얻어 평균하는 방법

그리드서치: 하이퍼파라미터 탐색을 자동으로 해주는 도구. 탐색할 parameter를 나열하면 교차 검증을 수행하여 가장 좋은 검증 점수의 매개변수 조합을 선택한다.

랜덤서치: 연속된 매개변수 값을 탐색할 때 유용. 탐색 값을 직접 나열하는 것이 아니고 탐색 값을 샘플링할 수 있는 확률 분포 객체를 전달 함. 지정된 횟수만큼 샘플링하여 교차 검증을 수행하기 때문에 시스템 자원이 허락하는 만큼 탐색량을 조절할 수 있다.

 

 

검증 세트

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)

(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

교차 검증

from sklearn.model_selection import cross_validate

scores = cross_validate(dt, train_input, train_target)
print(scores)

{'fit_time': array([0.00867891, 0.00763416, 0.00746775, 0.00764298, 0.00717449]),
'score_time': array([0.00082707, 0.00078511, 0.00080347, 0.00081134, 0.00074959]),
'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

<<< 위와 아래는 같은 내용이다

from sklearn.model_selection import StratifiedKFold

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

0.855300214703487

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

하이퍼파라미터 튜닝

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)

GridSearchCV(estimator=DecisionTreeClassifier(random_state=42),
n_jobs=-1,
param_grid={'min_impurity_decrease': [0.0001, 0.0002, 0.0003, 0.0004, 0.0005]})

 

GridSearch는 상당히 많은 작업량 때문에 시간이 오래 걸린다. n_jobs은 작업에 사용할 CPU 개수이며 -1은 system 최대치
dt = gs.best_estimator_
print(dt.score(train_input, train_target))

0.9615162593804117

print(gs.best_params_)

{'min_impurity_decrease': 0.0001}

print(gs.cv_results_['mean_test_score'])

[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)

GridSearchCV(estimator=DecisionTreeClassifier(random_state=42), n_jobs=-1, param_grid={'max_depth': range(5, 20), 'min_impurity_decrease': array([0.0001, 0.0002, 0.0003, 0.0004, 0.0005, 0.0006, 0.0007, 0.0008, 0.0009]), 'min_samples_split': range(2, 100, 10)})

 np.arange()는 parameter가 0.0001 ~ 0.001까지 0.0001씩 더한 배열 생성

range()도 동일하나 정수만 사용 가능

 

print(gs.best_params_)

{'max_depth': 14, 'min_impurity_decrease': 0.0004, 'min_samples_split': 12}

print(np.max(gs.cv_results_['mean_test_score']))

0.8683865773302731

랜덤 서치

from scipy.stats import uniform, randint
rgen = randint(0, 10)
rgen.rvs(10)
np.unique(rgen.rvs(1000), return_counts=True)

(array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]),
array([102, 87, 91, 105, 122, 91, 109, 90, 87, 116]))

ugen = uniform(0, 1)
ugen.rvs(10)

array([0.09471503, 0.74711048, 0.81052059, 0.30578852, 0.37093519, 0.17989678, 0.96227617, 0.807383 , 0.69161244, 0.62003229])

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)

RandomizedSearchCV(estimator=DecisionTreeClassifier(random_state=42), n_iter=100, n_jobs=-1, param_distributions={'max_depth': <scipy.stats._distn_infrastructure.rv_frozen object at 0x7fdf61082d10>, 'min_impurity_decrease': <scipy.stats._distn_infrastructure.rv_frozen object at 0x7fdf7000f5d0>, 'min_samples_leaf': <scipy.stats._distn_infrastructure.rv_frozen object at 0x7fdf61082a10>, 'min_samples_split': <scipy.stats._distn_infrastructure.rv_frozen object at 0x7fdf61082090>}, random_state=42)

print(gs.best_params_)

{'max_depth': 39, 'min_impurity_decrease': 0.00034102546602601173, 'min_samples_leaf': 7, 'min_samples_split': 13}

print(np.max(gs.cv_results_['mean_test_score']))

0.8695428296438884

dt = gs.best_estimator_

print(dt.score(test_input, test_target))

0.86

 

 

scikit-learn

* cross_validate() : 교차 검증 수행(default 5-폴드)

* GridSearchCV : 교차 검증으로 하이퍼파라미터 탐색을 수행

* RandomizedSearchCV : 교차 검증으로 랜덤한 하이퍼파라미터 탐색을 수행

728x90

+ Recent posts