分类时,为什么对于相同的测试数据会得到不同的精度?

时间:2019-07-10 09:52:58

标签: machine-learning classification precision

我正在测试决策树分类器上带有两个标签“ A”和“ B”的数据集。我无意间发现,该模型在相同的测试数据上获得了不同的精度结果。我想知道为什么。

这是我的工作,我训练模型并在

上对其进行测试
1. the testing set, 
2. the data only labelled 'A' in the testing set, 
3. and the data only labelled 'B'.

这就是我得到的:

  1. 用于测试数据集

         precision    recall  f1-score   support
    A       0.94      0.95      0.95     25258
    B       0.27      0.22      0.24      1963
    
  2. 对于仅在测试数据集中标记为“ A”的数据

        precision    recall  f1-score   support
    
    A       1.00      0.95      0.98     25258
    B       0.00      0.00      0.00         0
    
  3. 对于仅在测试数据集中标记为“ B”的数据

        precision    recall  f1-score   support
    
    A       0.00      0.00      0.00         0
    B       1.00      0.22      0.36      1963
    

训练数据集和模型相同,第2次和第3次测试中的数据也与第1次中的数据相同。为什么'A'和'B'的精度差异如此大?该模型的真正精度是多少?非常感谢。

1 个答案:

答案 0 :(得分:0)

您听起来很困惑,而且根本不清楚为什么您对度量标准感兴趣,因为您已经完全从评估集中删除了两个标签之一。

让我们用一些可复制的虚拟数据来探讨这个问题:

from sklearn.metrics import classification_report
import numpy as np
y_true = np.array([0, 1, 0, 1, 1, 0, 0])
y_pred = np.array([0, 0, 1, 1, 0, 0, 1])
target_names = ['A', 'B']

print(classification_report(y_true, y_pred, target_names=target_names))

结果:

             precision    recall  f1-score   support

          A       0.50      0.50      0.50         4
          B       0.33      0.33      0.33         3

avg / total       0.43      0.43      0.43         7

现在,让我们在y_true中仅保留A类:

indA = np.where(y_true==0)
print(indA)
print(y_true[indA])
print(y_pred[indA])

结果:

(array([0, 2, 5, 6], dtype=int64),)
[0 0 0 0] 
[0 1 0 1]

现在,这是scikit-learn documentation中对精度的定义:

  

精度是比率tp / (tp + fp),其中tp是真实肯定的数目,fp是错误肯定的数目。从直觉上讲,精度是分类器不将负样本标记为正的能力。

对于A类,真正(tp)是真实类为A(在我们的情况下为0)的情况,而我们确实预测到A(0 );从上方可以明显看出tp=2

棘手的部分是误报(fp):在这些情况下,我们预测了A(0),而真实标签是B(1)。但是显然在这里我们不能遇到任何这样的情况,因为我们(有意地)从y_true中删除了所有的B(为什么我们想做这样的事情?我不知道不知道,这根本没有任何意义);因此,fp=0在此(奇怪)设置中。因此,我们对A类的精度为tp / (tp+0) = tp/tp = 1

分类报告给出的结果完全相同:

print(classification_report(y_true[indA], y_pred[indA], target_names=target_names))
# result:

             precision    recall  f1-score   support

          A       1.00      0.50      0.67         4
          B       0.00      0.00      0.00         0

avg / total       1.00      0.50      0.67         4

显然B的情况是相同的。

  

为什么在情况1(对于A和B而言)中精度都不为1?数据是一样的

不,它们很明显不相同-基本事实已更改!

底线:在计算精度等之前从y_true中删除类。完全没有意义(即,在情况2和情况3中报告的结果不存在)任何实际用途);但是,由于您出于任何原因决定这样做,因此您报告的结果完全符合预期。