首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >向LightGBM提供额外的自定义度量,以便早期停止

向LightGBM提供额外的自定义度量,以便早期停止
EN

Stack Overflow用户
提问于 2021-09-10 20:37:04
回答 1查看 2.5K关注 0票数 3

我使用训练API在LightGBM中运行二进制分类,并希望停止使用自定义度量,同时仍然跟踪一个或多个内置度量。不过,目前还不清楚这是否可能。

在这里,我们可以禁用默认的binary_logloss度量,并且只跟踪自定义度量:

代码语言:javascript
运行
复制
import lightgbm as lgb

def my_eval_metric(...):
    ...

d_train = lgb.Dataset(...)
d_validate = lgb.Dataset(...)

params = {
    "objective": "binary",
    "metric": "custom",
}

evals_result = {}

model = lgb.train(
    params,
    d_train,
    valid_sets=[d_validate],
    feval=my_eval_metric,
    early_stopping_rounds=10,
    evals_result=evals_result,
)

如果我们让metric成为默认的,我们也会跟踪binary_logloss,但是我们将停止这两种度量,而不是仅仅停留在自定义度量上:

代码语言:javascript
运行
复制
params = {
    "objective": "binary",
    # "metric": "custom",
}

我们可以在first_metric_only中设置params,但是现在我们只在binary_logloss上停止,因为这显然是第一个度量:

代码语言:javascript
运行
复制
params = {
    "objective": "binary",
    "first_metric_only": True,
}

其他一些可能有用但看起来很痛苦的事情:

  1. 在sklearn API中显示,您可以指定一个评估指标列表,用于自定义度量的可调用性和用于内置度量的字符串;但是,我不希望切换到sklearn API。
  2. I可以重新实现binary_logloss并将其作为自定义评估指标传递到另一个自定义度量列表中,并使用first_metric_only;然而,似乎我不应该这样做。

不起作用的事情:

  1. feval=[my_eval_metric, 'binary_logloss']lgb.train调用中。抱怨字符串在callable.
  2. metric: [my_eval_metric, 'binary_logloss']集中不是params。警告Unknown parameter: my_eval_metric,然后当训练以Unknown parameter: my_eval_metric开始时出错

我是不是遗漏了一些显而易见的东西,或者这是LightGBM API中的一个小漏洞?

这是在3.2.1版上。在3.0.0版上,似乎完全不可能在培训API中传递多个自定义评估指标。我不确定那里的sklearn。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-09-12 22:50:12

如果您问“如何根据自定义的评估度量函数执行早期停止?”,这可以通过将参数metric设置为字符串"None"来实现。这将导致LightGBM跳过基于目标函数的默认评估度量(在您的示例中是binary_logloss),并且只对您在feval中提供的自定义度量函数执行早期停止。

下面的示例在Python3.8.8上使用lightgbm==3.2.1scikit-learn==0.24.1来再现此行为。

代码语言:javascript
运行
复制
import lightgbm as lgb
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split

X, y = load_breast_cancer(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.1, random_state=42)

dtrain = lgb.Dataset(
    data=X_train,
    label=y_train
)

dvalid = lgb.Dataset(
    data=X_test,
    label=y_test,
    reference=dtrain
)

def _constant_metric(dy_true, dy_pred):
    """An eval metric that always returns the same value"""
    metric_name = 'constant_metric'
    value = 0.708
    is_higher_better = False
    return metric_name, value, is_higher_better

evals_result = {}

model = lgb.train(
    params={
        "objective": "binary",
        "metric": "None",
        "num_iterations": 100,
        "first_metric_only": True,
        "verbose": 0,
        "num_leaves": 8
    },
    train_set=dtrain,
    valid_sets=[dvalid],
    feval=_constant_metric,
    early_stopping_rounds=5,
    evals_result=evals_result,
)

您可以在日志中看到,我提供的自定义度量函数是根据验证集进行评估的,培训在early_stopping_rounds连续回合之后停止,没有改进。

代码语言:javascript
运行
复制
[LightGBM] [Warning] Auto-choosing col-wise multi-threading, the overhead of testing was 0.000846 seconds.
You can set `force_col_wise=true` to remove the overhead.
[1] valid_0's constant_metric: 0.708
Training until validation scores don't improve for 5 rounds
[2] valid_0's constant_metric: 0.708
[3] valid_0's constant_metric: 0.708
[4] valid_0's constant_metric: 0.708
[5] valid_0's constant_metric: 0.708
[6] valid_0's constant_metric: 0.708
Early stopping, best iteration is:
[1] valid_0's constant_metric: 0.708
Evaluated only: constant_metric

如果您问“如何向lgb.train()提供内置度量和自定义评估函数的混合,并得到所有度量,但只使用自定义度量进行早期停止?”...then是,这在lightgbm 3.2.1中不受支持。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69137780

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档