혼공단/혼공단 5기

혼자 공부하는 머신러닝 + 딥러닝 5장 - 교차 검증과 그리드 서치

하양훈 2021. 2. 18. 22:09
반응형

1. 교차 검증

 

<검증 세트>

- 테스트 세트를 사용하지 않고 모델이 과대적합인지, 과소적합인지 판단하는 방법.

- 보통 전체 데이터중 20%를 테스트 세트로 80%를 훈련세트로 만든 뒤, 이 훈련 세트중 20%를 다시 떼어내서 검증세트로 만든다.

- 많은 데이터를 훈련할수록 좋은 모델이 생기지만, 검증 세트를 너무 적게 때면 검증 점수가 들쭉 날쭉해질 것이다..

 

<교차검증>

 

- 검증 세트를 떼어내는 과정을 여러번 반복 하는 것.

3-폴드 교차 검증

- 사이킷런에는 cross_validate라는 교차 검증 함수가 있다.

- 평가할 모델 객체를 첫번째 매개변수로 넣고, 두번째 매개변수로는 훈련세트 전체를 집어 넣는다.

 

 

from sklearn.model_selection import cross_validate

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

>>{'fit_time': array([0.00725031, 0.00697041, 0.00710249, 0.00712824, 0.00681305]), 'score_time': array([0.00077963, 0.00055647, 0.0005784 , 0.00052595, 0.00059152]), 'test_score': array([0.86923077, 0.84615385, 0.87680462, 0.84889317, 0.83541867])}

 

- fit_time(모델 훈련 시간), score_time(검증 시간),test_score(검증 폴드의 점수 != 테스트 점수)를 반환한다.

- cross_validate()는 기본적으로 5-폴드 교차 검증을 수행하며, cv매개변수에서 폴드 수를 바꿀 수도 있다.

-  cross_validate()는 훈련 세트를 섞어 폴드를 나누지 않는다 => 훈련 세트를 섞으려면 분할기(splitter) 필요

 

<분할기>

 

- 교차 검증에서 폴드를 어떻게 나눌지 결정해준다.

- 기본적으로 회귀모델에서는 KFold분할기를, 분류모델일 경우에는 StratifiedKFold를 사용한다. 

 

from sklearn.model_selection import StratifiedKFold

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

#n_splits : 폴드의 수
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']))

 

 

2. 하이퍼파라미터 튜닝

 

[하이퍼파라미터를 튜닝하는 과정]

1) 라이브러리가 제공하는 기본값을 그대로 사용해 모델을 훈련

2) 검증세트의 점수나 교차 검증을 통해서 매개변수를 조금씩 바꿔본다.

 

- 하지만 이럴 경우, 매개변수가 많아지면 각 값을 하나씩 변경하여 무한히 많이 반복을 돌려야 하므로 일일이 구하기 어려울 수 있다.

- AutoML : 사람의 개입 없이 하이퍼파라미터튜닝을 자동으로 수행하는 기술

- 이를 해결하는 도구 중 하나가 그리드서치(GridSearch)이다.

 

<그리드서치>

#GridSearchCV를 임포트
from sklearn.model_selection import GridSearchCV

#찾고자 하는 매개변수의 최적값 리스트를 딕셔너리로 변경
params = {'min_impurity_decrease': [0.0001, 0.0002, 0.0003, 0.0004, 0.0005]}

#GridSearchCV클래스에 탐색 대상 모델과 params 변수를 전달하여 그리드 서치 객체를 만든다.
gs = GridSearchCV(DecisionTreeClassifier(random_state=42), params, n_jobs=-1)

gs.fit(train_input, train_target)

 

- GridSearchCV의 cv 매개변수 기본값은 5이다, 따라서 찾고자 하는 매개변수의 값마다 5-폴드 교차검증을 수행한다. 

- 즉, 총 25개의 모델을 훈련하는 것이다.

- 많은 모델을 훈련하기 때문에 n_jobs매개변수를 사용해 병렬실행에 사용할 CPU코어수를 정할 수 있다. 이떄 n_jobs를 '-1'로 지정하면 모든 코어를 사용하게 된다.

 

dt = gs.best_estimator_
print(dt.score(train_input, train_target))

print(gs.best_params_)

 

- 그리드 서치는 훈련이 끝나면 검증 점수가 가장 높은 모델의 매개변수 조합으로 지정해 전체 훈련세트에서 자동으로 다시 훈련한다. 이때 사용되는 매개변수는 best_estimator_에 저장되어 있다.

- 그리드 서치로 찾은 최적의 매개변수는 best_params_에 저장되어 있다.

 

dt = gs.best_estimator_
print(dt.score(train_input, train_target))

 

- 매개변수는 하나가 아니라 여러개를 사용해서 사용이 가능하다.

 

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

 

[그리드 서치 과정 정리]

 

1) 탐색할 매개변수 목록 지정

2) 훈련 세트에서 그리드서치를 수행하여 최상의 평균 검증 점수가 나오는 매개변수 조합을 찾음 => 이 매개변수 조합은 그리드 서치 객체에 저장됨.

3) 저장된 최상의 매개변수로 교차검증에 사용한 훈련세트가 아닌 전체 훈련 세트를 사용해 최종모델 훈련 => 이 역시 그리드 서치 객체에 저장됨.

 

<랜덤서치>

 

- 랜덤서치 : 매개변수를 샘플링할 수 있는 확률 분포 객체를 전달해 최적의 매개변수를 찾는 과정

- 매개변수의 값이 수치일때 값의 범위나 간격을 미리 정하기 어려울 수 있다.  또 너무 많은 매개변수가 있을 경우 그리드 서치가 수행시간이 더 오래걸릴 수 있다. 이럴때 랜덤서치를 사용하는 것이 좋다.

 

from scipy.stats import uniform, randint

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

dt = gs.best_estimator_

print(dt.score(test_input, test_target))

 

<전체 소스 코드>

 

링크 : bit.ly/hg-05-2

반응형