如何从Scikit-learn中获取多类分类的特异性和阴性预测值?

问题描述 投票:0回答:2

目前,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)
。这是为什么,如何解决?

python-3.x machine-learning scikit-learn reporting precision-recall
2个回答
0
投票

混淆矩阵的维度取决于您拥有的类的数量。

在 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)。


0
投票

先生,我认为您的代码的第二行不正确, 考虑到 'confusion_matrix' 返回结果的格式为 [0,1][0,1] “confusion_matrix”的右下角应该是 tp。 我想你需要这个:

tn, fp, fn, tp = confusion_matrix(y_true, y_pred).ravel()

© www.soinside.com 2019 - 2024. All rights reserved.