Skip to content Skip to sidebar Skip to footer

Constructing A Confusion Matrix From Data Without Sklearn

I am trying to construct a confusion matrix without using the sklearn library. I am having trouble correctly forming the confusion matrix. Here's my code: def comp_confmat(): c

Solution 1:

You can derive the confusion matrix by counting the number of instances in each combination of actual and predicted classes as follows:

import numpy as np

def comp_confmat(actual, predicted):

    # extract the different classes
    classes = np.unique(actual)

    # initialize the confusion matrix
    confmat = np.zeros((len(classes), len(classes)))

    # loop across the different combinations of actual / predicted classes
    for i in range(len(classes)):
        for j in range(len(classes)):

           # count the number of instances in each combination of actual / predicted classes
           confmat[i, j] = np.sum((actual == classes[i]) & (predicted == classes[j]))

    return confmat

# sample data
actual = [1, 3, 3, 2, 5, 5, 3, 2, 1, 4, 3, 2, 1, 1, 2]
predicted = [1, 2, 3, 4, 2, 3, 3, 2, 1, 2, 3, 1, 5, 1, 1]

# confusion matrix
print(comp_confmat(actual, predicted))
# [[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.]]

Solution 2:

In your innermost loop, there should be a case distinction: Currently this loop counts agreement, but you only want that if actually c1 == c2.

Here's another way, using nested list comprehensions:

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]]

Solution 3:

Here is my solution using numpy and pandas:

import numpy as np
import pandas as pd

true_classes = [1, 3, 3, 2, 5, 5, 3, 2, 1, 4, 3, 2, 1, 1, 2]
predicted_classes = [1, 2, 3, 4, 2, 3, 3, 2, 1, 2, 3, 1, 5, 1, 1]

classes = set(true_classes)
number_of_classes = len(classes)

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

for true_label, prediction in zip(true_classes ,predicted_classes):
    # Each pair of (true_label, prediction) is a position in the confusion matrix (row, column)
    # Basically here we are counting how many times we have each pair.
    # The counting will be placed at the matrix index (true_label/row, prediction/column)
 
    conf_matrix.loc[true_label, prediction] += 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]]

Post a Comment for "Constructing A Confusion Matrix From Data Without Sklearn"