首页 > 解决方案 > Sklearn - 序数数据的多类混淆矩阵

问题描述

我写了一个预测序数数据的模型。目前,我正在使用二次科恩的 kappa评估我的模型。我正在寻找一种使用混淆矩阵来可视化结果的方法,然后在考虑预测距离的情况下计算召回率、精度和 f1 分数。

IE 在 class 为 1 时预测2class 为 1 时预测3更好。

我编写了以下代码来绘制和计算结果:

def plot_cm(df, ax):
    cf_matrix = confusion_matrix(df.x, df.y,normalize='true',labels=[0,1,2,3,4,5,6,7,8]) 
    
    ax = sns.heatmap(cf_matrix, linewidths=1, annot=True, ax=ax, fmt='.2f')
    ax.set_ylabel(f'Actual')
    ax.set_xlabel(f'Predicted')

    print(f'Recall score:',recall_score(df.x,df.y, average= 'weighted',zero_division=0))
    print(f'Precision score:',precision_score(df.x,df.y, average= 'weighted',zero_division=0))
    print(f'F1 score:',f1_score(df.x,df.y, average= 'weighted',zero_division=0))

在此处输入图像描述

Recall score: 0.53505
Precision score: 0.5454783454981732
F1 score: 0.5360650278722704

可视化很好,但是,计算忽略了“几乎”为真的预测。IE在实际为9时预测为8(例如)。

考虑到数据的序数行为,有没有办法计算召回率、精度和 F1?

标签: pythonconfusion-matrixordinalcohen-kappa

解决方案


常规精度(对于类)计算为该类的 True Positives 与 Totally Detected 的比率。通常,真正的肯定检测以二进制方式定义:您要么正确检测到该类,要么没有。没有任何限制可以使样本的 TP 检测分数变得i模糊(或者换句话说,轻微惩罚接近类别的检测,并随着差异的增加使惩罚更加严重):

TP(i) = max(0, (1 - abs(detected_class(i) - true_class(i))/penalty_factor) )

其中TP_i是样本的“真阳性检测”值i,并且是介于之间的某个数字[0,1]- 这是 。使类数相等是合理penalty_factor的(应该大于1)。通过更改它,您可以控制将惩罚多少“远程”课程。例如,如果您决定大于 3 的差异足以考虑“未检测到”,请将其设置为 3。如果将其设置为 1,您将回到“常规”精度公式。我max()用来确保 TP 分数不会变成负数。

现在,为了使分母正确,您需要将其设置为 TP(i)>0 的样本数。也就是说,如果您总共有 100 个样本,并且在这 5 个样本中检测到 TP 检测分数为 1,而 6 个样本的 TP 检测分数为 0.5,那么您的 Precision 将为 (5 + 6*0.5)/(5+6)。

这里的一个问题是“每类精度”变得毫无意义,因为任何类都以某种方式与所有类相关,如果您需要按类“加权”总精度(对于不平衡类的情况),您需要考虑到真实的 TP 分数样本的类别i

使用相同的逻辑,召回率将是相关人群的 TP 分数的总和,即

R = (sum of (weighted) TP scores)/(total amount of samples)

最后,F1 是 Precision 和 Recall 的调和平均值。


推荐阅读