首页 > 解决方案 > ROC 曲线表明我的预测比随机的更差,但我的混淆矩阵另有说明

问题描述

我正在使用数据将手写数字从 0 分类到 9。我正在使用 PCA 将维度减少到 6 个主成分,并使用 KNN 对数据进行建模。

当我创建混淆矩阵时,我得到了合理的答案。它并不完美,没想到会如此完美,但考虑到我的 k 值约为 0.8885 的准确度,这是有道理的。

array([[ 952,    0,    2,    1,    0,    9,    9,    0,    7,    0],
       [   0, 1125,    0,    3,    0,    0,    5,    1,    1,    0],
       [   7,    5,  973,   11,    4,    2,    9,    3,   18,    0],
       [   4,    9,   15,  846,    2,   40,    2,    7,   82,    3],
       [   3,    4,    9,    6,  830,    5,   16,   11,    0,   98],
       [  23,    1,    9,   38,    9,  787,    9,    2,   10,    4],
       [  17,    8,   16,    2,   13,    9,  893,    0,    0,    0],
       [   2,   14,   13,    3,   54,    4,    0,  909,    6,   23],
       [  16,    2,   25,   60,   23,   23,    4,    6,  802,   13],
       [  11,    5,    7,   16,  155,   15,    4,   21,    7,  768]],
      dtype=int64)

但是,当我尝试绘制 ROC 曲线时,我要么得到 3 个点输出到 fpr 和 tpr,而且曲线似乎异常高。我确信我需要更多点,所以我尝试改变计算 roc_curve 的方法,但现在我的曲线得到的结果非常低,这对我的混淆矩阵没有意义。当我查看要检查的类列表时,似乎 ROC 的准确性有所提高。

我想知道我在 ROC 计算中可能做错了什么。

accuracy = 0;
predicted_class = np.zeros((np.size(y_test),1))
knn = KNeighborsClassifier(n_neighbors = 3)
knn.fit(test_projected,y_test)
for i in range (0,np.size(test_projected[:,0])):
    query_point = test_projected[i,:]
    true_class_of_query_point = y_test[i]

    predicted_class[i] = knn.predict([query_point])
    if(predicted_class[i] == true_class_of_query_point):
        accuracy += 1;
print('Accuracy of k = 3 is ', accuracy/np.size(test_projected[:,0]), '\n')

fig,axs = plt.subplots(5,2,figsize=(15,15))
fig.tight_layout()
j = 0;
k = 0;
y_gnd = np.zeros((10000,1))
for i in range (0,10):
    for m in range(0,10000):
        if(y_test[m]==i):
            y_gnd[m] = 1
        else:
            y_gnd[m] = 0
    fpr,tpr,threshold = metrics.roc_curve(y_gnd,predicted_class)
    auc = metrics.roc_auc_score(y_gnd,predicted_class)

此外,roc_auc_score 的输入是否应该是 fpr 和 tpr?我已经将标签和预测以及 fpr 和 tpr 都视为输入。

    axs[j][k].plot(fpr,tpr)
    axs[j][k].set_title('AUC Score for ' +str(i)+ ' is = ' +str(auc)+ '.')

    if(k == 1):
        j += 1;
    k += 1;
    if(k > 1):
        k = 0;

在此处输入图像描述

在此处输入图像描述

编辑:使用 predict_proba 预测类的新 ROC 曲线

pred = knn.predict_proba(test_projected)
fpr,tpr,threshold = metrics.roc_curve(y_gnd,pred[:,i])
auc = metrics.roc_auc_score(y_gnd,pred[:,i])

在此处输入图像描述

在此处输入图像描述

标签: pythonrocconfusion-matrixauc

解决方案


鉴于您的混淆矩阵,基于预测概率的 ROC 图对我来说很有意义。例如,ROC 图表明,当对一小部分其他数字进行错误分类时,您将能够识别所有真零。考虑到混淆矩阵,这似乎是有道理的,它显示了非常高的零精度。ROC 图还反映了三或九的较低准确度。

但是,我认为 ROC 可能不是解决您的问题的正确指标:ROC 曲线本质上显示了给定任务的假阴性和假阳性之间的权衡(例如识别九)。就您而言,我想您对识别单个数字并不太感兴趣,而是对所有数字的整体模型准确性更感兴趣。因此,您最好查看诸如分类交叉熵损失之类的度量。

但是,我认为,在您的情况下,查看整个 ROC 曲线可能会有点误导:您可能不愿意错误分类


推荐阅读