python - 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])
解决方案
鉴于您的混淆矩阵,基于预测概率的 ROC 图对我来说很有意义。例如,ROC 图表明,当对一小部分其他数字进行错误分类时,您将能够识别所有真零。考虑到混淆矩阵,这似乎是有道理的,它显示了非常高的零精度。ROC 图还反映了三或九的较低准确度。
但是,我认为 ROC 可能不是解决您的问题的正确指标:ROC 曲线本质上显示了给定任务的假阴性和假阳性之间的权衡(例如识别九)。就您而言,我想您对识别单个数字并不太感兴趣,而是对所有数字的整体模型准确性更感兴趣。因此,您最好查看诸如分类交叉熵损失之类的度量。
但是,我认为,在您的情况下,查看整个 ROC 曲线可能会有点误导:您可能不愿意错误分类
推荐阅读
- c++ - 退出循环而不等待迭代结束
- r - flextable中的有条件粗体值
- python - 在Streamlit中使用Python选择任何小部件后如何停止重新加载页面
- filesystems - FUSE 中 FS 的介绍性文档(高和低 API 理解)
- javascript - 向同一个 HTML Image() 对象添加多个事件
- php - 使用 vscode 和 xDebug 使用 Composer 和骨架调试 php slim proyect create
- php - 数据库中的表情符号和阿拉伯字符问题
- html - 使用 justify-content: space-between; 在嵌套的弹性盒中
- c# - 在 NavigationProvider 中注入应用服务
- python - Django Steam API 的“列表索引超出范围”