경진대회를 푸는 데 필요한 주요 머신러닝 개념들을 요약·정리해뒀습니다. 머신러닝 이론을 기초부터 차근히 설명하려는 목적이 ‘아니므로’ 정독하실 필요는 없습니다. 문제를 풀다가 언뜻 떠오르지 않는 개념이 있을 때 참고해주세요. 총 4편으로 준비했습니다. 마지막 4편에서는 대표적인 하이퍼파라미터 최적화 방법인 그리드서치, 랜덤서치, 베이지안 최적화를 정리했습니다.
1. 그리드서치
그리드서치(Grid search)는 가장 기본적인 하이퍼파라미터 최적화 기법으로, 주어진 하이퍼파라미터를 모두 순회하며 가장 좋은 성능을 내는 값을 찾습니다. 모든 경우의 수를 탐색하는 방식이죠. 그래서 시간이 오래 걸린다는 단점이 있습니다.
▼ 그리드서치 도식
그리드서치를 이용하지 않으면 alpha에 0.1, 1, 2 등의 값을 전달하여 교차 검증으로 모델 성능을 각각 측정해야 합니다. 수작업으로 하나하나 수행한 뒤 최적 하이퍼파라미터를 찾아야 하니 무척 번거롭습니다. 특히 하이퍼파라미터의 개수가 하나 늘어날 때마다 번거로움은 기하급수적으로 커질 것입니다. 그리드서치는 이 일을 자동으로 해줍니다. 테스트하려는 하이퍼파라미터와 값의 범위만 전달하면 알아서 모든 가능한 조합을 순회하며 교차 검증합니다.
그리드서치가 추가되면서 하이퍼파라미터 최적화 절차는 다음 그림처럼 세분화됩니다.
▼ 하이퍼파라미터 최적화 절차(그리드서치)
2. 랜덤서치
랜덤서치(Random search)는 하이퍼파라미터를 무작위로 탐색해 가장 좋은 성능을 내는 값을 찾는 기법입니다. 무작위라는 한계 때문에 그리드서치나 베이지안 최적화에 비해 사용 빈도가 떨어집니다.
랜덤서치는 사이킷런이 제공하는 RandomizedSearchCV( ) 메서드로 수행할 수 있습니다. 그리드서치와 사용법이 비슷하므로 자세히 설명하진 않겠습니다.
3. 베이지안 최적화
베이지안 최적화(Bayesian optimization)란 사전 정보를 바탕으로 최적 하이퍼파라미터 값을 확률적으로 추정하며 탐색하는 기법입니다. 그리드서치나 랜덤서치보다 최적 하이퍼파라미터를 더 빠르고 효율적으로 찾아줍니다. 코드도 직관적이어서 사용하기도 편리하고요.
bayes_opt라는 패키지로 베이지안 최적화를 구현할 수 있습니다. bayes_opt 패키지 기준으로 베이지안 최적화를 수행하는 절차는 다음과 같습니다.
- 하이퍼파라미터 탐색 범위 설정 : 최적 값을 찾고 싶은 하이퍼파라미터의 범위를 설정합니다.
- 평가지표 계산 함수( 성능 평가 함수) 정의 : 탐색하려는 하이퍼파라미터를 인수로 받아 평가지표 값을 계산해주는 함수를 정의합니다.
- BayesianOptimization 객체 생성 : bayes_opt 패키지의 BayesianOptimization 객체를 생성합니다. 객체 생성 시 ‘평가지표 계산 함수’와 ‘하이퍼파라미터 탐색 범위’를 입력받습니다.
- 베이지안 최적화 수행 : 3에서 생성한 BayesianOptimization 객체의 maximize( ) 메서드를 호출합니다. 하이퍼파라미터 범위 내 값을 평가지표 계산 함수에 전달하면서 평가지표 값을 구합니다. 평가지표 값이 가장 좋았을 때의 하이퍼파라미터 값을 최적 하이퍼파라미터로 간주합니다.
다음과 같은 간단한 예제로 베이지안 최적화를 수행해보겠습니다.
1) 하이퍼파라미터 탐색 범위 설정
본 예제에서 탐색할 하이퍼파라미터는 x와 y이며, 탐색 범위는 딕셔너리 형태로 지정합니다.
# 하이퍼 파라미터 범위 (딕셔너리 형태)
param_bounds = {'x': (-1, 5),
'y': (0, 4)}
딕셔너리의 키key에 하이퍼파라미터 이름을, 값value에 하이퍼파라미터 범위(튜플 형태)를 지정하면 됩니다. 하이퍼파라미터 x 범위가 (-1, 5)라면 -1~5 사이를 탐색하겠다는 뜻입니다.
2) 평가지표 계산 함수 정의
베이지안 최적화는 평가지표 계산 함수로 구한 평가점수를 최대화하는 방향으로 하이퍼파라미터를 탐색합니다. 평가점수가 가장 큰 값일 때의 하이퍼파라미터를 최적 하이퍼파라미터로 간주합니다. 물론 실제 최적 하이퍼파라미터는 아닐 수 있습니다. 최적일 가능성이 높은 하이퍼파라미터입니다.
다음은 임의로 만들어본 평가지표 계산 함수입니다.
def eval_function(x, y):
return -x ** 2 - (y - 2) ** 2 + 10
3) 베이지안 최적화 객체 생성
BayesianOptimization( )으로 베이지안 최적화 객체를 생성합니다. 중요한 생성 파라미터로는 f와 pbounds가 있습니다. f에 ‘최대화하려는 평가지표 계산 함수’를 전달하고, pbounds에 하이퍼파라미터 범위를 전달합니다. 더불어 random_state를 설정해 시드값을 고정하면 다음번에 실행할 때도 동일한 결과를 얻을 수 있습니다.
from bayes_opt import BayesianOptimization
# 베이지안 최적화 객체 생성
optimizer = BayesianOptimization(f=eval_function,
pbounds=param_bounds,
random_state=0)
4) 최적화 수행
최적화는 간단히 maximize( ) 메서드로 수행할 수 있습니다. 이 메서드는 여러 파라미터를 받는데, 가장 중요한 파라미터는 init_points와 n_iter입니다.
- init_points : 랜덤 탐색을 수행할 스텝 횟수. 랜덤 탐색은 탐색 공간을 다양화함으로써 최적화에 도움을 줄 수 있습니다.
- n_iter : 베이지안 최적화를 수행할 스텝 횟수. 스텝 횟수가 많을수록 최적 값을 찾을 가능성이 높습니다.
# 베이지안 최적화 수행
optimizer.maximize(init_points=2, n_iter=10)
총 스텝 횟수(12)는 init_points(2)와 n_iter(10)을 합친 횟수입니다. 중간중간 결과가 빨갛게 출력되는데, 평가 함수 점수가 기존 최댓값을 갱신했다는 뜻입니다. 따라서 빨간 결과 중 가장 마지막 스텝의 평가점수가 전체에서 최대가 되는 값입니다. 이 결과에서는 11번째 스텝으로, 베이지안 최적화로 찾은 최적 하이퍼파라미터는 x=0.181, y=2.48입니다.
이 값은 베이지안 최적화 객체의 max에 저장되어 있습니다.
# 평가점수가 최대일 때 타깃, x, y 값 출력
optimizer.max
{'target': 9.737113614981094, 'params': {'x': 0.18055072150995197, 'y': 2.4798831336702114}}