Data

하이퍼 파라미터 튜닝 - 그리드 서치 / 랜덤 서치

HC-Kang 2021. 5. 12. 19:16

혼자 공부하는 머신러닝+딥러닝 / 박해선 저

 

우선 파라미터는 모델이 돌아갈 때 쓰는 변수들이라고 생각하면 될 것 같고, 그중에서도 우리가 주로 신경 쓸 것은 하이퍼 파라미터임.

결론만 간단히 하면, 하이퍼 파라미터는 사람이 만지는 것이라고 보면 될 것 같고 종종 휴리스틱,, 그러니까 때려맞추기로 하는 경우도 있다고 함.

 

출처 : machinelearningmastery.com/difference-between-a-parameter-and-a-hyperparameter/

 

What is the Difference Between a Parameter and a Hyperparameter?

It can be confusing when you get started in applied machine learning. There are so many terms to use and […]

machinelearningmastery.com

 

 

위에서 말한 하이퍼 파라미터를 사람이 수동으로 하나씩 바꾸면서 찾아볼순 없는 노릇이니, 아래 두 가지 방법 사용

 

1. 그리드 서치

from sklearn.model_selection import GridSearchCV
        # GridSearchCV 함수 불러오기
params = {'min_impurity_decrease' : [0.0001, 0.0002, 0.0003, 0.0004, 0.0005]}
        # GridSearchCV에 적용할 parameter 지정해주기
gs = GridSearchCV(DecisionTreeClassifier(random_state = 42), params, n_jobs = -1)
        # n_jobs 는 병렬작업 수 지정. -1이면 가용한 모든 연산을 동시에 진행하라는 뜻.
        # cv를 지정 안했으니 기본값 5로 들어감.  
        # 최상의 평균검증 점수가 나오는 매개변수 조합을 찾아서 gs에 넣어두기.

gs.fit(train_input, train_target)
        # 5종류의 params 를 활용해서 train set 학습시키기

dt = gs.best_estimator_
print(dt.score(train_input, train_target))
        # 가장 우수한 성능을 가진 param의 점수 0.962

print(gs.best_params_)
        # 최고성능 param은 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'])
        # np.argmax 로 array gs.cv_results_ 의 mean_test_score 필드 내 최고값의 인덱스값 출력.

print(gs.cv_results_['params'][best_index])
        # 출력된 인덱스값을 가지고 value 값 출력

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)}
        # 기존 params에서 max_depth 와 min sample split을 추가하되 범위를 주고 지정함.

gs = GridSearchCV(DecisionTreeClassifier(random_state = 42), params, n_jobs = -1)
        # params 외에 다른 조건을 위와 동일하게 세팅하여 인스턴스 생성

gs.fit(train_input, train_target)
        # params 에 대해 생각해보면, min_impurity_decrease 9종, max_depth 15종, 
        # min_samples_split 10종으로 9x15x10 = 1,350 가지 경우의수를 뽑아줌.
        # 여기에 추가적으로 cv = None이므로 기본 5회 적용되어 총 6750회 모델 검증


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.868

 

2. 랜덤 서치

from scipy.stats import uniform, randint
        # scipy의 stats 서브 패키지에 있는 uniform과 randint는 모두 균등분포에서 샘플링한다고 함.
        # randint : 정수, uniform : 실수
rgen = randint(0, 10)
rgen
rgen.rvs(10)
        # 1~10까지 정수 10개 생성

np.unique(rgen.rvs(1000), return_counts = True)

ugen = uniform(0, 1)
ugen.rvs(10)
        # 1~10까지 실수 10개 생성

막상 해놓고 보니,, 그냥 한번 만들어본듯,, 이런

params = {
    'min_impurity_decrease' : uniform(0.0001, 0.001),
    'max_depth' : randint(20, 50),
    'min_samples_leaf' : randint(2, 25),
    'min_samples_leaf' : randint(1, 25)
}
        # 이번에는 params를 수동으로 작성하지 않고 uniform 과 randint 함수를 통해 생성함.
        # parameter 의 종류는 해당 함수의 공식문서를 확인하자.

공식 문서를 자주 확인하자.

from sklearn.model_selection import RandomizedSearchCV
        # 위의 그리드 서치와 비슷하게, 랜덤 서치 함수를 불러와준다.

gs = RandomizedSearchCV(DecisionTreeClassifier(random_state = 42), params, n_iter = 100, n_jobs = -1, random_state = 42)
        # n_iter 는 지정된 params 의 범위 내에서 랜덤하게 시행하는 횟수이고, 기본값은 10회. 여기서는 100회로 지정.
        # 숫자가 클수록 성능은 잘 나올수 있겠지만, 소요시간에 늘어남.

gs.fit(train_input, train_target)

print(gs.best_params_)
        #{'max_depth': 36, 말단 노드까지의 층 수
        # 'min_impurity_decrease': 0.00041435598107632666,  - 최소 순수도 감소폭
        # 'min_samples_leaf': 4} - 말단 노드에 있어야할 최소한의 샘플 수

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

dt = gs.best_estimator_

print(dt.score(test_input, test_target))
        # 0.8592307692307692