我使用训练API在LightGBM中运行二进制分类,并希望停止使用自定义度量,同时仍然跟踪一个或多个内置度量。不过,目前还不清楚这是否可能。
在这里,我们可以禁用默认的binary_logloss
度量,并且只跟踪自定义度量:
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
,但是我们将停止这两种度量,而不是仅仅停留在自定义度量上:
params = {
"objective": "binary",
# "metric": "custom",
}
我们可以在first_metric_only
中设置params
,但是现在我们只在binary_logloss
上停止,因为这显然是第一个度量:
params = {
"objective": "binary",
"first_metric_only": True,
}
其他一些可能有用但看起来很痛苦的事情:
binary_logloss
并将其作为自定义评估指标传递到另一个自定义度量列表中,并使用first_metric_only
;然而,似乎我不应该这样做。不起作用的事情:
feval=[my_eval_metric, 'binary_logloss']
在lgb.train
调用中。抱怨字符串在callable.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。
发布于 2021-09-12 22:50:12
如果您问“如何根据自定义的评估度量函数执行早期停止?”,这可以通过将参数metric
设置为字符串"None"
来实现。这将导致LightGBM跳过基于目标函数的默认评估度量(在您的示例中是binary_logloss
),并且只对您在feval
中提供的自定义度量函数执行早期停止。
下面的示例在Python3.8.8上使用lightgbm==3.2.1
和scikit-learn==0.24.1
来再现此行为。
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
连续回合之后停止,没有改进。
[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中不受支持。
https://stackoverflow.com/questions/69137780
复制相似问题