【问题标题】:White lines in confusion matrix?混淆矩阵中的白线?
【发布时间】:2015-01-07 03:15:07
【问题描述】:

我有一个关于 numpy 矩阵的非常普遍的问题:我尝试根据线条对结果进行归一化,但我得到了一些奇怪的白线。这是因为在除法的某个地方卡住了一些零吗?

代码如下:

import numpy as np
from matplotlib.pylab import *

def confusion_matrix(results,tagset):
    # results : list of tuples (predicted, true)
    # tagset  : list of tags
    np.seterr(divide='ignore', invalid='ignore')
    mat     = np.zeros((len(tagset),len(tagset)))
    percent = [0,0]
    for guessed,real in results :
        mat[tagset.index(guessed),tagset.index(real)] +=1
        if guessed == real :
            percent[0] += 1
            percent[1] += 1
        else :
            percent[1] += 1
    mat /=  mat.sum(axis=1)[:,np.newaxis]
    matshow(mat,fignum=100)
    xticks(arange(len(tagset)),tagset,rotation =90,size='x-small')
    yticks(arange(len(tagset)),tagset,size='x-small')
    colorbar()
    show()
    #print "\n".join(["\t".join([""]+tagset)]+["\t".join([tagset[i]]+[str(x) for x in 
                (mat[i,:])]) for i in xrange(mat.shape[1])])
    return (percent[0] / float(percent[1]))*100

感谢您的宝贵时间! (希望答案不要太明显)

【问题讨论】:

  • 一个示例图像可能会有所帮助(什么是“奇怪的白线”)。为了使调试更容易,您可能会尝试将代码分成两部分:一部分创建矩阵,另一部分绘制矩阵。然后在 ipython (或其他)中运行第一个函数来获取矩阵。检查整行的数据中没有零或 NaN,并且它看起来与您预期的一样。

标签: python numpy confusion-matrix


【解决方案1】:

简而言之,您有一些标签,其中特定标签从未被猜到。因为您正在通过猜测标签的次数进行标准化,所以您有一行0/0,它产生np.nan。默认情况下,matplotlib 的颜色条会将NaN 设置为没有填充颜色,从而导致轴的背景显示出来(默认为白色)。

这里有一个简单的例子来重现您当前的问题:

import numpy as np
import matplotlib.pyplot as plt

def main():
    tags = ['A', 'B', 'C', 'D']
    results = [('A', 'A'), ('B', 'B'), ('C', 'C'), ('A', 'D'), ('C', 'A'),
               ('B', 'B'), ('C', 'B')]
    matrix = confusion_matrix(results, tags)
    plot(matrix, tags)
    plt.show()

def confusion_matrix(results, tagset):
    output = np.zeros((len(tagset), len(tagset)), dtype=float)
    for guessed, real in results:
        output[tagset.index(guessed), tagset.index(real)] += 1
    return output / output.sum(axis=1)[:, None]

def plot(matrix, tags):
    fig, ax = plt.subplots()
    im = ax.matshow(matrix)
    cb = fig.colorbar(im)
    cb.set_label('Percentage Correct')

    ticks = range(len(tags))
    ax.set(xlabel='True Label', ylabel='Predicted Label',
           xticks=ticks, xticklabels=tags, yticks=ticks, yticklabels=tags)
    ax.xaxis.set(label_position='top')
    return fig

main()

如果我们看一下混淆矩阵:

array([[ 0.5  ,  0.   ,  0.   ,  0.5  ],
       [ 0.   ,  1.   ,  0.   ,  0.   ],
       [ 0.333,  0.333,  0.333,  0.   ],
       [   nan,    nan,    nan,    nan]])

如果您想避免标签永远猜不到的问题,您可以执行类似的操作:

def confusion_matrix(results, tagset):
    output = np.zeros((len(tagset), len(tagset)), dtype=float)
    for guessed, real in results:
        output[tagset.index(guessed), tagset.index(real)] += 1
    num_guessed = output.sum(axis=1)[:, None]
    num_guessed[num_guessed == 0] = 1
    return output / num_guessed

哪个产量(其他一切都相同):

【讨论】:

    【解决方案2】:

    不直接回答您的问题,但使用scikit-learn 很容易做到这一点:

    from sklearn.metrics import confusion_matrix
    import matplotlib.pyplot as plt
    
    y_test=[2, 1, 0, 2, 0, 2, 0, 1, 1, 1, 2, 1, 1, 1, 1, 0, 1, 1, 0, 0, 2, 1, 0, 0, 2, 0, 0, 1, 1, 0, 2, 1, 0, 2, 2, 1, 0, 1]
    y_pred = [2, 1, 0, 2, 0, 2, 0, 1, 1, 1, 2, 1, 1, 1, 1, 0, 1, 1, 0, 0, 2, 1, 0, 0, 2, 0, 0, 1, 1, 0, 2, 1, 0, 2, 2, 1, 0, 2]
    
    cm = confusion_matrix(y_test, y_pred)
    print(cm)
    
    # Plot confusion matrix
    plt.matshow(cm)
    plt.title('Confusion matrix')
    plt.colorbar()    plt.ylabel('True label')
    plt.xlabel('Predicted label')
    plt.show()
    

    输出:

    [[13  0  0]
     [ 0 15  1]
     [ 0  0  9]]
    

    【讨论】:

    • 哦,好的。非常感谢。好吧,如果我跳过规范化部分,我的工作......所以如果我想用你的代码规范化矩阵,我需要在之前(在列表中)做,对吧?我要检查 scikit 但我想自己实现它......
    猜你喜欢
    • 2018-12-26
    • 1970-01-01
    • 2020-09-16
    • 2016-01-15
    • 2014-07-09
    • 2015-03-09
    • 2018-01-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多