关于python:Scikit学习错误消息’精度和F分数定义不正确并在标签中设置为0.0′

Scikit learn Error Message 'Precision and F-score are ill-defined and being set to 0.0 in labels'

本问题已经有最佳答案,请猛点这里访问。

我正在研究二进制分类模型,分类器是朴素贝叶斯。我有一个几乎平衡的数据集,但是当我预测时会收到以下错误消息:

1
2
UndefinedMetricWarning: Precision and F-score are ill-defined and being set to 0.0 in labels with no predicted samples.
  'precision', 'predicted', average, warn_for)

我正在使用CV k-fold 10的gridsearch。测试集和预测包含这两个类,因此我不理解该消息。我正在使用相同的数据集,对其他6个模型进行训练/测试拆分,简历和随机种子,并且这些模型运行完美。数据从外部吸收到数据帧中,随机化并固定种子。然后,朴素的贝叶斯分类模型在此代码段之前的开头对文件进行分类。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
X_train, X_test, y_train, y_test, len_train, len_test = \\
     train_test_split(data['X'], data['y'], data['len'], test_size=0.4)
pipeline = Pipeline([
    ('classifier', MultinomialNB())
])

cv=StratifiedKFold(len_train, n_folds=10)

len_train = len_train.reshape(-1,1)
len_test = len_test.reshape(-1,1)

params = [
  {'classifier__alpha': [0, 0.0001, 0.001, 0.01]}

]

grid = GridSearchCV(
    pipeline,
    param_grid=params,
    refit=True,  
    n_jobs=-1,
    scoring='accuracy',
    cv=cv,
)

nb_fit = grid.fit(len_train, y_train)

preds = nb_fit.predict(len_test)

print(confusion_matrix(y_test, preds, labels=['1','0']))
print(classification_report(y_test, preds))

我被python"强迫"改变了系列的形状,也许是罪魁祸首?


警告的含义

如此处其他答案所示,您遇到一种情况,由于定义F-Score,精度F-Score无法被计算(精度/召回率等于0)。在这种情况下,该指标的分数值为0。

测试数据包含所有标签,为什么仍会发生这种情况?

好吧,您使用的是K-Fold(在您的情况下为k=10),这意味着一个特定的拆分可能包含0个一类的样本

即使使用分层K折

,仍会发生

这有点棘手。分层K折可确保每个分组中每个班级的相同部分。但是,这不仅取决于实际的类。
例如,Precision的计算方式如下:TP/predicted yes。如果由于某种原因,您预测所有样本都为"否",则将得到predicted yes=0,这将导致不确定的精度(这可能导致不确定的F-Score)。

这听起来像是一个极端的情况,但考虑到以下事实:在网格搜索中,您可能正在搜索很多不同的组合,其中某些组合可能会完全消失,从而导致这种情况。

我希望这能回答您的问题!


正如aadel所评论的那样,当没有数据点被分类为正数时,精度除以零,因为它被定义为TP /(TP FP)(即真正数/真正数和假正数)。然后,该库将precision设置为0,但是会发出警告,因为该值实际上是未定义的。 F1取决于精度,因此也未定义。

一旦意识到这一点,您可以选择通过以下方式禁用警告:

1
2
3
import warnings
import sklearn.exceptions
warnings.filterwarnings("ignore", category=sklearn.exceptions.UndefinedMetricWarning)