f1_score lightgbm 中的指标
f1_score metric in lightgbm
我想用自定义指标训练 lgb 模型:f1_score
平均 weighted
。
我通过 here 浏览了 lightgbm 的高级示例,发现了自定义二进制错误函数的实现。我实现了与 return f1_score 类似的功能,如下所示。
def f1_metric(preds, train_data):
labels = train_data.get_label()
return 'f1', f1_score(labels, preds, average='weighted'), True
我尝试通过将 feval
参数作为 f1_metric
传递来训练模型,如下所示。
evals_results = {}
bst = lgb.train(params,
dtrain,
valid_sets= [dvalid],
valid_names=['valid'],
evals_result=evals_results,
num_boost_round=num_boost_round,
early_stopping_rounds=early_stopping_rounds,
verbose_eval=25,
feval=f1_metric)
然后我得到 ValueError: Found input variables with inconsistent numbers of samples:
正在将训练集而不是验证集传递给函数。
我如何配置才能通过验证集并且 f1_score 被 returned。?
文档有点混乱。在描述传递给 feval 的函数的签名时,他们将其参数称为 preds 和 train_data,这有点误导.
但以下似乎有效:
from sklearn.metrics import f1_score
def lgb_f1_score(y_hat, data):
y_true = data.get_label()
y_hat = np.round(y_hat) # scikits f1 doesn't like probabilities
return 'f1', f1_score(y_true, y_hat), True
evals_result = {}
clf = lgb.train(param, train_data, valid_sets=[val_data, train_data], valid_names=['val', 'train'], feval=lgb_f1_score, evals_result=evals_result)
lgb.plot_metric(evals_result, metric='f1')
要使用多个自定义指标,请像上面一样定义一个总体自定义指标函数,在其中计算所有指标和return一个元组列表。
编辑:固定代码,当然 F1 越大越好应该设置为 True。
关于托比的回答:
def lgb_f1_score(y_hat, data):
y_true = data.get_label()
y_hat = np.round(y_hat) # scikits f1 doesn't like probabilities
return 'f1', f1_score(y_true, y_hat), True
我建议将 y_hat 部分更改为:
y_hat = np.where(y_hat < 0.5, 0, 1)
原因:
我使用了 y_hat = np.round(y_hat) 并发现在训练期间 lightgbm 模型有时(非常不可能但仍然是一个变化)将我们的 y 预测视为多类而不是二进制。
我的推测:
有时 y 预测会小或大到足以舍入为负值或 2?我不确定,但是当我使用 np.where 更改代码时,错误消失了。
花了我一个上午的时间来解决这个错误,虽然我不确定 np.where 解决方案是否好。
我想用自定义指标训练 lgb 模型:f1_score
平均 weighted
。
我通过 here 浏览了 lightgbm 的高级示例,发现了自定义二进制错误函数的实现。我实现了与 return f1_score 类似的功能,如下所示。
def f1_metric(preds, train_data):
labels = train_data.get_label()
return 'f1', f1_score(labels, preds, average='weighted'), True
我尝试通过将 feval
参数作为 f1_metric
传递来训练模型,如下所示。
evals_results = {}
bst = lgb.train(params,
dtrain,
valid_sets= [dvalid],
valid_names=['valid'],
evals_result=evals_results,
num_boost_round=num_boost_round,
early_stopping_rounds=early_stopping_rounds,
verbose_eval=25,
feval=f1_metric)
然后我得到 ValueError: Found input variables with inconsistent numbers of samples:
正在将训练集而不是验证集传递给函数。
我如何配置才能通过验证集并且 f1_score 被 returned。?
文档有点混乱。在描述传递给 feval 的函数的签名时,他们将其参数称为 preds 和 train_data,这有点误导.
但以下似乎有效:
from sklearn.metrics import f1_score
def lgb_f1_score(y_hat, data):
y_true = data.get_label()
y_hat = np.round(y_hat) # scikits f1 doesn't like probabilities
return 'f1', f1_score(y_true, y_hat), True
evals_result = {}
clf = lgb.train(param, train_data, valid_sets=[val_data, train_data], valid_names=['val', 'train'], feval=lgb_f1_score, evals_result=evals_result)
lgb.plot_metric(evals_result, metric='f1')
要使用多个自定义指标,请像上面一样定义一个总体自定义指标函数,在其中计算所有指标和return一个元组列表。
编辑:固定代码,当然 F1 越大越好应该设置为 True。
关于托比的回答:
def lgb_f1_score(y_hat, data):
y_true = data.get_label()
y_hat = np.round(y_hat) # scikits f1 doesn't like probabilities
return 'f1', f1_score(y_true, y_hat), True
我建议将 y_hat 部分更改为:
y_hat = np.where(y_hat < 0.5, 0, 1)
原因: 我使用了 y_hat = np.round(y_hat) 并发现在训练期间 lightgbm 模型有时(非常不可能但仍然是一个变化)将我们的 y 预测视为多类而不是二进制。
我的推测: 有时 y 预测会小或大到足以舍入为负值或 2?我不确定,但是当我使用 np.where 更改代码时,错误消失了。
花了我一个上午的时间来解决这个错误,虽然我不确定 np.where 解决方案是否好。