이번 장에서는 하이퍼파라미터를 머신 러닝을 이용하여 찾을 수 있다는 것이 핵심으로 보인다.
검증세트: 하이퍼파라미터 튜닝을 위한 모델 평가 시, 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 : 교차 검증으로 랜덤한 하이퍼파라미터 탐색을 수행
'Programming > Machine Learning' 카테고리의 다른 글
[혼공머신] 06-3 주성분 분석 (0) | 2022.03.27 |
---|---|
[혼공머신] 용어 04장 (0) | 2022.02.28 |
[혼공머신] 06-2 k-평균 (0) | 2022.02.20 |
[혼공머신] 06-1 군집 알고리즘(비지도학습) (0) | 2022.02.19 |
[혼공머신] 05-3 트리의 앙상블 (0) | 2022.02.13 |
[혼공머신] 05-1 결정트리 (0) | 2022.02.06 |
[혼공머신] 04-2 확률적 경사 하강법 (0) | 2022.02.05 |
[혼공머신] 용어 03장 (0) | 2022.02.03 |
[혼공머신] 04-1 로지스틱 회귀 (0) | 2022.01.23 |
[혼공머신] 03-3 특성공학과 규제 (0) | 2022.01.22 |