我得到了这个奇怪的错误:
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-score:
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:\Users\Michael\Miniconda3\envs\snowflakes\lib\site-packages\sklearn\metrics\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)
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。
答案 0 :(得分:58)
如评论中所述,y_true中的某些标签不会出现在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
在这种情况下不会显示警告。
答案 1 :(得分:3)
当我训练分类模型时,我也遇到了同样的问题。 导致此问题的原因是因为警告消息中所说的“在没有谓词的标签中”,在计算f1分数时将导致零除。 当我阅读sklearn.metrics.f1_score文档时,发现了另一种解决方案,有一条注释如下:
当真肯定+假肯定== 0时,精度是不确定的;当真阳性+假阴性== 0时,召回率是不确定的。在这种情况下,默认情况下,度量将设置为0,f分数也将设置为0,并且将引发UndefinedMetricWarning。可以使用zero_division修改此行为
zero_division
的默认值为"warn"
,可以将其设置为0
或1
以避免UndefinedMetricWarning
。
它对我有用;)哦,等等,当我使用zero_division
时,还有另一个问题,我的sklearn报告说,使用scikit-learn 0.21.3时没有这样的关键字参数。只需运行pip install scikit-learn -U
答案 2 :(得分:1)
如我所见,此错误在两种情况下发生
因此,请使用np.array(y_test)得分y_true或y_test.reset_index(drop = True)
希望这会有所帮助。
答案 3 :(得分:0)
已接受的答案已经很好地说明了警告发生的原因。如果您只想控制警告,则可以使用precision_recall_fscore_support
。它提供了(半官方)自变量warn_for
,该自变量可以用于使警告静音。
(_, _, f1, _) = metrics.precision_recall_fscore_support(y_test, y_pred,
average='weighted',
warn_for=tuple())
正如一些评论中已经提到的那样,请谨慎使用。
答案 4 :(得分:0)
或者,您可以使用以下代码行
from sklearn.metrics import f1_score
metrics.f1_score(y_test, y_pred, labels=np.unique(y_pred))
这应该删除您的警告,并为您提供想要的结果
答案 5 :(得分:0)
我最终遇到了同样的错误,但在阅读了@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)
答案 6 :(得分:-1)
正如错误消息所述,用于获取F分数的方法来自sklearn的“分类”部分 - 因此谈论“标签”。
你有回归问题吗? Sklearn在“特征选择”组下为回归提供了“F得分”方法:http://scikit-learn.org/stable/modules/generated/sklearn.feature_selection.f_regression.html
如果您确实遇到分类问题,@ Shovalt的答案对我来说似乎是正确的。