Scikit学习错误消息'精确度和F分数定义不明确,并在标签中设置为0.0'

OAK*_*OAK 8 python classification scikit-learn

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

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)
Run Code Online (Sandbox Code Playgroud)

我正在使用带有CV k-fold 10的gridsearch.测试集和预测包含两个类,所以我不理解该消息.我正在为其他6个模型研究相同的数据集,训练/测试分裂,cv和随机种子,这些工作非常完美.数据被外部摄取到数据帧中,随机化并且种子是固定的.然后,朴素贝叶斯分类模型将该文件放在此代码片段之前的开头.

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))
Run Code Online (Sandbox Code Playgroud)

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

Ori*_*Ori 7

警告的含义

正如这里的其他答案所建议的那样,您会遇到F-Score由于精度定义而无法计算精度的情况(精度/召回率等于0)。在这种情况下,指标的分数值为0。

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

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

即使使用分层K折仍会发生

这有点棘手。分层K折可确保每个分组中每个类别的相同部分。但是,这不仅取决于实际的类。例如,精密的计算,如下所示:TP/predicted yes。如果由于某种原因,您使用No预测所有样本,则将具有predicted yes=0,这将导致不确定的精度(这可能导致undefined F-Score)。

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

我希望这回答了你的问题!


小智 5

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

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

import warnings
import sklearn.exceptions
warnings.filterwarnings("ignore", category=sklearn.exceptions.UndefinedMetricWarning)
Run Code Online (Sandbox Code Playgroud)