UndefinedMetricWarning:F 分数定义不明确,在没有预测样本的标签中被设置为 0.0

2024-12-26 08:43:00
admin
原创
164
摘要:问题描述:我收到这个奇怪的错误:classification.py:1113: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples. 'precision...

问题描述:

我收到这个奇怪的错误:

classification.py:1113: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.
'precision', 'predicted', average, warn_for)`

但是第一次运行时它也会打印 f 分数:

metrics.f1_score(y_test, y_pred, average='weighted')

第二次运行时,它提供了正确的分数。这是为什么?

>>> y_pred = test.predict(X_test)
>>> y_test
array([ 1, 10, 35,  9,  7, 29, 26,  3,  8, 23, 39, 11, 20,  2,  5, 23, 28,
       30, 32, 18,  5, 34,  4, 25, 12, 24, 13, 21, 38, 19, 33, 33, 16, 20,
       18, 27, 39, 20, 37, 17, 31, 29, 36,  7,  6, 24, 37, 22, 30,  0, 22,
       11, 35, 30, 31, 14, 32, 21, 34, 38,  5, 11, 10,  6,  1, 14, 12, 36,
       25,  8, 30,  3, 12,  7,  4, 10, 15, 12, 34, 25, 26, 29, 14, 37, 23,
       12, 19, 19,  3,  2, 31, 30, 11,  2, 24, 19, 27, 22, 13,  6, 18, 20,
        6, 34, 33,  2, 37, 17, 30, 24,  2, 36,  9, 36, 19, 33, 35,  0,  4,
        1])
>>> y_pred
array([ 1, 10, 35,  7,  7, 29, 26,  3,  8, 23, 39, 11, 20,  4,  5, 23, 28,
       30, 32, 18,  5, 39,  4, 25,  0, 24, 13, 21, 38, 19, 33, 33, 16, 20,
       18, 27, 39, 20, 37, 17, 31, 29, 36,  7,  6, 24, 37, 22, 30,  0, 22,
       11, 35, 30, 31, 14, 32, 21, 34, 38,  5, 11, 10,  6,  1, 14, 30, 36,
       25,  8, 30,  3, 12,  7,  4, 10, 15, 12,  4, 22, 26, 29, 14, 37, 23,
       12, 19, 19,  3, 25, 31, 30, 11, 25, 24, 19, 27, 22, 13,  6, 18, 20,
        6, 39, 33,  9, 37, 17, 30, 24,  9, 36, 39, 36, 19, 33, 35,  0,  4,
        1])
>>> metrics.f1_score(y_test, y_pred, average='weighted')
C:UsersMichaelMiniconda3envssnowflakeslibsite-packagessklearnmetricsclassification.py:1113: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.
  'precision', 'predicted', average, warn_for)
0.87282051282051276
>>> metrics.f1_score(y_test, y_pred, average='weighted')
0.87282051282051276
>>> metrics.f1_score(y_test, y_pred, average='weighted')
0.87282051282051276

另外,为什么会有尾随'precision', 'predicted', average, warn_for)错误消息?没有左括号,那么为什么它以右括号结尾?我在 Windows 10 上的 conda 环境中使用 Python 3.6.0 运行 sklearn 0.18.1。

我也看了这里,不知道是不是同样的错误。这篇SO 帖子也没有解决方案。


解决方案 1:

正如评论中提到的,中的一些标签y_test没有出现在中y_pred。具体来说,在这种情况下,标签“2”从未被预测到:

>>> set(y_test) - set(y_pred)
{2}

这意味着没有要为该标签计算的 F 分数,因此此案例的 F 分数被视为 0.0。由于您要求计算分数的平均值,因此您必须考虑到计算中包含了 0 分,这就是 scikit-learn 向您显示该警告的原因。

这让我不会再看到错误。正如我所提到的,这是一个警告,它与 Python 中的错误处理方式不同。大多数环境中的默认行为是仅显示一次特定警告。此行为可以更改:

import warnings
warnings.filterwarnings('always')  # "error", "ignore", "always", "default", "module" or "once"

如果在导入其他模块之前设置此项,则每次运行代码时都会看到警告。

除了设置之外,没有其他方法可以避免第一次看到此警告warnings.filterwarnings('ignore')。您可以做的是决定您对未预测的标签分数不感兴趣,然后明确指定您感兴趣的标签至少被预测过一次的标签):

>>> metrics.f1_score(y_test, y_pred, average='weighted', labels=np.unique(y_pred))
0.91076923076923078

警告将消失。

解决方案 2:

我在训练分类模型时也遇到了同样的问题。导致此问题的原因正如警告消息所述“在无预测样本的标签中”,它将在计算 f1-score 时导致零除。我在阅读sklearn.metrics.f1_score文档时找到了另一个解决方案,其中有一条注释如下:

当真阳性 + 假阳性 == 0 时,精度未定义;当真阳性 + 假阴性 == 0 时,召回率未定义。在这种情况下,默认情况下,指标将设置为 0,f-score 也将设置为 0,并且会引发 UndefinedMetricWarning。可以使用 zero_division 修改此行为

默认值zero_division"warn",您可以将其设置为01以避免UndefinedMetricWarning。它对我有用 ;) 哦,等等,当我使用 时还有另一个问题zero_division,我的 sklearn 报告说使用 scikit-learn 0.21.3 没有这样的关键字参数。只需通过运行将 sklearn 更新到最新版本即可pip install scikit-learn -U

解决方案 3:

我最终遇到了同样的错误,但在阅读了@Shovalt 的回答后,我意识到我的测试/训练分割相当低。我一开始有一个很大的数据集,但把它分割了,其中一个组相当小。通过增加样本量,这个警告就消失了,我得到了我的 f1 分数。从这个

from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.1, random_state=0)

对此

from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)

解决方案 4:

我注意到这个错误在两种情况下发生,

  1. 如果您已使用 train_test_split() 分割数据,则必须确保重置数据的索引(特别是使用 pandas 系列对象时):y_train、y_test 索引应重置。问题是当您尝试使用 sklearn.metrics 中的一个分数(例如 precision_score)时,这将尝试匹配您从 train_test_split() 获得的 y_test 的打乱索引。

因此,要么使用np.array(y_test) for y_true in scores,要么y_test.reset_index(drop=True)

  1. 然后,如果您预测的“真阳性”为 0(用于精度、召回率和 f1_scores),您仍然会遇到此错误。您可以使用 Confusion_matrix 将其可视化。如果分类是多标签的,并且您设置了参数:average='weighted'/micro/macro,只要矩阵中的对角线不为 0,您就会得到答案

希望这有帮助。

解决方案 5:

接受的答案已经很好地解释了为什么会出现警告。如果您只是想控制警告,可以使用precision_recall_fscore_support。它提供了一个(半官方)论点,warn_for可用于静音警告。

(_, _, f1, _) = metrics.precision_recall_fscore_support(y_test, y_pred,
                                                        average='weighted', 
                                                        warn_for=tuple())

正如一些评论中所提到的,请谨慎使用。

解决方案 6:

按照Shovalt 的建议,我检查了多标签情况下真值集和预测之间的差异,但这并没有帮助我解决问题。

因此,我搜索了sklearn.metrics.precision_recall_fscore_support源代码(由 f1_score 调用)以检查其工作原理。

触发警告的代码如下:

precision = _prf_divide(
    tp_sum, pred_sum, "precision", "predicted", average, warn_for, zero_division
)
recall = _prf_divide(
    tp_sum, true_sum, "recall", "true", average, warn_for, zero_division
)
  • tpsum对应于 TP (True Positives)

  • pred_sum对应于 TP + FP(假阳性)

  • true_sum对应于 TP + FN(假阴性)

  • 第一个参数_prf_divide是除法的分子

  • 的第二个参数_prf_divide是除法的分母

一旦 pred_sum 或 true_sum 等于 0,就会触发警告,因为不允许除以 0。

为了获取这些不同的值,请使用sklearn.metrics.multilabel_confusion_matrix。结果是一个三维数组。您可以将其视为 2x2 矩阵列表,其中每个矩阵代表每个标签的真阴性 (TN)、假阳性 (FP)、假阴性 (FP) 和真阳性 (TP),结构如下:

multilabel_confusion_matrix 输出

就我而言,问题来自于模型由于训练不佳或缺乏样本而无法预测某些标签。

解决方案 7:

正如错误消息所述,获取 F 分数的方法来自 sklearn 的“分类”部分 - 因此谈论“标签”。

您有回归问题吗?Sklearn 在“特征选择”组下为回归提供了一种“F 分数”方法:http ://scikit-learn.org/stable/modules/generated/sklearn.feature_selection.f_regression.html

如果您确实存在分类问题,@Shovalt 的答案对我来说似乎是正确的。

解决方案 8:

小心 Seqeval 的单字母标签!

使用 Seqeval pakcage 计算指标时,我遇到了类似的问题。事实证明,当我为 NER 使用单字符标签(如“U”或“0”)时,脚本seqeval/metrics/sequence_labeling.py会在处理过程中截断一个字母,因此用于比较的标签为空。将标签更改为“UU”和“00”解决了该问题。

解决方案 9:

您遇到的错误是由于 used_actions 中的某些标签在 y_true 列表中没有任何真实样本。在计算这些标签的召回率(或其他指标)时,它变得不确定,因为召回率计算中的分母(该标签的真实样本数量)为零。

要解决此问题,您可以使用分类报告函数中的 zero_division 参数来控制此行为。将 zero_division 设置为 1 或 0 将通过明确定义发生零除时要执行的操作来避免警告。

class_report = classification_report(y_true, y_pred, labels=used_actions, zero_division=1)```

解决方案 10:

此命令对我有用

sklearn.metrics.f1_score(y_true, y_pred,average='weighted',zero_division=0)
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1579  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1355  
  信创产品在政府采购中的占比分析随着信息技术的飞速发展以及国家对信息安全重视程度的不断提高,信创产业应运而生并迅速崛起。信创,即信息技术应用创新,旨在实现信息技术领域的自主可控,减少对国外技术的依赖,保障国家信息安全。政府采购作为推动信创产业发展的重要力量,其对信创产品的采购占比情况备受关注。这不仅关系到信创产业的发展前...
信创和国产化的区别   8  
  信创,即信息技术应用创新产业,旨在实现信息技术领域的自主可控,摆脱对国外技术的依赖。近年来,国货国用信创发展势头迅猛,在诸多领域取得了显著成果。这一发展趋势对科技创新产生了深远的推动作用,不仅提升了我国在信息技术领域的自主创新能力,还为经济社会的数字化转型提供了坚实支撑。信创推动核心技术突破信创产业的发展促使企业和科研...
信创工作   9  
  信创技术,即信息技术应用创新产业,旨在实现信息技术领域的自主可控与安全可靠。近年来,信创技术发展迅猛,对中小企业产生了深远的影响,带来了诸多不可忽视的价值。在数字化转型的浪潮中,中小企业面临着激烈的市场竞争和复杂多变的环境,信创技术的出现为它们提供了新的发展机遇和支撑。信创技术对中小企业的影响技术架构变革信创技术促使中...
信创国产化   8  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用