Confusion matrix using numpy.bincount.
1. np.bincount函数
np.bincount
用于统计一个非负数组中元素的出现次数。函数格式如下:
import numpy as np
np.bincount(x, weights=None, minlength=None)
通常默认数组$x$的最小值为$0$,若其最大值为$n$,则会返回长度为$n+1$的数组,其索引$i$表示数值$i$在数组$x$中出现的次数:
# x中最大的数为7,因此bin的数量为8,其索引值为0->7
x = np.array([0, 1, 1, 3, 2, 1, 7])
# 索引0出现了1次,索引1出现了3次......索引7出现了1次
np.bincount(x)
#输出结果为:array([1, 3, 1, 1, 0, 0, 0, 1])
参数weights
指定了数组$x$每个位置的权重(默认权重为$1$),如果在位置$i$出现值$n$,则有out[n]+=weights[i]
而不是out[n]+=1
:
w = np.array([0.3, 0.5, 0.2, 0.7, 1., -0.6])
# x中最大的数为4,因此bin的数量为5,其索引值为0->4
x = np.array([2, 1, 3, 4, 4, 3])
# 索引0 -> 0
# 索引1 -> w[1] = 0.5
# 索引2 -> w[0] = 0.3
# 索引3 -> w[2] + w[5] = 0.2 - 0.6 = -0.4
# 索引4 -> w[3] + w[4] = 0.7 + 1 = 1.7
np.bincount(x, weights=w)
# 输出结果为:array([ 0. , 0.5, 0.3, -0.4, 1.7])
参数minlength
指定了bin的最小长度。其最小长度不会低于数组最大值加$1$:
# x中最大的数为3,因此bin的数量为4,其索引值为0->3
x = np.array([3, 2, 1, 3, 1])
# bin的默认数量为4,若指定参数为7,则bin的数量为7,其索引值为0->6
np.bincount(x, minlength=7)
# 输出结果为:array([0, 2, 1, 2, 0, 0, 0])
# bin的默认数量为4,若指定参数为1,指定数量小于默认值,索引值还是0->3
np.bincount(x, minlength=1)
# 输出结果为:array([0, 2, 1, 2])
2. 使用np.bincount计算混淆矩阵
混淆矩阵是分类任务的常用评估方法,对于多分类任务,混淆矩阵会统计每个类别的预测情况。一个具有$3$个类别的混淆矩阵表示如下
\[\begin{array}{l|ccc} \text{真实情况\预测结果} & \text{类别1} & \text{类别2} & \text{类别3} \\ \hline \text{类别1} & a & b & c \\ \text{类别2} & d & e & f \\ \text{类别3} & g & h & i \\ \end{array}\]注意到真实类别为$i$,预测类别为$j$的样本被统计到第$i$行第$j$列,若将混淆矩阵拉直成一个行向量,则对应索引位置为$n*i+j$。
若预测数组为pred
,标签数组为label
,类别数为n
。则数组n*label+pred
存储了混淆矩阵的索引值。
import numpy as np
def genConfusionMatrix(pred, label, n):
'''
Parameters
----------
pred : 预测数组.
label : 标签数组.
n : 类别数(不包括背景).
'''
return np.bincount(n*label+pred, minlength=n**2).reshape(n, n)
pred = np.array([0,1,0,2,1,0,2,2,1])
label = np.array([0,2,0,2,1,0,0,2,1])
print(genConfusionMatrix(pred, label, 3))
###
[[3 0 1]
[0 2 0]
[0 1 2]]
###