-
Notifications
You must be signed in to change notification settings - Fork 4k
Incorrect delta for huber objective #7194
Copy link
Copy link
Open
Labels
Description
Description
huber objective implementation in lightgbm uses alpha directly as delta. However, alpha is meant to be interpreted as a percentile. This means the default alpha=0.9 is often meaningless and not targeted to the problem.
Instead, delta should be calculated from alpha, e.g. as (C++ equivalent of) delta=np.quantile(np.abs(labels - labels.mean()), 0.9)
LightGBM/src/objective/regression_objective.hpp
Lines 314 to 339 in 64ab66e
| void GetGradients(const double* score, score_t* gradients, | |
| score_t* hessians) const override { | |
| if (weights_ == nullptr) { | |
| #pragma omp parallel for num_threads(OMP_NUM_THREADS()) schedule(static) | |
| for (data_size_t i = 0; i < num_data_; ++i) { | |
| const double diff = score[i] - label_[i]; | |
| if (std::abs(diff) <= alpha_) { | |
| gradients[i] = static_cast<score_t>(diff); | |
| } else { | |
| gradients[i] = static_cast<score_t>(Common::Sign(diff) * alpha_); | |
| } | |
| hessians[i] = 1.0f; | |
| } | |
| } else { | |
| #pragma omp parallel for num_threads(OMP_NUM_THREADS()) schedule(static) | |
| for (data_size_t i = 0; i < num_data_; ++i) { | |
| const double diff = score[i] - label_[i]; | |
| if (std::abs(diff) <= alpha_) { | |
| gradients[i] = static_cast<score_t>(diff * weights_[i]); | |
| } else { | |
| gradients[i] = static_cast<score_t>(Common::Sign(diff) * static_cast<score_t>(weights_[i]) * alpha_); | |
| } | |
| hessians[i] = static_cast<score_t>(weights_[i]); | |
| } | |
| } | |
| } |
Reactions are currently unavailable