2015-01-06 7 views
1

У меня довольно общий вопрос о матрицах 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 

Спасибо за ваше время! (Я надеюсь, что ответ не слишком очевидна)

+4

Пример изображения может помочь (что такое "странные белые линии"). Чтобы облегчить отладку, вы можете попытаться разделить свой код на две части: одну, которая создает матрицу, и матрицу. Затем в ipython (или другом) запустите первую функцию для получения матрицы. Убедитесь, что в данных нет нулей или NaN для всей строки и что она выглядит так, как вы ожидаете. – daveydave400

ответ

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() 

enter image description here

И если мы посмотрим на матрицы неточностей:

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 

Который дает (все остальное идентично):

enter image description here

+0

Спасибо, он работает сейчас! Я думал, что Нэн относился к нулю ... –

1

Не прямо отвечая на ваш вопрос, но это очень легко сделать с 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]] 

enter image description here

+0

О, хорошо. Большое спасибо. Ну, мои работы, если я пропущу часть нормализации ... Итак, если я хочу нормализовать матрицу с вашим кодом, мне нужно сделать это раньше (в списках), правильно? Я собираюсь проверить scikit, но я хотел реализовать его сам ... –