오늘은 최종 제출 하루 전이라서 모델 세팅에 몰두했다.
LightGBM에 하이퍼 파라미터 조정을 위해 Optuna를 적용해봤다.
def objective 함수를 만들어 각 파라미터의 low와 high값을 설정해두고 가장 fold_mae의 합이 최소가 되는 파라미터 값을 찾는다. n_trials를 num_boost_round와 적절하게 세팅한 후 진행한다.
마지막 최종 예측은 best_params로 진행해서 최종적으로 구한다.
코드
import lightgbm as lgb
import numpy as np
from sklearn.model_selection import KFold
from sklearn.metrics import mean_absolute_error
import optuna
# 학습에 사용할 특징 열
feature_columns = [col for col in temp_train_df.columns if col not in ['deposit', '_type', 'index']]
# 학습 데이터 준비
X = temp_train_df[feature_columns]
y = temp_train_df['deposit']
# 5-fold 교차 검증 설정
n_folds = 5
kf = KFold(n_splits=n_folds, shuffle=True, random_state=42)
def objective(trial):
# 하이퍼파라미터 탐색 공간 정의
params = {
'objective': 'regression',
'metric': 'mae',
'boosting_type': 'gbdt',
'num_leaves': trial.suggest_int('num_leaves', 21, 51),
'learning_rate': trial.suggest_float('learning_rate', 0.05, 0.05),
'feature_fraction': trial.suggest_float('feature_fraction', 0.8, 1.0),
'bagging_fraction': trial.suggest_float('bagging_fraction', 0.8, 1.0),
'bagging_freq': trial.suggest_int('bagging_freq', 3, 10),
'min_child_samples': trial.suggest_int('min_child_samples', 10, 100),
'max_depth': trial.suggest_int('max_depth', 5, 50),
'seed': 42,
}
# 교차 검증 결과를 저장할 변수
cv_scores = []
for fold, (train_idx, val_idx) in enumerate(kf.split(X), 1):
X_train, X_val = X.iloc[train_idx], X.iloc[val_idx]
y_train, y_val = y.iloc[train_idx], y.iloc[val_idx]
dtrain = lgb.Dataset(X_train, label=y_train)
dval = lgb.Dataset(X_val, label=y_val, reference=dtrain)
model = lgb.train(
params,
dtrain,
num_boost_round=500,
valid_sets=[dval],
)
val_pred = model.predict(X_val)
fold_mae = mean_absolute_error(y_val, val_pred)
cv_scores.append(fold_mae)
return np.mean(cv_scores)
study = optuna.create_study(direction='minimize')
study.optimize(objective, n_trials=50)
# 최적의 하이퍼파라미터 출력
print("Best parameters:", study.best_params)
print("Best MAE:", study.best_value)
# 최적화된 파라미터로 최종 모델 학습
best_params = study.best_params
best_params.update({
'objective': 'regression',
'metric': 'mae',
'boosting_type': 'gbdt',
'seed': 42
})
# 최종 예측은 기존 코드와 동일한 방식으로 진행
oof_predictions = np.zeros(len(X))
test_predictions = np.zeros(len(test_df))
def print_evaluation(period=10):
def callback(env):
if (env.iteration + 1) % period == 0:
train_mae = env.evaluation_result_list[0][2]
val_mae = env.evaluation_result_list[1][2]
print(f"[{env.iteration + 1}] Train MAE: {train_mae:.4f}, Val MAE: {val_mae:.4f}")
return callback
for fold, (train_idx, val_idx) in enumerate(kf.split(X), 1):
X_train, X_val = X.iloc[train_idx], X.iloc[val_idx]
y_train, y_val = y.iloc[train_idx], y.iloc[val_idx]
dtrain = lgb.Dataset(X_train, label=y_train)
dval = lgb.Dataset(X_val, label=y_val, reference=dtrain)
model = lgb.train(
best_params,
dtrain,
num_boost_round=12000,
valid_sets=[dtrain, dval],
callbacks=[print_evaluation(100)]
)
oof_predictions[val_idx] = model.predict(X_val)
test_predictions += model.predict(test_df[feature_columns]) / n_folds