混淆矩阵confusion matrix的创建方式(可视化)

1.分类准确率及其局限性

分类准确率是预测正确的样本数与总样本数的比值

即:分类准确率 = 预测正确的样本数 / 总样本数

错误率即: 错误率 = 1 - 分类准确率

分类准确率看上去是一个不错的评判标准,但在实际当中往往却存在着一些问题。其主要问题在于它隐藏了我们需要的细节,从而阻碍我们更好地理解分类模型的性能。 有两个最常见的例子:

  1. 当我们的数据有2个以上的类时,如3个或更多类,我们可以得到80%的分类准确率,但是我们却不知道是否所有的类别都被预测得同样好,或者说模型是否忽略了一个或两个类;

  2. 当我们的每个类中的样本数并不接近时,我们可以达到90%或更高的准确率,但如果每100个记录中有90个记录属于一个类别,则这不是一个好分数,我们可以通过始终预测最常见的类值来达到此分数。如90个样本都属于类别1,则我们的模型只需要预测所有的样本都属于类别1,便可以达到90%或更高的准确率。

分类准确率可以隐藏诊断模型性能所需的详细信息,但幸运的是,我们可以通过混淆矩阵来进一步区分这些细节。

2、什么是混淆矩阵

混淆矩阵是对分类问题的预测结果的总结。使用计数值汇总正确和不正确预测的数量,并按每个类进行细分,这是混淆矩阵的关键所在。混淆矩阵显示了分类模型的在进行预测时会对哪一部分产生混淆。它不仅可以让您了解分类模型所犯的错误,更重要的是可以了解哪些错误类型正在发生。正是这种对结果的分解克服了仅使用分类准确率所带来的局限性。

对于二分类来说,其混淆矩阵可以定义为如下形式:

其中 :

1. 真阳性(True Positive,TP):样本的真实类别是正例,并且模型预测的结果也是正例

2. 真阴性(True Negative,TN):样本的真实类别是负例,并且模型将其预测成为负例

3. 假阳性(False Positive,FP):样本的真实类别是负例,但是模型将其预测成为正例

4. 假阴性(False Negative,FN):样本的真实类别是正例,但是模型将其预测成为负例

3、从混淆矩阵中得出的一些指标

预测性分类模型,肯定是希望越准越好。那么,对应到混淆矩阵中,那肯定是希望TP与TN的数量大,而FP与FN的数量小。

如下表所示,是得到的一些指标的计算方式:

F1 Score

这个指标是由上表中的精确度和召回率得到,计算方式如下:

 

其中,P代表Precision,R代表Recall。

F1-Score指标综合了Precision与Recall的产出的结果。F1-Score的取值范围从0到1的,1代表模型的输出最好,0代表模型的输出结果最差。

4、多分类混淆矩阵实例

 前面章节所述均是以二分类问题为基础的。而对于多分类问题,使用混淆矩阵计算各个指标的方式如下:

以下表所示的混淆矩阵为例,我们模型的目的是为了预测样本是什么动物,这是预测结果:

通过混淆矩阵,我们可以得到如下结论:

Accuracy

在总共66个动物中,我们一共预测对了10 + 15 + 20=45个样本,所以准确率(Accuracy)=45/66 = 68.2%。

以猫为例,我们可以将上面的图合并为二分问题:

Precision

所以,以猫为例,模型的预测结果告诉我们,66只动物里有13只是猫,但是其实这13只猫只有10只预测对了。模型认为是猫的13只动物里,有1条狗,两只猪。所以,Precision(猫)= 10/13 = 76.9%

Recall

以猫为例,在总共18只真猫中,我们的模型认为里面只有10只是猫,剩下的3只是狗,5只都是猪。这5只八成是橘猫,能理解。所以,Recall(猫)= 10/18 = 55.6%

Specificity

以猫为例,在总共48只不是猫的动物中,模型认为有45只不是猫。所以,Specificity(猫)= 45/48 = 93.8%。

虽然在45只动物里,模型依然认为错判了6只狗与4只猪,但是从猫的角度而言,模型的判断是没有错的。

F1-Score

通过公式,可以计算出,对猫而言,F1-Score=(2 * 0.769 *  0.556)/( 0.769 +  0.556) = 64.54%

同样,我们也可以分别计算猪与狗各自的二级指标与三级指标值。

 5、python实现混淆矩阵经计算并可视化

from sklearn.metrics import confusion_matrix    # 生成混淆矩阵的函数

'''
首先是从结果文件中读取预测标签与真实标签,然后将读取的标签信息传入python内置的混淆矩阵矩阵函数confusion_matrix(真实标签,
预测标签)中计算得到混淆矩阵,之后调用自己实现的混淆矩阵可视化函数plot_confusion_matrix()即可实现可视化。
三个参数分别是混淆矩阵归一化值,总的类别标签集合,可是化图的标题
'''

def plot_confusion_matrix(cm, labels_name, title):
    np.set_printoptions(precision=2)
    # print(cm)
    plt.imshow(cm, interpolation='nearest')    # 在特定的窗口上显示图像
    plt.title(title)    # 图像标题
    plt.colorbar()
    num_local = np.array(range(len(labels_name)))    
    plt.xticks(num_local, labels_name, rotation=90)    # 将标签印在x轴坐标上
    plt.yticks(num_local, labels_name)    # 将标签印在y轴坐标上
    plt.ylabel('True label')    
    plt.xlabel('Predicted label')
    # show confusion matrix
    plt.savefig('./fig/'+title+'.png', format='png')

gt = []
pre = []
with open("result.txt", "r") as f:
    for line in f:
        line=line.rstrip()#rstrip() 删除 string 字符串末尾的指定字符(默认为空格)
        words=line.split()
        pre.append(int(words[0]))
        gt.append(int(words[1]))

cm=confusion_matrix(gt,pre)  #计算混淆矩阵
print('type=',type(cm))
cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]    # 归一化
labels = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]  #类别集合
plot_confusion_matrix(cm,labels,'confusion_matrix')  #绘制混淆矩阵图,可视化

实验结果如下:

 

关于上图中预测标签与真实标签在坐标轴上的位置,可以任意交换,不影响最后的结果的。

 

  • 7
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值