我正在研究二元分类模型,分类器是天真的贝叶斯。我有一个几乎平衡的数据集,但是当我预测时,我收到以下错误消息:
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个模型训练/测试分裂,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))
我被迫'通过python改变系列的形状,也许这就是罪魁祸首?
答案 0 :(得分:4)
正如aadel评论的那样,当没有数据点被归类为正数时,精度除以零,因为它被定义为TP /(TP + FP)(即真阳性 / true和误报)。然后,库将精度设置为0,但发出警告,因为实际上该值未定义。 F1取决于精度,因此也没有定义。
一旦您意识到这一点,您可以选择禁用警告:
import warnings
import sklearn.exceptions
warnings.filterwarnings("ignore", category=sklearn.exceptions.UndefinedMetricWarning)
答案 1 :(得分:2)
警告的含义
正如这里的其他答案所建议的,您遇到一种情况,由于定义{precision / recall等于0),因此无法计算精度F-Score
。在这种情况下,指标的得分值为0。
测试数据包含所有标签,为什么仍会发生这种情况?
好吧,您使用的是K-Fold
(在您的情况下尤其是k=10
),这意味着一个特定的拆分可能包含0个一类的样本
即使使用分层K折叠,仍然会发生
这有点棘手。分层K折可确保每个分组中每个类别的相同部分。但是,这不仅取决于实际的类。
例如, Precision 的计算方式如下:TP/predicted yes
。如果由于某种原因而用 No 预测所有样本,则将得到predicted yes=0
,这将导致不确定的精度(这可能导致不确定的F-Score
)。
这听起来像是一个极端的情况,但考虑到以下事实:在网格搜索中,您可能正在搜索很多不同的组合,其中某些组合可能会完全消失,从而导致这种情况。
我希望这能回答您的问题!