如何实现与LightGBM中二元目标相同的自定义对数损失?

我正在尝试为二元分类实现自己的损失函数。首先,我想重现二元目标的完全行为。特别是,我希望实现以下几点:

  • 两个函数的损失具有相同的尺度
  • 训练和验证的斜率相似
  • predict_proba(X) 返回概率

以下代码并未实现这些要求:

import sklearn.datasetsimport lightgbm as lgbimport numpy as npX, y = sklearn.datasets.load_iris(return_X_y=True)X, y = X[y <= 1], y[y <= 1]def loglikelihood(labels, preds):    preds = 1. / (1. + np.exp(-preds))    grad = preds - labels    hess = preds * (1. - preds)    return grad, hessmodel = lgb.LGBMClassifier(objective=loglikelihood)  # or "binary"model.fit(X, y, eval_set=[(X, y)], eval_metric="binary_logloss")lgb.plot_metric(model.evals_result_)

使用 objective=”binary” 时:

enter image description here

使用 objective=loglikelihood 时,斜率甚至不平滑:

enter image description here

此外,对于 loglikelihood,必须对 model.predict_proba(X) 应用 sigmoid 函数才能获得概率(正如我从 https://github.com/Microsoft/LightGBM/issues/2136 中了解到的)。

是否有可能使用自定义损失函数获得相同的行为?有谁了解这些差异的来源?


回答:

查看每个案例中 model.predict_proba(X) 的输出,我们可以看到内置的 binary_logloss 模型返回概率,而自定义模型返回 logit。

内置的评估函数以概率作为输入。为了适应自定义目标,我们需要一个自定义评估函数,该函数将 logit 作为输入。

以下是如何编写这一点。我已经更改了 sigmoid 计算,以便在 logit 为大负数时不会溢出。

def loglikelihood(labels, logits):    #数值稳定的 sigmoid:    preds = np.where(logits >= 0,                 1. / (1. + np.exp(-logits)),                 np.exp(logits) / (1. + np.exp(logits)))    grad = preds - labels    hess = preds * (1. - preds)    return grad, hessdef my_eval(labels, logits):    #数值稳定的 logsigmoid:    logsigmoid = np.where(logits >= 0,                           -np.log(1 + np.exp(-logits)),                          logits - np.log(1 + np.exp(logits)))    loss = (-logsigmoid + logits * (1 - labels)).mean()    return "error", loss, False        model1 = lgb.LGBMClassifier(objective='binary')    model1.fit(X, y, eval_set=[(X, y)], eval_metric="binary_logloss")    model2 = lgb.LGBMClassifier(objective=loglikelihood)    model2.fit(X, y, eval_set=[(X, y)], eval_metric=my_eval)

现在,结果是相同的。

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注