Skip to content

Incorrect delta for huber objective #7194

@thebigspin

Description

@thebigspin

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)

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]);
}
}
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions