【问题标题】:Is there something already implemented in Python to calculate TP, TN, FP, and FN for multiclass confusion matrix?是否已经在 Python 中实现了计算多类混淆矩阵的 TP、TN、FP 和 FN 的东西?
【发布时间】:2017-09-27 14:55:06
【问题描述】:

Sklearn.metrics 具有用于获取分类指标的强大功能,尽管我认为缺少的是在给定预测和实际标签序列的情况下返回 TP、FN、FP 和 FN 计数的功能。甚至来自混淆矩阵。

我知道可以使用sklearn 获得混淆矩阵,但我需要实际的 TP、FN、FP 和 FN 计数(对于多标签分类 - 超过 2 个标签),并为每个类。

也就是说,我有下面的混淆矩阵和 3 个类。是否有一些包可用于从中获取每个类的计数?我找不到任何东西。

【问题讨论】:

    标签: python scikit-learn confusion-matrix


    【解决方案1】:

    Scikit-learn 可以计算和绘制多类混淆矩阵,请参阅文档 (Demo on a Jupiter notebook) 中的此示例:

    import itertools
    import numpy as np
    import matplotlib.pyplot as plt
    
    from sklearn import svm, datasets
    from sklearn.model_selection import train_test_split
    from sklearn.metrics import confusion_matrix
    
    # import some data to play with
    iris = datasets.load_iris()
    X = iris.data
    y = iris.target
    class_names = iris.target_names
    
    # Split the data into a training set and a test set
    X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)
    
    # Run classifier, using a model that is too regularized (C too low) to see
    # the impact on the results
    classifier = svm.SVC(kernel='linear', C=0.01)
    y_pred = classifier.fit(X_train, y_train).predict(X_test)
    
    
    def plot_confusion_matrix(cm, classes,
                              normalize=False,
                              title='Confusion matrix',
                              cmap=plt.cm.Blues):
        """
        This function prints and plots the confusion matrix.
        Normalization can be applied by setting `normalize=True`.
        """
        plt.imshow(cm, interpolation='nearest', cmap=cmap)
        plt.title(title)
        plt.colorbar()
        tick_marks = np.arange(len(classes))
        plt.xticks(tick_marks, classes, rotation=45)
        plt.yticks(tick_marks, classes)
    
        if normalize:
            cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]
            print("Normalized confusion matrix")
        else:
            print('Confusion matrix, without normalization')
    
        print(cm)
    
        thresh = cm.max() / 2.
        for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):
            plt.text(j, i, cm[i, j],
                     horizontalalignment="center",
                     color="white" if cm[i, j] > thresh else "black")
    
        plt.tight_layout()
        plt.ylabel('True label')
        plt.xlabel('Predicted label')
    
    # Compute confusion matrix
    cnf_matrix = confusion_matrix(y_test, y_pred)
    np.set_printoptions(precision=2)
    
    # Plot non-normalized confusion matrix
    plt.figure()
    plot_confusion_matrix(cnf_matrix, classes=class_names,
                          title='Confusion matrix, without normalization')
    
    # Plot normalized confusion matrix
    plt.figure()
    plot_confusion_matrix(cnf_matrix, classes=class_names, normalize=True,
                          title='Normalized confusion matrix')
    
    plt.show()
    

    结果(txt):

    Confusion matrix, without normalization
    [[13  0  0]
     [ 0 10  6]
     [ 0  0  9]]
    
    Normalized confusion matrix
    [[ 1.    0.    0.  ]
     [ 0.    0.62  0.38]
     [ 0.    0.    1.  ]]
    

    绘制结果:


    在下面的链接中查看此代码:
    DEMO ON A JUPYTER NOTEBOOK

    【讨论】:

      【解决方案2】:

      我最终自己实现了它,因为我没有找到任何东西。这是代码,以防其他人在将来查找此代码:

      def counts_from_confusion(confusion):
          """
          Obtain TP, FN FP, and TN for each class in the confusion matrix
          """
      
          counts_list = []
      
          # Iterate through classes and store the counts
          for i in range(confusion.shape[0]):
              tp = confusion[i, i]
      
              fn_mask = np.zeros(confusion.shape)
              fn_mask[i, :] = 1
              fn_mask[i, i] = 0
              fn = np.sum(np.multiply(confusion, fn_mask))
      
              fp_mask = np.zeros(confusion.shape)
              fp_mask[:, i] = 1
              fp_mask[i, i] = 0
              fp = np.sum(np.multiply(confusion, fp_mask))
      
              tn_mask = 1 - (fn_mask + fp_mask)
              tn_mask[i, i] = 0
              tn = np.sum(np.multiply(confusion, tn_mask))
      
              counts_list.append({'Class': i,
                                  'TP': tp,
                                  'FN': fn,
                                  'FP': fp,
                                  'TN': tn})
      
          return counts_list
      

      【讨论】:

        猜你喜欢
        • 2021-03-31
        • 2017-02-05
        • 2015-03-13
        • 1970-01-01
        • 2020-06-14
        • 2021-04-17
        • 1970-01-01
        • 2021-03-01
        • 2015-01-05
        相关资源
        最近更新 更多