以lightgbm为单位的f1_分数度量

2024-06-07 04:13:21 发布

您现在位置:Python中文网/ 问答频道 /正文

我想训练一个具有自定义度量的lgb模型:使用f1_score平均值weighted

我浏览了here上lightgbm的高级示例,发现了自定义二进制错误函数的实现。我实现了一个类似的函数来返回f1的分数,如下所示。

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_分数。?


Tags: 函数模型datalabelstrainmetric分数f1
2条回答

关于托比的回答:

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 = np.where(y_hat < 0.5, 0, 1)  

原因: 我使用了y庠hat=np.round(y庠hat)并得出结论,在训练期间,lightgbm模型有时(非常不可能,但仍然是一个变化)会将y预测视为多类预测,而不是二进制预测。

我的推测是: 有时,y预测值会很小或更高,足以舍入到负值或2?我不确定,但是当我使用np.where更改代码时,错误就消失了。

花了我一上午的时间来计算这个bug,虽然我不确定np.where解决方案是否好。

文件有点混乱。在描述传递给feval的函数的签名时,它们调用其参数predstrain_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')

要使用多个自定义度量,请像上面一样定义一个总体自定义度量函数,在该函数中计算所有度量并返回元组列表。

编辑:固定代码,当然用F1大是比较好的应该设置为真。

相关问题 更多 >