Построение путаницы из данных без склеарна - PullRequest
1 голос
/ 13 апреля 2020

Я пытаюсь создать путаницу без использования библиотеки sklearn. У меня проблемы с правильным формированием матрицы путаницы. Вот мой код:

def comp_confmat():
    currentDataClass = [1,3,3,2,5,5,3,2,1,4,3,2,1,1,2]    
    predictedClass = [1,2,3,4,2,3,3,2,1,2,3,1,5,1,1]
    cm = []
    classes = int(max(currentDataClass) - min(currentDataClass)) + 1 #find number of classes

    for c1 in range(1,classes+1):#for every true class
        counts = []
        for c2 in range(1,classes+1):#for every predicted class
            count = 0
            for p in range(len(currentDataClass)):
                if currentDataClass[p] == predictedClass[p]:
                    count += 1
            counts.append(count)
        cm.append(counts)
    print(np.reshape(cm,(classes,classes)))

Однако это возвращает:

[[7 7 7 7 7]
[7 7 7 7 7]
[7 7 7 7 7]
[7 7 7 7 7]
[7 7 7 7 7]]

Но я не понимаю, почему каждая итерация приводит к 7, когда я сбрасываю счетчик каждый раз, и он проходит по циклу разные значения?

Вот что я должен получить (используя функцию sklearn confusion_matrix):

[[3 0 0 0 1]
[2 1 0 1 0]
[0 1 3 0 0]
[0 1 0 0 0]
[0 1 1 0 0]]

Ответы [ 3 ]

2 голосов
/ 13 апреля 2020
import numpy as np

currentDataClass = [1, 3, 3, 2, 5, 5, 3, 2, 1, 4, 3, 2, 1, 1, 2]
predictedClass = [1, 2, 3, 4, 2, 3, 3, 2, 1, 2, 3, 1, 5, 1, 1]

def comp_confmat(actual, predicted):

    classes = np.unique(actual) # extract the different classes
    matrix = np.zeros((len(classes), len(classes))) # initialize the confusion matrix with zeros

    for i in range(len(classes)):
        for j in range(len(classes)):

            matrix[i, j] = np.sum((actual == classes[i]) & (predicted == classes[j]))

    return matrix

comp_confmat(currentDataClass, predictedClass)

array([[3., 0., 0., 0., 1.],
       [2., 1., 0., 1., 0.],
       [0., 1., 3., 0., 0.],
       [0., 1., 0., 0., 0.],
       [0., 1., 1., 0., 0.]])

1 голос
/ 13 апреля 2020

Вот мое решение с использованием numpy и pandas:

import numpy as np
import pandas as pd

currentDataClass = [1, 3, 3, 2, 5, 5, 3, 2, 1, 4, 3, 2, 1, 1, 2]
predictedClass = [1, 2, 3, 4, 2, 3, 3, 2, 1, 2, 3, 1, 5, 1, 1]

classes = set(currentDataClass)
number_of_classes = len(classes)

conf_matrix = pd.DataFrame(
    np.zeros((number_of_classes, number_of_classes),dtype=int),
    index=classes,
    columns=classes)

for i, j in zip(currentDataClass,predictedClass):
        conf_matrix.loc[i, j] += 1

print(conf_matrix.values)
[[3 0 0 0 1]
 [2 1 0 1 0]
 [0 1 3 0 0]
 [0 1 0 0 0]
 [0 1 1 0 0]]
1 голос
/ 13 апреля 2020

В вашем самом внутреннем l oop должно быть различие в регистре: в настоящее время это l oop считает соглашение, но вы хотите, чтобы это было только в том случае, если на самом деле c1 == c2.

Вот другой способ, используя вложенный список пониманий:

currentDataClass = [1,3,3,2,5,5,3,2,1,4,3,2,1,1,2]    
predictedClass = [1,2,3,4,2,3,3,2,1,2,3,1,5,1,1]

classes = int(max(currentDataClass) - min(currentDataClass)) + 1 #find number of classes

counts = [[sum([(currentDataClass[i] == true_class) and (predictedClass[i] == pred_class) 
                for i in range(len(currentDataClass))])
           for pred_class in range(1, classes + 1)] 
           for true_class in range(1, classes + 1)]
counts    
[[3, 0, 0, 0, 1],
 [2, 1, 0, 1, 0],
 [0, 1, 3, 0, 0],
 [0, 1, 0, 0, 0],
 [0, 1, 1, 0, 0]]
...