目前,scikit-learn 的默认分类报告 (
sklearn.metrics.classification_report
- link) 不包括特异性和阴性预测值 (NPV)。
因此,我做了自己的分类报告功能:
def custom_classification_report(y_true, y_pred):
tp, fn, fp, tn = confusion_matrix(y_true, y_pred).ravel()
acc = (tp+tn)/(tp+tn+fp+fn)
sen = (tp)/(tp+fn)
sp = (tn)/(tn+fp)
ppv = (tp)/(tp+fp)
npv = (tn)/(tn+fn)
f1 = 2*(sen*ppv)/(sen+ppv)
fpr = (fp)/(fp+tn)
tpr = (tp)/(tp+fn)
return ( '2X2 confusion matrix:', ['TP', tp, 'FP', fp, 'FN', fn, 'TN', tn],
'Accuracy:', round(acc, 3),
'Sensitivity/Recall:', round(sen, 3),
'Specificity:', round(sp, 3),
'PPV/Precision:', round(ppv, 3),
'NPV:', round(npv, 3),
'F1-score:', round(f1, 3),
'False positive rate:', round(fpr, 3),
'True positive rate:', round(tpr, 3),
)
def auc_roc(y_true, y_pred_score):
return ('AUC-ROC:', round(roc_auc_score(y_true, y_pred_score), 3))
def avg_precision(y_true, y_pred_score, target_name):
return ('Average precision:', round(average_precision_score(y_true, y_pred_score, pos_label=target_name), 3))
tpr = (tp)/(tp+fn)
return ( '2X2 confusion matrix:', ['TP', tp, 'FP', fp, 'FN', fn, 'TN', tn],
'Accuracy:', round(acc, 3),
'Sensitivity/Recall:', round(sen, 3),
'Specificity:', round(sp, 3),
'PPV/Precision:', round(ppv, 3),
'NPV:', round(npv, 3),
'F1-score:', round(f1, 3),
'False positive rate:', round(fpr, 3),
'True positive rate:', round(tpr, 3),
)
def auc_roc(self, y_true, y_pred_score):
return ('AUC-ROC:', round(roc_auc_score(y_true, y_pred_score), 3))
def avg_precision(self, y_true, y_pred_score, target_name):
return ('Average precision:', round(average_precision_score(y_true, y_pred_score, pos_label=target_name), 3))
当我使用它进行二元类分类时,它工作得很好 -
print('>> Custom classification report:\n', custom_classification_report(y_test, predicted_labels), '\n')
当我使用同一行代码
print('>> Custom classification report:\n', custom_classification_report(y_test, predicted_labels), '\n')
进行多类分类时,它给出了错误ValueError: too many values to unpack (expected 4)
。这是为什么,如何解决?
混淆矩阵的维度取决于您拥有的类的数量。
在 2x2 的情况下,您将返回预期的四个(tn、fp、fn、tp)。但是,在多类情况下,您将返回一个 n_class * n_class 矩阵。
尝试例如:
from sklearn.metrics import confusion_matrix
test = [0,0,0,0,1,1,1,1,2,2,2,2,]
pred = [0,0,0,1,1,1,1,2,2,2,1,0]
confusion_matrix(test, pred)```
生成:
array([[3, 1, 0], [0, 3, 1], [1, 1, 2]])
... 3 x3 矩阵。所以你的函数无法将这 9 个值解压缩为 4。
如果您想要四个值,则需要选择一个感兴趣的类别(例如类别 1),然后运行该类别与所有其他类别组合的 2x2 混淆矩阵。
另一个注意事项,我认为返回的 fusion_matrix 函数分数的顺序与您上面指定的顺序略有不同(在 https://scikit-learn.org/stable/modules/ generated 上为 tn、fp、fn、tp) /sklearn.metrics.confusion_matrix.html)。
先生,我认为您的代码的第二行不正确, 考虑到 'confusion_matrix' 返回结果的格式为 [0,1][0,1] “confusion_matrix”的右下角应该是 tp。 我想你需要这个:
tn, fp, fn, tp = confusion_matrix(y_true, y_pred).ravel()