不使用 sklearn 从数据构建混淆矩阵

Ris*_*e47 5 python machine-learning confusion-matrix

我正在尝试在不使用 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)))
Run Code Online (Sandbox Code Playgroud)

然而这会返回:

[[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]]
Run Code Online (Sandbox Code Playgroud)

但我不明白为什么当我每次重置计数并且循环遍历不同的值时,每次迭代都会产生 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]]
Run Code Online (Sandbox Code Playgroud)

Fla*_*ino 7

您可以通过计算实际类和预测类的每个组合中的实例数来导出混淆矩阵,如下所示:

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.]]
Run Code Online (Sandbox Code Playgroud)


Arn*_*rne 4

在最里面的循环中,应该有一个大小写区别:目前这个循环计算一致,但你只希望 if 实际上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    
Run Code Online (Sandbox Code Playgroud)
[[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]]
Run Code Online (Sandbox Code Playgroud)