最近在做一个四分类的医学图像分类,记录下到处凑来的分类效果评价指标吧:
y_true,y_pred,outProb 都是列表
发现了一个问题:metrics.classification_report不会打出多分类的特异度,需要自己写个函数
def cal_metrics(confusion_matrix):
n_classes = confusion_matrix.shape[0]
metrics_result = []
for i in range(n_classes):
# 逐步获取 真阳,假阳,真阴,假阴四个指标,并计算三个参数
ALL = np.sum(confusion_matrix)
# 对角线上是正确预测的
TP = confusion_matrix[i, i]
# 列加和减去正确预测是该类的假阳
FP = np.sum(confusion_matrix[:, i]) - TP
# 行加和减去正确预测是该类的假阴
FN = np.sum(confusion_matrix[i, :]) - TP
# 全部减去前面三个就是真阴
TN = ALL - TP - FP - FN
metrics_result.append([TP / (TP + FP), TP / (TP + FN), TN / (TN + FP)])
return metrics_result
result = cal_metrics(confusion_matrix)
print('cal_metrics: ',result)
评价指标完整版:包括metrics.classification_report,acc,confusion_matrix,auc曲线等
# Recall & Precision
target_names = ['class 0', 'class 1','class 2', 'class 3']
print(metrics.classification_report(y_true, y_pred,digits=3))
# 混淆矩阵
confusion_matrix = metrics.confusion_matrix(y_true, y_pred)
print("confusion_matrix=", confusion_matrix)
accuracy = metrics.accuracy_score(y_true, y_pred)
print("accuracy=", accuracy)
def cal_metrics(confusion_matrix):
n_classes = confusion_matrix.shape[0]
metrics_result = []
for i in range(n_classes):
# 逐步获取 真阳,假阳,真阴,假阴四个指标,并计算三个参数
ALL = np.sum(confusion_matrix)
# 对角线上是正确预测的
TP = confusion_matrix[i, i]
# 列加和减去正确预测是该类的假阳
FP = np.sum(confusion_matrix[:, i]) - TP
# 行加和减去正确预测是该类的假阴
FN = np.sum(confusion_matrix[i, :]) - TP
# 全部减去前面三个就是真阴
TN = ALL - TP - FP - FN
metrics_result.append([TP / (TP + FP), TP / (TP + FN), TN / (TN + FP)])
return metrics_result
result = cal_metrics(confusion_matrix)
print('cal_metrics: ',result)
# 显示混淆矩阵
classes = range(0, 4)
plt.imshow(confusion_matrix, cmap=plt.cm.Blues)
# ticks 坐标轴的坐标点
# label 坐标轴标签说明
indices = range(len(confusion_matrix))
# 第一个是迭代对象,表示坐标的显示顺序,第二个参数是坐标轴显示列表
plt.xticks(indices, classes)
plt.yticks(indices, classes)
plt.colorbar()
plt.xlabel('Predicted label')
plt.ylabel('True label')
plt.title("Confusion matrix",fontdict={'weight': '0'})
# plt.title("Confusion matrix", fontdict={'weight': '0', 'size': 18})
# 显示数据
for first_index in range(len(confusion_matrix)): # 第几行
for second_index in range(len(confusion_matrix[first_index])): # 第几列
plt.text(first_index, second_index, confusion_matrix[second_index][first_index])
# 显示
plt.show()
# 多分类Roc & Auc
y_true = label_binarize(y_true, classes=[0, 1, 2, 3])
fpr = dict()
tpr = dict()
roc_auc = dict()
for i in range(4):
fpr[i], tpr[i], _ = metrics.roc_curve(y_true[:,i], outProb[:, i])
roc_auc[i] = metrics.auc(fpr[i], tpr[i])
print(i,' auc:',roc_auc[i])
colors = cycle(['aqua', 'darkorange', 'cornflowerblue','green'])
for i, color in zip(range(4), colors):
plt.plot(fpr[i], tpr[i], color=color, lw=2,
label='ROC curve of class {0} (area = {1:0.3f})'
''.format(i, roc_auc[i]))
plt.plot([0, 1], [0, 1], 'k--', lw=2)
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('ROC Curve')
plt.legend(loc="lower right")
plt.show()
结果如图:
————————————————————————————————————————
看到有的多分类文章里也有医生预测效果roc曲线:其实就是对医生预测值进行label_binarize
因为医生预测结果只有类型而非深度学习能预测概率,所以医生的roc曲线是一条折线
补下代码
data_table = pd.read_csv(r'C:\Users\admin\Desktop\给医生的数据\四分类统计数据.csv', encoding='GB18030', delimiter=',')
data_table_arr = np.array(data_table)
Y_true = data_table_arr[:, 3]
lsy = data_table_arr[:, 1]
y_true = list(Y_true)
lsy = list(lsy)
# 多分类Roc & Auc
y_true = label_binarize(y_true, classes=[0, 1, 2, 3])
# 医生预测结果二值化
lsy_pred = label_binarize(lsy,classes=[0, 1, 2, 3])
wzm_pred = label_binarize(wzm,classes=[0, 1, 2, 3])
fpr = dict()
tpr = dict()
roc_auc = dict()
for i in range(4):
fpr[i], tpr[i], _ = metrics.roc_curve(y_true[:,i], lsy_pred[:, i])
roc_auc[i] = metrics.auc(fpr[i], tpr[i])
print(i,' auc:',roc_auc[i])
colors = cycle(['aqua', 'darkorange', 'cornflowerblue','green'])
for i, color in zip(range(4), colors):
plt.plot(fpr[i], tpr[i], color=color, lw=2,
label='ROC curve of class {0} (area = {1:0.3f})'
''.format(i, roc_auc[i]))
plt.plot([0, 1], [0, 1], 'k--', lw=2)
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('ROC Curve')
plt.legend(loc="lower right")
plt.show()
代码里lsy指是csv里lsy医生预测的结果