LightGBMPruningCallback metric direction may conflict with objective value #5348
-
Hi there! Here is some part of the source code in class LightGBMPruningCallback:
def __init__(
self,
trial: optuna.trial.Trial,
metric: str,
valid_name: str = "valid_0",
report_interval: int = 1,
) -> None:
_imports.check()
self._trial = trial
self._valid_name = valid_name
self._metric = metric
self._report_interval = report_interval
# other code
def __call__(self, env: CallbackEnv) -> None:
if (env.iteration + 1) % self._report_interval == 0:
# other code
evaluation_result = self._find_evaluation_result(target_valid_name, env)
# other code
valid_name, metric, current_score, is_higher_better = evaluation_result[:4]
# other code
if is_higher_better:
if self._trial.study.direction != optuna.study.StudyDirection.MAXIMIZE:
raise ValueError(
"The intermediate values are inconsistent with the objective values"
"in terms of study directions. Please specify a metric to be minimized"
"for LightGBMPruningCallback."
)
else:
if self._trial.study.direction != optuna.study.StudyDirection.MINIMIZE:
raise ValueError(
"The intermediate values are inconsistent with the objective values"
"in terms of study directions. Please specify a metric to be"
"maximized for LightGBMPruningCallback."
)
# other code According to the code above, I assume that the At the same time, I copied some part of code from this example. def objective(trial):
data, target = sklearn.datasets.load_breast_cancer(return_X_y=True)
train_x, valid_x, train_y, valid_y = train_test_split(data, target, test_size=0.25)
dtrain = lgb.Dataset(train_x, label=train_y)
dvalid = lgb.Dataset(valid_x, label=valid_y)
param = {
"objective": "binary",
"metric": "auc",
"verbosity": -1,
"boosting_type": "gbdt",
"lambda_l1": trial.suggest_float("lambda_l1", 1e-8, 10.0, log=True),
"lambda_l2": trial.suggest_float("lambda_l2", 1e-8, 10.0, log=True),
"num_leaves": trial.suggest_int("num_leaves", 2, 256),
"feature_fraction": trial.suggest_float("feature_fraction", 0.4, 1.0),
"bagging_fraction": trial.suggest_float("bagging_fraction", 0.4, 1.0),
"bagging_freq": trial.suggest_int("bagging_freq", 1, 7),
"min_child_samples": trial.suggest_int("min_child_samples", 5, 100),
}
# Add a callback for pruning.
pruning_callback = optuna.integration.LightGBMPruningCallback(trial, "auc")
gbm = lgb.train(param, dtrain, valid_sets=[dvalid], callbacks=[pruning_callback])
preds = gbm.predict(valid_x)
pred_labels = np.rint(preds)
accuracy = sklearn.metrics.accuracy_score(valid_y, pred_labels)
return accuracy
if __name__ == "__main__":
study = optuna.create_study(
pruner=optuna.pruners.MedianPruner(n_warmup_steps=10), direction="maximize"
)
study.optimize(objective, n_trials=100)
print("Best trial:")
trial = study.best_trial I think Optuna will check if the objective value was the best result and if it was,model parameters will be saved to After reading all these code above, I found out the value returned from objective function may or may not be the same metric with LightGBMPruningCallback(trial, "some_metric"), for example, the objective function above returned the 'accuracy' value and the pruning_callback tracks the 'auc' value. So here is my question:
Pardon me since these are all my personal opinions and it may not be correct. Thanks to those who may answer my questions! Looking forward to your reply :) |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 2 replies
-
BTW, I think Optuna was a very interesting and helpful tools in model optimization. And it has very clean source code which makes people easy to read. Thanks to contributors of Optuna. |
Beta Was this translation helpful? Give feedback.
-
Short answers: Yes (but this never happens with the example above, I think) and Yes. Thank you for your questions. Indeed, the example script from For the second question, I think that will happen. In my mind, the imbalanced data case, accuracy can be very high (99%), but not AUC. |
Beta Was this translation helpful? Give feedback.
Short answers: Yes (but this never happens with the example above, I think) and Yes.
Thank you for your questions. Indeed, the example script from
optuna-examples
seems not good. In my understanding, the intermediate values should be the same metric as the objective value, especially, when a sampler cares the pruned trials; #3542 and #1647 explain why this matters. Even not, at least they should have the same direction. If they are not consistent like the first question's setting, the pruner will stop optimisations for good trails (maybe best trial too) because the pruner usesdirection
instudy
; pruners treat trials having lower logloss intermediate values as bad trails, which actually g…