使用precision_recall_curve 计算最大f1 分数?

Posted

技术标签:

【中文标题】使用precision_recall_curve 计算最大f1 分数?【英文标题】:compute maximum f1 score using precision_recall_curve? 【发布时间】:2019-11-25 09:43:54 【问题描述】:

对于一个简单的二元分类问题,我想找出什么阈值设置使 f1 分数最大化,即精度和召回率的调和平均值。 scikit learn 中是否有任何内置功能可以做到这一点?现在,我只是在打电话

precision, recall, thresholds = precision_recall_curve(y_test, y_test_predicted_probas)

然后,我可以使用数组三元组中每个索引处的信息计算 f1 分数:

curr_f1 = compute_f1(precision[index], recall[index])

有没有更好的方法来做到这一点,或者这就是图书馆的预期用途?谢谢。

【问题讨论】:

请注意,如果有任何改变,我正在使用带有二进制逻辑输出的 XGBoost 分类器 【参考方案1】:

有时precision_recall_curve 会选择一些对于数据来说太高的阈值,因此您最终会得到precisionrecall 都为零的点。在计算 F1 分数时,这可能会导致 nans。为确保输出正确,请使用np.divide 仅在分母不为零的地方进行除法:

precision, recall, thresholds = precision_recall_curve(y_test, y_test_predicted_probas)
numerator = 2 * recall * precision
denom = recall + precision
f1_scores = np.divide(numerator, denom, out=np.zeros_like(denom), where=(denom!=0))
max_f1 = np.max(f1_scores)
max_f1_thresh = thresholds[np.argmax(f1_scores)]

【讨论】:

【参考方案2】:

计算精度、召回率和阈值分数后,您将获得 NumPy 数组。 只需使用 NumPy 函数找到最大化 F1-Score 的阈值:

f1_scores = 2*recall*precision/(recall+precision)
print('Best threshold: ', thresholds[np.argmax(f1_scores)])
print('Best F1-Score: ', np.max(f1_scores))

【讨论】:

如果我们关心“加权 f1 分数”怎么办?考虑不平衡的类

以上是关于使用precision_recall_curve 计算最大f1 分数?的主要内容,如果未能解决你的问题,请参考以下文章

输入到precision_recall_curve - predict 或 predict_proba 输出?

Python Scikit - 调用 sklearn.metrics.precision_recall_curve 时输入形状错误

在scikit的precision_recall_curve中,为啥threshold与recall和precision的维度不同?

如何为scikit学习随机森林模型设置阈值

sklearn如何在精确召回曲线中选择阈值步骤?

测试使用