🔥알림🔥
① 테디노트 유튜브 -
구경하러 가기!
② LangChain 한국어 튜토리얼
바로가기 👀
③ 랭체인 노트 무료 전자책(wikidocs)
바로가기 🙌
④ RAG 비법노트 LangChain 강의오픈
바로가기 🙌
⑤ 서울대 PyTorch 딥러닝 강의
바로가기 🙌
Optuna를 활용한 하이퍼파라미터 최적화
이번 포스팅에서는 기계 학습 모델의 성능을 극대화하기 위해 하이퍼파라미터 최적화 과정에 대해 깊게 다루려고 합니다.
특히, 최적의 하이퍼파라미터를 찾기 위해 Optuna 라는 라이브러리를 사용하는 방법에 초점을 맞춰 설명하겠습니다.
Optuna
를 활용하면 다양한 알고리즘의 파라미터를 효과적으로 탐색하면서, 교차 검증 기반으로 모델의 일반화 성능을 평가할 수 있습니다. 이러한 과정을 통해 모델의 성능을 향상시키는 데 큰 도움이 될 것입니다.
Optuna 설치
pip install optuna
파라미터 도메인 설정: trial.suggest_…
- 참고 문서: https://optuna.readthedocs.io/en/stable/reference/generated/optuna.trial.Trial.html#optuna.trial.Trial
Optuna
라이브러리는 하이퍼파라미터 최적화를 위한 강력한 도구로, 여러 종류의 하이퍼파라미터에 대한 제안 방법을 제공합니다. trial.suggest_...
메소드를 통해 다양한 형태의 하이퍼파라미터를 제안할 수 있습니다.
trial.suggest_categorical()
- 카테고리형 하이퍼파라미터를 제안합니다.
- 인수:
- name (str): 하이퍼파라미터의 이름입니다.
- choices (Sequence): 가능한 카테고리 값을 포함한 리스트나 튜플입니다.
- 이 메소드는 주어진
choices
중 하나를 무작위로 선택하여 반환합니다. - 예시
optimizer = trial.suggest_categorical("optimizer", ["SGD", "Adam", "RMSprop"])
trial.suggest_int()
- 정수 범위 내의 하이퍼파라미터를 제안합니다.
- 인수:
- name (str): 하이퍼파라미터의 이름입니다.
- low (int): 가능한 최소값입니다.
- high (int): 가능한 최대값입니다.
- step (int, optional): 값 간의 거리를 지정합니다. 기본값은 1입니다.
- log (bool, optional): 로그 스케일로 값을 제안할 것인지를 결정합니다. 기본값은 False입니다.
- 이 메소드는
low
와high
사이의 정수 값을 무작위로 선택하여 반환합니다.step
이 주어진 경우,low
에서 시작하여step
만큼씩 증가하는 값들 중 하나를 반환합니다. - 예시
n_estimators = trial.suggest_int("n_estimators", 100, 2000, step=100)
trial.suggest_float()
- 실수 범위 내의 하이퍼파라미터를 제안합니다.
- 인수:
- name (str): 하이퍼파라미터의 이름입니다.
- low (float): 가능한 최소값입니다.
- high (float): 가능한 최대값입니다.
- step (float, optional): 값 간의 거리를 지정합니다. step이 주어지면 실수 대신
low
와high
사이의 이산 값 중 하나를 제안합니다. - log (bool, optional): 로그 스케일로 값을 제안할 것인지를 결정합니다. 기본값은 False입니다.
- 이 메소드는
low
와high
사이의 실수 값을 무작위로 선택하여 반환합니다.step
이 주어진 경우,low
에서 시작하여step
만큼씩 증가하는 값들 중 하나를 반환합니다. - 예시
max_features = trial.suggest_float('max_features', 0.6, 0.9, step=0.1),
이 3가지 함수를 활용하여 다양한 유형의 하이퍼파라미터 공간을 정의하고 탐색할 수 있습니다. Optuna의 장점 중 하나는 이러한 함수들을 쉽게 조합하여 복잡한 하이퍼파라미터 탐색 공간도 쉽게 정의할 수 있다는 점입니다.
Optuna 를 활용한 파라미터 최적화
objective
함수를 정의합니다. 함수 내에서는 5-Fold Cross Validation 평가를 통해 가장 낮은 에러를 도출하도록 parameter 조정이 이루어 집니다.
알고리즘 별로 파라미터 도메인이 다를 수 있으므로, objective
함수 내의 params 는 적절히 수정하도록 합니다.
from optuna.trial import Trial
import optuna
from sklearn.model_selection import KFold
from sklearn.metrics import mean_squared_error
from sklearn.ensemble import RandomForestRegressor
def objective(trial: Trial, model, x, y, eval_metric):
"""
Optuna의 하이퍼파라미터 튜닝을 위한 목적 함수
Parameters:
- trial: Optuna의 Trial 객체
- model: 튜닝할 머신러닝 모델
- x: 입력 데이터
- y: 타겟 데이터
- eval_metric: 모델을 평가하기 위한 메트릭
"""
# 모델에 맞는 하이퍼파라미터 범위를 정의합니다.
params = {
'random_state': 123,
'n_jobs': -1,
'criterion': trial.suggest_categorical('criterion', ['squared_error', 'absolute_error']),
'max_depth': trial.suggest_int('max_depth', 3, 20, step=1),
'n_estimators': trial.suggest_int('n_estimators', 50, 500, step=10),
'max_features': trial.suggest_float('max_features', 0.6, 0.9, step=0.1),
}
# 데이터 프레임이나 시리즈 형태의 x와 y를 numpy 배열로 변환합니다.
x = x.values if isinstance(x, pd.DataFrame) else x
y = y.values if isinstance(y, pd.Series) else y
results = dict()
# 5-Fold Cross Validation을 정의합니다.
fold = KFold(n_splits=5, shuffle=True, random_state=SEED)
# 각 Fold에 대해 모델을 학습하고 평가합니다.
for i, (train_idx, test_idx) in enumerate(fold.split(x, y)):
x_train, y_train = x[train_idx], y[train_idx]
x_test, y_test = x[test_idx], y[test_idx]
# 현재의 하이퍼파라미터 세트로 모델을 생성하고 학습합니다.
fold_model = model(**params)
fold_model.fit(x_train, y_train)
fold_pred = fold_model.predict(x_test)
# 해당 Fold의 평가 결과를 저장합니다.
fold_error = eval_metric(y_test, fold_pred)
results[i] = {
'model': fold_model,
'error': fold_error
}
# 모든 Fold의 평가 결과의 평균을 반환합니다.
errors = [v['error'] for k, v in results.items()]
return np.array(errors).mean()
optuna.create_study()
로 최적화 객체를 생성하고 optimize()
함수를 호출하여 최적화를 진행합니다.
optimize()
함수에 전달하는 인수에 모델, x, y, 평가지표, 마지막으로 n_trials 를 적절히 전달합니다.
# 최소화 방향으로 하이퍼 파라미터 학습을 위한 스터디 객체를 생성합니다.
study = optuna.create_study(direction='minimize', study_name='randomforest_1')
# 하이퍼파라미터 튜닝을 시작합니다.
study.optimize(lambda trial: objective(trial, RandomForestRegressor, x, y, mean_squared_error), n_trials=20)
최종 결과를 출력하여 찾은 파라미터를 출력합니다.
# 최적의 하이퍼파라미터를 출력합니다.
print(study.best_params)
# 모델에 적용시
model = RandomForestRegressor(**study.best_params)
model.fit(x, y)
댓글남기기