代码之家  ›  专栏  ›  技术社区  ›  Hitesh

如何从多类分类的混淆矩阵中提取假阳性、假阴性

  •  7
  • Hitesh  · 技术社区  · 8 年前

    我正在使用以下Keras代码对mnist数据进行分类。从…起 confusion_matrix 的命令 sklearn.metrics 我得到了混乱矩阵 TruePositive= sum(numpy.diag(cm1)) 命令我能够得到真正的积极。但我不知道如何得到真阴性、假阳性、假阴性。我从中读取解决方案 here 但用户的评论让我困惑。请帮助编写代码以获取参数。

    from sklearn.metrics import confusion_matrix
    import keras
    from keras.datasets import mnist
    from keras.models import Sequential
    from keras.layers import Dense, Dropout, Flatten
    from keras.layers import Conv2D, MaxPooling2D
    from keras import backend as K
    import numpy as np
    (x_train, y_train), (x_test, y_test) = mnist.load_data()
    batch_size = 128
    num_classes = 10
    epochs = 1
    img_rows, img_cols = 28, 28
    y_test1=y_test
    
    if K.image_data_format() == 'channels_first':
        x_train = x_train.reshape(x_train.shape[0], 1, img_rows, img_cols)
        x_test = x_test.reshape(x_test.shape[0], 1, img_rows, img_cols)
        input_shape = (1, img_rows, img_cols)
    else:
        x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1)
        x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1)
        input_shape = (img_rows, img_cols, 1)
    
    x_train = x_train.astype('float32')
    x_test = x_test.astype('float32')
    x_train /= 255
    x_test /= 255
    
    y_train = keras.utils.to_categorical(y_train, num_classes)
    y_test = keras.utils.to_categorical(y_test, num_classes)
    
    model = Sequential()
    model.add(Conv2D(32, kernel_size=(3, 3),
                     activation='relu',
                     input_shape=input_shape))
    model.add(Conv2D(64, (3, 3), activation='relu'))
    model.add(MaxPooling2D(pool_size=(2, 2)))
    model.add(Dropout(0.25))
    model.add(Flatten())
    #model.add(GlobalAveragePooling2D())
    #model.add(GlobalMaxPooling2D())
    model.add(Dense(128, activation='relu'))
    model.add(Dropout(0.5))
    model.add(Dense(num_classes, activation='softmax'))
    
    model.compile(loss=keras.losses.binary_crossentropy,
                  optimizer=keras.optimizers.Adadelta(),
                  metrics=['accuracy'])
    
    
    
    model.fit(x_train, y_train,
              batch_size=batch_size,
              epochs=epochs,
              verbose=1,
              validation_data=(x_test, y_test))
    
    pre_cls=model.predict_classes(x_test)
    
    cm1 = confusion_matrix(y_test1,pre_cls)
    print('Confusion Matrix : \n', cm1)
    
    TruePositive= sum(np.diag(cm1))
    
    1 回复  |  直到 8 年前
        1
  •  11
  •   desertnaut SKZI    8 年前

    首先,代码中有遗漏-为了运行,我需要添加以下命令:

    import keras
    (x_train, y_train), (x_test, y_test) = mnist.load_data()
    

    完成后,给出了混淆矩阵 cm1 :

    array([[ 965,    0,    1,    0,    0,    2,    6,    1,    5,    0],
           [   0, 1113,    4,    2,    0,    0,    3,    0,   13,    0],
           [   8,    0,  963,   14,    5,    1,    7,    8,   21,    5],
           [   0,    0,    3,  978,    0,    7,    0,    6,   12,    4],
           [   1,    0,    4,    0,  922,    0,    9,    3,    3,   40],
           [   4,    1,    1,   27,    0,  824,    6,    1,   20,    8],
           [  11,    3,    1,    1,    5,    6,  925,    0,    6,    0],
           [   2,    6,   17,    8,    2,    0,    1,  961,    2,   29],
           [   5,    1,    2,   13,    4,    6,    2,    6,  929,    6],
           [   6,    5,    0,    7,    5,    6,    1,    6,   10,  963]])
    

    下面是您如何获得请求的TP、FP、FN、TN 每类 :

    真正的积极因素只是对角线元素:

    TruePositive = np.diag(cm1)
    TruePositive
    # array([ 965, 1113,  963,  978,  922,  824,  925,  961,  929,  963])
    

    误报是各列的总和减去对角线元素:

    FalsePositive = []
    for i in range(num_classes):
        FalsePositive.append(sum(cm1[:,i]) - cm1[i,i])
    FalsePositive
    # [37, 16, 33, 72, 21, 28, 35, 31, 92, 92]
    

    类似地,假阴性是各行的总和减去对角线元素:

    FalseNegative = []
    for i in range(num_classes):
        FalseNegative.append(sum(cm1[i,:]) - cm1[i,i])
    FalseNegative
    # [15, 22, 69, 32, 60, 68, 33, 67, 45, 46]
    

    现在,真正的负面因素有点棘手;让我们首先思考真正的否定到底意味着什么,比如说阶级 0 :表示所有已正确识别为 不存在 0 . 因此,本质上我们应该做的是删除相应的行&列,然后总结所有剩余元素:

    TrueNegative = []
    for i in range(num_classes):
        temp = np.delete(cm1, i, 0)   # delete ith row
        temp = np.delete(temp, i, 1)  # delete ith column
        TrueNegative.append(sum(sum(temp)))
    TrueNegative
    # [8998, 8871, 9004, 8950, 9057, 9148, 9040, 9008, 8979, 8945]
    

    让我们做一次理智检查:对于 每个班级 ,TP、FP、FN和TN的总和必须等于我们测试集的大小(这里是10000):让我们确认事实确实如此:

    l = len(y_test)
    for i in range(num_classes):
        print(TruePositive[i] + FalsePositive[i] + FalseNegative[i] + TrueNegative[i] == l)
    

    结果是

    True
    True
    True
    True
    True
    True
    True
    True
    True
    True