lightgbm中的f1_score指标

时间:2018-06-19 14:42:57

标签: python machine-learning lightgbm

我想训练一个具有自定义指标的lgb模型:f1_score,平均值为weighted

我在here上浏览了lightgbm的高级示例,并发现了自定义二进制错误函数的实现。我实现了类似的功能来返回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 ??

2 个答案:

答案 0 :(得分:8)

文档有些混乱。在描述传递给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')

要使用多个自定义指标,请像上面定义一个整体自定义指标功能,在其中您可以计算所有指标并返回元组列表。

编辑:固定代码,当然F1越大越好,应将其设置为True。

答案 1 :(得分:0)

关于托比的答案:

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更改代码时,错误消失了。

虽然我不确定np.where解决方案是否很好,但还是花了一个早晨来弄清楚这个错误。