혼자 공부하는 머신러닝+딥러닝 책을 바탕으로 공부한 내용입니다.
CH5 트리 알고리즘 ②
최적의 모델을 위한 하이퍼파라미터 탐색
검증 세트, 교차 검증에 대해 배우기
그리드 서치와 랜덤 서치를 이용해 최적의 성능을 내는 하이퍼파라미터를 찾아보자
▶ 검증 세트
- 검증세트는 하이퍼파라미터 튜닝을 위해 모델을 평가할 때, test set을 사용하지 않기 위해 train set에서 다시 떼어 낸 data set이다.
test set으로 일반화 성능을 올바르게 예측하려면 가능한 한 test set을 사용하지 않아야 한다.
test set을 사용하지 않고 모델이 과대적합인지 과소적합인지 판단하기 위해 검증 세트를 이용하자
- train set에서 모델을 훈련하고 검증 세트로 모델 평가
- 테스트하고 싶은 매개변수를 바꿔가며 가장 좋은 모델 찾기
- 이 매개변수를 사용해 train set, 검증 세트를 합쳐 전체 훈련 데이터에서 모델을 다시 훈련
- 마지막으로 test set에서 최종 점수 평가
데이터를 불러와 직접 실습해보자
import pandas as pd
wine = pd.read_csv("https://bit.ly/wine_csv_data")
wine.head()
train_test_split() 함수를 2번 적용해 훈련 세트와 검증 세트로 나눠주고 크기를 확인해보자
# train set, test set으로 나누기
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)
# 검증 set 만들기
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)
- 5,197개였던 훈련 세트가 4,147개가 되고, 검증 세트는 1,040개가 된 것이 확인된다.
이제 결정 트리 모델을 만들고 평가해보자
# 결정 트리 모델
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))
- train set에 과대적합되어 있는 것으로 확인되므로 매개변수를 바꿔 더 좋은 모델을 찾아야 한다.
▶ 교차 검증
- 훈련 세트를 여러 폴드로 나눈 다음 한 폴드가 검증 세트의 역할을 하고 나머지 폴드에서는 모델을 훈련
- 교차 검증은 이런 식으로 모든 폴드에 대해 검증 점수를 얻어 평균하는 방법
사이킷런에는 cross_validate()라는 교차 검증 함수가 있다.
직접 검증 세트를 떼어 내지 않고 train set 전체를 이 함수에 전달해보자
# 교차 검증 함수 사용
from sklearn.model_selection import cross_validate
scores = cross_validate(dt, train_input, train_target)
print(scores)
- 처음 2개의 키는 모델을 훈련하는 시간, 검증하는 시간을 의미
- 교차 검증의 최종 점수는 test_score 키에 담긴 5개의 점수를 평균하여 얻음
# 교차 검증의 점수
import numpy as np
print(np.mean(scores['test_score'])) #0.855300214703487
cross_validate()는 훈련 세트를 섞어 폴드를 나누지 않으므로
교차 검증을 할 때 훈련 세트를 섞으려면 분할기를 지정해야 한다.
- 회귀 모델일 경우 - KFold 분할기 사용
- 분류 모델인 경우 - StratifiedKFole 사용
위에서 수행했던 교차 검증은 다음 코드와 동일하다
# 위와 같은 식
from sklearn.model_selection import StratifiedKFold
scores = cross_validate(dt, train_input, train_target, cv=StratifiedKFold())
print(np.mean(scores['test_score'])) #0.855300214703487
# 10-폴드 교차 검증 수행
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
- n_splits 매개변수는 몇(k) 폴드 교차 검증을 할지 정한다.
- 우리는 10-폴드 교차 검증을 수행해보았다.
이제 결정 트리의 매개변수 값을 바꿔가며 가장 좋은 성능이 나오는 모델을 찾아보자
이때, test set을 사용하지 않고 교차 검증을 통해 좋은 모델을 고를 것이다.
▶ 하이퍼파라미터 튜닝
- 모델 파라미터 - 머신러닝 모델이 학습하는 파라미터
- 하이퍼파라미터 - 모델이 학습할 수 없어서 사용자가 지정해야 하는 파라미터
- 그리드 서치
- 하이퍼파라미터 탐색을 자동화 해주는 도구
- 탐색할 매개변수를 나열하면 교차 검증을 수행하여 가장 좋은 검증 점수의 매개변수 조합을 선택
- 이 매개변수의 조합으로 최종 모델 훈련
- 별도로 cross_validate() 함수를 호출할 필요가 없음
사이킷런의 그리드 서치를 어떻게 사용하는지 간단한 예로 확인해보자
# 예시 - min_impurity_decrease 매개변수의 최적값 찾아보기
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의 cv 매개변수 기본값은 5이므로 여기서는 5*5 = 25개의 모델을 훈련함
- n_jobs=-1로 지정하면 시스템에 있는 모든 코어를 사용한다.
사이킷런의 그리드 서치는 훈련이 끝나면 25개의 모델 중 검증 점수가
가장 높은 모델의 매개변수 조합으로 전체 훈련 세트에서 자동으로 모델을 다시 훈련한다.
( 이 모델은 gs 객체의 best_estimator_ 속성에 저장 되어 있음 )
dt = gs.best_estimator_
print(dt.score(train_input, train_target))
# 최적의 매개변수
print(gs.best_params_)
- best_params_로 최적의 매개변수 찾기
- 0.0001이 가장 좋은 값으로 선택되었다.
# 교차 검증의 평균 점수
print(gs.cv_results_['mean_test_score'])
# 가장 큰 값의 인덱스 추출
best_index = np.argmax(gs.cv_results_['mean_test_score'])
print(gs.cv_results_['params'][best_index])
- 교차 검증 점수와 가장 큰 값의 인덱스를 다음과 같이 구할 수 있다.
- 넘파이 argmax() 함수를 사용하여 가장 큰 값의 인덱스 추출
결정 트리에서 min_impurity_decrease는 노드를 분할하기 위한 불순도 감소 최소량을 지정한다.
이번에는 이것과 더불어 max_depth, min_samples_split로 노드를 나누기 위한 최소 샘플 수도 골라보자
# 조금 더 복잡한 매개변수 조합 탐색
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']))
- 매개변수로 수행할 교차 검증 횟수는 9*15*10 = 1350개이다.
- 기본 5-폴드 교차 검증을 수행하므로 만들어지는 모델의 수는 6750개
GridSearchCV 클래스를 사용하면 일일이 바꿔가며 교차 검증을 수행하지 않고
원하는 매개변수 값을 나열하면 자동으로 교차 검증을 수행해 최상의 매개변수를 찾을 수 있다.
▶ 랜덤 서치
이번에는 랜덤 서치를 사용해 매개변수 값의 목록을 전달하는 것이 아닌
매개변수를 샘플링할 수 있는 확률 분포 객체를 전달해보자
[ randint, uniform 사용 예시 ]
from scipy.stats import uniform, randint
# randint 객체에서 10개 숫자 샘플링
rgen = randint(0, 10)
rgen.rvs(10) #array([6, 5, 2, 1, 5, 1, 6, 2, 4, 8])
np.unique(rgen.rvs(1000), return_counts=True)
# uniform 클래스 사용법도 동일
ugen = uniform(0, 1)
ugen.rvs(10)
- randint, uniform 클래스는 균등 분포에서 샘플링을 한다.
- randint는 정숫값을 뽑고 uniform은 실숫값을 뽑는다.
앞에서는 직접 매개변수 값의 목록을 지정했었는데 이번에는 랜덤 서치를 사용해보자
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)
- min_samples_leaf 매개변수는 리프 노드가 되기 위한 최소 샘플의 개수
- n_iter 매개변수는 샘플링의 횟수로 총 100번 샘플링하도록 지정하였다.
이제 최적의 매개변수 조합과 교차 검증 점수를 출력해보자
# 최적의 매개변수 조합 출력
print(gs.best_params_)
# 최고의 교차 검증 점수 출력
print(np.max(gs.cv_results_['mean_test_score']))
최적의 모델은 이미 전체 train set으로 훈련되어 best_estimator_ 속성에 저장되어 있다.
이 모델을 최종 모델로 결정하고 test set의 성능을 확인해보자
dt = gs.best_estimator_
print(dt.score(test_input, test_target)) #0.86
▶ 정리
- 교차 검증을 사용해 다양한 하이퍼파라미터를 탐색
- 테스트하고 싶은 매개변수 리스트를 만들어 이 과정을 자동화하는 그리드 서치를 사용하면 편리함
- 랜덤 서치는 연속된 매개변수 값을 탐색할 때 유용
- 탐색 값을 샘플링 할 수 있는 확률 분포 객체를 전달
'Python > ML & DL 공부' 카테고리의 다른 글
[ML] 06-1 군집 알고리즘 (0) | 2022.03.12 |
---|---|
[ML] 05-3 트리의 앙상블 (0) | 2022.03.11 |
[ML] 05-1 결정 트리 (0) | 2022.03.11 |
[ML] 04-2 확률적 경사 하강법 (0) | 2022.03.10 |
[ML] 04-1 로지스틱 회귀 (0) | 2022.03.07 |