1#ifndef LIGHTGBM_OBJECTIVE_BINARY_OBJECTIVE_HPP_
2#define LIGHTGBM_OBJECTIVE_BINARY_OBJECTIVE_HPP_
4#include <LightGBM/objective_function.h>
16 sigmoid_ =
static_cast<double>(config.sigmoid);
17 if (sigmoid_ <= 0.0) {
18 Log::Fatal(
"Sigmoid parameter %f should be greater than zero", sigmoid_);
20 is_unbalance_ = config.is_unbalance;
21 scale_pos_weight_ =
static_cast<double>(config.scale_pos_weight);
22 if (is_unbalance_ && std::fabs(scale_pos_weight_ - 1.0f) > 1e-6) {
23 Log::Fatal(
"Cannot set is_unbalance and scale_pos_weight at the same time");
26 if (is_pos_ ==
nullptr) {
27 is_pos_ = [](
label_t label) {
return label > 0; };
31 explicit BinaryLogloss(
const std::vector<std::string>& strs) {
33 for (
auto str : strs) {
34 auto tokens = Common::Split(str.c_str(),
':');
35 if (tokens.size() == 2) {
36 if (tokens[0] == std::string(
"sigmoid")) {
37 Common::Atof(tokens[1].c_str(), &sigmoid_);
41 if (sigmoid_ <= 0.0) {
42 Log::Fatal(
"Sigmoid parameter %f should be greater than zero", sigmoid_);
50 label_ = metadata.
label();
55 Log::Warning(
"Starting from the 2.1.2 version, default value for "
56 "the \"boost_from_average\" parameter in \"binary\" objective is true.\n"
57 "This may cause significantly different results comparing to the previous versions of LightGBM.\n"
58 "Try to set boost_from_average=false, if your old models produce bad results");
60 #pragma omp parallel for schedule(static) reduction(+:cnt_positive, cnt_negative)
62 if (is_pos_(label_[i])) {
69 if (cnt_negative == 0 || cnt_positive == 0) {
70 Log::Warning(
"Contains only one class");
74 Log::Info(
"Number of positive: %d, number of negative: %d", cnt_positive, cnt_negative);
79 label_weights_[0] = 1.0f;
80 label_weights_[1] = 1.0f;
82 if (is_unbalance_ && cnt_positive > 0 && cnt_negative > 0) {
83 if (cnt_positive > cnt_negative) {
84 label_weights_[1] = 1.0f;
85 label_weights_[0] =
static_cast<double>(cnt_positive) / cnt_negative;
87 label_weights_[1] =
static_cast<double>(cnt_negative) / cnt_positive;
88 label_weights_[0] = 1.0f;
91 label_weights_[1] *= scale_pos_weight_;
98 if (weights_ ==
nullptr) {
99 #pragma omp parallel for schedule(static)
102 const int is_pos = is_pos_(label_[i]);
103 const int label = label_val_[is_pos];
104 const double label_weight = label_weights_[is_pos];
106 const double response = -label * sigmoid_ / (1.0f + std::exp(label * sigmoid_ * score[i]));
107 const double abs_response = fabs(response);
108 gradients[i] =
static_cast<score_t>(response * label_weight);
109 hessians[i] =
static_cast<score_t>(abs_response * (sigmoid_ - abs_response) * label_weight);
112 #pragma omp parallel for schedule(static)
115 const int is_pos = is_pos_(label_[i]);
116 const int label = label_val_[is_pos];
117 const double label_weight = label_weights_[is_pos];
119 const double response = -label * sigmoid_ / (1.0f + std::exp(label * sigmoid_ * score[i]));
120 const double abs_response = fabs(response);
121 gradients[i] =
static_cast<score_t>(response * label_weight * weights_[i]);
122 hessians[i] =
static_cast<score_t>(abs_response * (sigmoid_ - abs_response) * label_weight * weights_[i]);
128 double BoostFromScore(
int)
const override {
131 if (weights_ !=
nullptr) {
132 #pragma omp parallel for schedule(static) reduction(+:suml, sumw)
134 suml += is_pos_(label_[i]) * weights_[i];
138 sumw =
static_cast<double>(num_data_);
139 #pragma omp parallel for schedule(static) reduction(+:suml)
141 suml += is_pos_(label_[i]);
144 double pavg = suml / sumw;
145 pavg = std::min(pavg, 1.0 - kEpsilon);
146 pavg = std::max<double>(pavg, kEpsilon);
147 double initscore = std::log(pavg / (1.0f - pavg)) / sigmoid_;
148 Log::Info(
"[%s:%s]: pavg=%f -> initscore=%f", GetName(), __func__, pavg, initscore);
152 bool ClassNeedTrain(
int )
const override {
156 const char* GetName()
const override {
160 void ConvertOutput(
const double* input,
double* output)
const override {
161 output[0] = 1.0f / (1.0f + std::exp(-sigmoid_ * input[0]));
164 std::string ToString()
const override {
165 std::stringstream str_buf;
166 str_buf << GetName() <<
" ";
167 str_buf <<
"sigmoid:" << sigmoid_;
168 return str_buf.str();
171 bool SkipEmptyClass()
const override {
return true; }
187 double label_weights_[2];
190 double scale_pos_weight_;
191 std::function<bool(
label_t)> is_pos_;
Objective function for binary classification.
Definition binary_objective.hpp:13
void GetGradients(const double *score, score_t *gradients, score_t *hessians) const override
calculating first order derivative of loss function
Definition binary_objective.hpp:94
bool NeedAccuratePrediction() const override
The prediction should be accurate or not. True will disable early stopping for prediction.
Definition binary_objective.hpp:173
void Init(const Metadata &metadata, data_size_t num_data) override
Initialize.
Definition binary_objective.hpp:48
The interface of Objective Function.
Definition objective_function.h:13
desc and descl2 fields must be written in reStructuredText format
Definition application.h:10
float score_t
Type of score, and gradients.
Definition meta.h:26
float label_t
Type of metadata, include weight and label.
Definition meta.h:33
int32_t data_size_t
Type of data size, it is better to use signed type.
Definition meta.h:14