什么是混淆矩阵?怎么理解np.bincount(n_class * label_true[mask].astype(int) + label_pred[mask])

https://blog.csdn.net/sinat_29047129/article/details/103642140

理解混淆矩阵

  1. 概念

混淆矩阵(Confusion Matrix),一个分类模型的评价指标,统计归对类、归错类的样本的个数(对图像来说就是样本就是所有像素),然后把结果放在一个表里展示出来,这个表就是混淆矩阵。

  1. 初步理解混淆矩阵

以二分类混淆矩阵作为入门,多分类混淆矩阵都是以二分类为基础作为延伸的!

Q: 什么是二分类?

A: 顾名思义,分类器(又叫:网络模型、学习器)对两个类别进行分类处理的问题,就叫二分类

对于二分类问题,将类别1称为正例(Positive),类别2称为反例(Negative),分类器预测正确记作真(True),预测错误记作(False),由这4个基本术语相互组合,构成混淆矩阵的4个基础元素,为:

  • TP(True Positive):真正例,模型预测为正例,实际是正例(模型预测为类别1,实际是类别1)

  • FP(False Positive):假正例,模型预测为正例,实际是反例 (模型预测为类别1,实际是类别2)

  • FN(False Negative):假反例,模型预测为反例,实际是正例 (模型预测为类别2,实际是类别1)

  • TN(True Negative):真反例,模型预测为反例,实际是反例 (模型预测为类别2,实际是类别2)

混淆矩阵示意图(参考:西瓜书 p30):

根据混淆矩阵计算其他常见模型评价指标:

  • 准确率(Accuracy),对应语义分割的像素准确率 PA

公式:Accuracy = (TP + TN) / (TP + TN + FP + FN)

意义:对角线计算。预测结果中正确的占总预测值的比例(对角线元素值的和 / 总元素值的和)

  • 精准率(Precision),对应语义分割的类别像素准确率 CPA

公式:Precision = TP / (TP + FP) 或 TN / (TN + FN)

意义:竖着计算。预测结果中,某类别预测正确的概率

  • 召回率(Recall),不对应语义分割常用指标

公式:Recall = TP / (TP + FN) 或 TN / (TN + FP)

意义:横着计算。真实值中,某类别被预测正确的概率

  1. 三分类模型分类结果的混淆矩阵示意图

  • 准确率:Accuracy = (a + e + i) / (a + b + c + d + e +f + g + h + i)

  • 类别1精准率:P1 = a / (a + d + g)

  • 类别1召回率:R1 = a / (a + b + c)

混淆矩阵计算代码

# 计算混淆矩阵
def _fast_hist(label_true, label_pred, n_class):
    mask = (label_true >= 0) & (label_true < n_class)
    hist = np.bincount(
        n_class * label_true[mask].astype(int) +
        label_pred[mask], minlength=n_class ** 2).reshape(n_class, n_class)
    return hist
# 例如
label_true  = np.array([[0,1,0],[2,1,0],[2,2,1]])
label_pred = np.array([[1,1,0],[2,1,1],[2,2,1]])
n_class = 3
confusionmatrix = _fast_hist(label_true, label_pred, n_class)

在这个例子中,各个变量、中间变量的值如下所示:

代码理解

对于核心代码 np.bincount(n_class * label_true[mask].astype(int) + label_pred[mask], minlength=n_class ** 2)的理解,此函数用于产生n*n的分类统计表

https://blog.csdn.net/weixin_43143670/article/details/104722381

  1. mask = (label_true >= 0) & (label_true < n_class)

这一句是为了保证标记的正确性(标记的每个元素值在[0, n_class)内),标记正确得到的mask是一个全为true的数组。

  1. label_true[mask]及label_pred[mask]把label_true、label_pred拉平为一维数组。

  1. 令a = label_true[mask],b = label_pred[mask],

c = n_class * label_true[mask] + label_pred[mask] = n_class * a + b

当a=0,b=0时,c=0;当a=0,b=1时,c=1;……;当a=2,b=2时,c=8,得到以下对应表。

label_true[i]=

0

0

0

1

1

1

2

2

2

label_pred[i]=

0

1

2

0

1

2

0

1

2

c[i]=

0

1

2

3

4

5

6

7

8

因此可根据c的值推出a、b的值,以下面这个计算结果为例,

c[0]=1,可推知label_true[mask][0]=0,label_pred[mask][0]=1,即c=1,(label_true,label_pred)=(0,1)

c[1]=4,可推知label_true[mask][1]=1,label_pred[mask][1]=1,即c=4,(label_true,label_pred)=(1,1)

……

简而言之,n_class * label_true[mask] + label_pred[mask]的作用是建立一个由索引查询(label_true,label_pred)这个数对的字典。

  1. d = np.bincount(c,minlength=n_class ** 2)的作用是统计c中每个元素出现的次数,比如0出现了1次,1出现了2次……,8出现了3次。d的维度默认是c中最大值+1,此处设为n_class ** 2。由c[i]的值可知标签图、预测图在位置i处的值,即真实值和预测值,通过np.bincount()统计c的每个元素(从0到(n_class ** 2 - 1))出现的次数,就意味着得到了每个(label_true,label_pred)对出现的次数,比如c=0出现了1次,可推知(0,0)对出现的次数就是1,c=8出现了3次,可推知(2,2)对出现的次数就是3,填入下表,就得到了混淆矩阵。

混淆矩阵

预测值

0

1

2

真实值

0

1

2

0

1

0

3

0

2

0

0

3

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值