sklearn中分类模型评估指标(一):准确率、Top准确率、平衡准确率

简介: accuracy_score函数计算准确率分数,即预测正确的分数(默认)或计数(当normalize=False时)。在多标签分类中,该函数返回子集准确率(subset accuracy)。 如果样本的整个预测标签集与真实标签集严格匹配,则子集准确率为 1.0; 否则为 0.0。

准确率分数


accuracy_score函数计算准确率分数,即预测正确的分数(默认)或计数(当normalize=False时)。

在多标签分类中,该函数返回子集准确率(subset accuracy)。 如果样本的整个预测标签集与真实标签集严格匹配,则子集准确率为 1.0; 否则为 0.0。

如果y^i\hat{y}_iy^i是第i个样本的预测值和yiy_iyi是对应的真实值,那么正确预测的分数,公式定义如下:

accuracy(y,y^)=1nsamples∑i=0nsamples−11(y^i=yi)=TP+TNTP+FP+TN+FN\texttt{accuracy}(y, \hat{y}) = \frac{1}{n_\text{samples}} \sum_{i=0}^{n_\text{samples}-1} 1(\hat{y}_i = y_i)=\frac{TP+TN}{TP+FP+TN+FN}accuracy(y,y^)=nsamples1i=0nsamples11(y^i=yi)=TP+FP+TN+FNTP+TN

其中,1(x)1(x)1(x) 表示指示函数(indicator function),它的含义是:当输入为True的时候,输出为1,输入为False的时候,输出为0。

关于指示函数的说明:

在数学中,指示函数是定义在某集合XXX上的函数,表示其中有哪些元素属于某一子集AAA ,常应用在集合论中。指示函数有时候也称为特征函数。

示例代码如下:

import numpy as np
from sklearn.metrics import accuracy_score
y_pred = [0, 2, 1, 3]
y_true = [0, 1, 2, 3]
print(accuracy_score(y_true, y_pred))
print(accuracy_score(y_true, y_pred, normalize=False))
复制代码


运行结果:

0.5
2
复制代码


在具有两个类标签指示符矩阵的多标签场景下,示例代码为:

print(accuracy_score(np.array([[0, 1], [1, 1]]), np.ones((2, 2))))
复制代码


运行结果:

0.5
复制代码


Top-k准确率分数


top_k_accuracy_score函数是对accuracy_score函数的扩展。 不同之处在于,只要真实标签与前 k 个最高预测分数之一相关联,就认为预测是正确的。accuracy_score是 k = 1的特例。

该函数可以应用于二分类和多分类情况,但不包括多标签情况。

如果f^i,j\hat{f}_{i,j}f^i,j是对应于第i个样本的第j个最大预测分数的预测类别,yiy_iyi是对应的真实值,那么对于nsamplesn_\text{samples}nsamples个样本,正确预测的分数被定义为

top-k accuracy(y,f^)=1nsamples∑i=0nsamples−1∑j=1k1(f^i,j=yi)\texttt{top-k accuracy}(y, \hat{f}) = \frac{1}{n_\text{samples}} \sum_{i=0}^{n_\text{samples}-1} \sum_{j=1}^{k} 1(\hat{f}_{i,j} = y_i)top-k accuracy(y,f^)=nsamples1i=0nsamples1j=1k1(f^i,j=yi)

其中,k是允许的预测个数, 1(x)1(x)1(x)是指示函数。

示例代码:

import numpy as np
from sklearn.metrics import top_k_accuracy_score
y_true = np.array([0, 1, 2, 2])
# 0, 1, 2
y_score = np.array([[0.5, 0.2, 0.2], # 0,1
                    [0.3, 0.4, 0.2], # 0,1
                    [0.2, 0.4, 0.3], # 1,2
                    [0.7, 0.2, 0.1]]) # 0,1
print(top_k_accuracy_score(y_true, y_score, k=2))
# 如果没有归一化,则返回分类样本预测正确的数量
print(top_k_accuracy_score(y_true, y_score, k=2, normalize=False))
复制代码


运行结果:

0.75
3
复制代码


平衡准确率分数


balance_accuracy_score 函数计算平衡准确率,在二分类和多分类场景中,平衡准确率用来处理不平衡数据集的问题,从而避免对不平衡数据集的评估表现夸大。它被定义为在每个类上的召回率的宏平均值,或者等效于,原始准确率(raw accuracy),其中每个样本根据其真实类别的逆流行程度(逆流行率)进行加权。 因此,对于平衡数据集,其分数等于准确率分数。

在二分类情况下,平衡准确率等于灵敏度(true positive rate,真阳性率)和特异度(true negative rate,真阴性率)的算术平均值,或者二分类情况下,预测的 ROC 曲线下面积而不是分数:

balanced-accuracy=12(TPTP+FN+TNTN+FP)=TPR+TNR2\texttt{balanced-accuracy} = \frac{1}{2}\left( \frac{TP}{TP + FN} + \frac{TN}{TN + FP}\right )=\frac{TPR+TNR}{2}balanced-accuracy=21(TP+FNTP+TN+FPTN)=2TPR+TNR

如果分类器在任一类上具有同等表现,则该术语简化为常规准确率(即正确预测的数量除以预测总数)。

相反,如果仅因为分类器使用了不平衡的测试集,导致常规的准确率高于随机值(chance=1n_classeschance=\frac{1}{n\_classes}chance=n_classes1),那么平衡准确率,这种情况下,将下降到 1n_classes\frac{1}{n\_classes}n_classes1

adjusted=False时,分数范围为从0到1,最佳值为1,最差值为0。当 adjusted=True 时,分数范围从11−n_classes\frac{1}{1 - n\_classes}1n_classes1111(包括边界),随机值分数表现是0(不平衡数据集),完美表现分数是1,完全预测错误分数为11−n_classes\frac{1}{1 - n\_classes}1n_classes1

如果 yiy_iyi是第iii个样本的真实值,并且wiw_iwi是对应的样本权重,那么我们调整样本权重为:

w^i=wi∑j1(yj=yi)wj\hat{w}_i = \frac{w_i}{\sum_j{1(y_j = y_i) w_j}}w^i=j1(yj=yi)wjwi

其中,1(x)1(x)1(x)是指示函数。给定样本 iii的预测y^i\hat{y}_iy^i,则平衡准确率公式定义为:

balanced-accuracy(y,y^,w)=1∑w^i∑i1(y^i=yi)w^i\texttt{balanced-accuracy}(y, \hat{y}, w) = \frac{1}{\sum{\hat{w}_i}} \sum_i 1(\hat{y}_i = y_i) \hat{w}_ibalanced-accuracy(y,y^,w)=w^i1i1(y^i=yi)w^i

adjusted相关源码如下:

if adjusted:
    n_classes = len(per_class) # 类别数
    chance = 1 / n_classes
    score -= chance
    score /= 1 - chance
复制代码


针对二分类情况,示例代码:

from sklearn.metrics import balanced_accuracy_score
y_true = [0, 1, 0, 0, 1, 0]
y_pred = [0, 1, 0, 0, 0, 1]
# tp=1,  fn=1,  tn=3, fp=1
# 常规:(1+3)/6 = 0.66
# 平衡:(1/2+3/4)/2 = 0.625
print(accuracy_score(y_true, y_pred))
print(balanced_accuracy_score(y_true, y_pred))
# 1/类别数
# 0.625 - 1/2  = 0.125
# 0.125 / (1-1/2) = 0.25
print(balanced_accuracy_score(y_true, y_pred, adjusted=True))
复制代码


运行结果:

0.6666666666666666
0.625
0.25
复制代码


针对多分类情况,示例代码如下:

from sklearn.metrics import accuracy_score,balanced_accuracy_score
y_true = [0, 1, 2, 0, 0]
y_pred = [0, 2, 2, 0, 1]
# 3/5
print(accuracy_score(y_true, y_pred))
# 对于0  tp=2  fn=1     2/3
# 对于1  tp=0  fn=1     0
# 对于2  tp=1  fn=0     1
# (2/3+0+1)/3 = 5/9
print(balanced_accuracy_score(y_true, y_pred, adjusted=False))
# 5/9 - 1/3 = 2/9
# (2/9)/(1-1/3) = 1/3
print(balanced_accuracy_score(y_true, y_pred, adjusted=True))
复制代码


运行结果:

0.6
0.5555555555555555
0.3333333333333332
复制代码


针对不平衡数据集的示例代码如下:

from sklearn.metrics import recall_score,balanced_accuracy_score 
def test_balanced_accuracy_score():
    y_true = [0, 1, 2, 0, 0, 1, 4]
    y_pred = [0, 2, 2, 0, 1, 1, 2]
    macro_recall = recall_score(y_true, y_pred, average='macro',
                                labels=np.unique(y_true))
    # adjusted=False时,平衡准确率
    balanced = balanced_accuracy_score(y_true, y_pred)
    print(balanced)
    # adjusted=True时,平衡准确率
    adjusted = balanced_accuracy_score(y_true, y_pred, adjusted=True)
    print(adjusted)
    print("-------------")
    # 不平衡数据集(预测的运气值)
    print(np.full_like(y_true, y_true[0]))
    print(np.full_like(y_true, y_true[1]))
    print(np.full_like(y_true, y_true[2]))
    print(np.full_like(y_true, y_true[6]))
    # 不平衡数据集(预测的运气值)
    chance = balanced_accuracy_score(y_true, np.full_like(y_true, y_true[0]))
    print(chance)
    chance = balanced_accuracy_score(y_true, np.full_like(y_true, y_true[1]))
    print(chance)
    chance = balanced_accuracy_score(y_true, np.full_like(y_true, y_true[2]))
    print(chance)
    # 从adjusted=False到adjusted=True的转换
    print(adjusted == (balanced - chance) / (1 - chance) )
    print("+++++++++++++")
    # 采用不平衡测试集(adjusted=True),则平衡准确率为0
    print(balanced_accuracy_score(y_true, np.full_like(y_true, y_true[6]), adjusted=False))
    # 采用不平衡测试集(adjusted=True),则平衡准确率为1/(n_classes)
    chance = balanced_accuracy_score(y_true, np.full_like(y_true, y_true[6]), adjusted=True)
    print(chance)
    print("-------------")
    y_true = [0, 1, 2, 0]
    y_pred = [1, 2, 0, 1]
    # 完全错误的数据集(adjusted=True),则平衡准确率为1/(1 - n_classes)
    print(balanced_accuracy_score(y_true, y_pred, adjusted=True))
    # 完全错误的数据集(adjusted=True),则平衡准确率为0
    print(balanced_accuracy_score(y_true, y_pred, adjusted=False))
test_balanced_accuracy_score()
复制代码


运行结果:

0.5416666666666666
0.38888888888888884
-------------
[0 0 0 0 0 0 0]
[1 1 1 1 1 1 1]
[2 2 2 2 2 2 2]
[4 4 4 4 4 4 4]
0.25
0.25
0.25
True
+++++++++++++
0.25
0.0
-------------
-0.49999999999999994
0.0
复制代码


总结



函数 说明
accuracy_score 适用于二分类、多分类和多标签分类场景。通常用于平衡数据集的场景。
top_k_accuracy_score 适用于二分类、多分类场景。
balance_accuracy_score 适用于二分类、多分类场景。通常用于不平衡数据集的场景。


相关文章
SQL 个版本下载地址
备用:   SQL Server 2016简体中文企业版 文件名:cn_sql_server_2016_enterprise_x64_dvd_8699450.iso 64位下载地址:ed2k://|file|cn_sql_server_2016_enterprise_x64_dvd_8699450.
3103 0
|
机器学习/深度学习 人工智能 达摩院
10万亿!达摩院发布全球最大AI预训练模型M6
今天,阿里巴巴达摩院公布多模态大模型M6最新进展,其参数已从万亿跃迁至10万亿,成为全球最大的AI预训练模型。
9380 0
10万亿!达摩院发布全球最大AI预训练模型M6
|
人工智能 新能源 BI
关于举办"2025年第五届全国大学生技术创新创业大赛"的通知
大赛已连续举办四届,举办以来大赛始终以“创新驱动,赋能就业”为目标,促进学生的创新创造能力,普及创新创业知识,拓宽就业创业渠道,挖掘创新人才,培育多元化的未来产业推进力量。自开赛以来,赛事受到百余所学校关注,十几所高校已立项,参赛人次达上万人,征集优秀商业计划书上千余份。本届新赛事将继续全面贯彻党的二十大精神,完整、准确、全面贯彻新发展理念,加快构建新发展格局,以传统产业的高端化升级和前沿技术的产业化落地为主线,以创新为动力,第五届赛事将开展优秀项目落地北京计划。
3089 4
|
搜索推荐 物联网 PyTorch
Qwen2.5-7B-Instruct Lora 微调
本教程介绍如何基于Transformers和PEFT框架对Qwen2.5-7B-Instruct模型进行LoRA微调。
14576 34
Qwen2.5-7B-Instruct Lora 微调
|
Kubernetes 安全 虚拟化
VMware Fusion 13.6.3 发布下载,现在完全免费无论个人还是商业用途
VMware Fusion 13.6.3 发布下载,现在完全免费无论个人还是商业用途
26931 10
VMware Fusion 13.6.3 发布下载,现在完全免费无论个人还是商业用途
|
人工智能 安全 Java
片段式代码VS完整工程生成:飞算JavaAI如何让开发者告别碎片化开发?
飞算 JavaAI 是一款基于大模型的智能开发平台,旨在解决传统开发中的“碎片化困局”。它通过“智能引导开发五步法”,从需求分析到工程代码交付实现全链路智能化。不仅能生成高质量代码片段,更能直接输出可运行的完整工程,帮助开发者摆脱重复性劳动,专注于系统架构设计和业务创新,推动软件开发从“体力劳动”向“脑力创造”转变,开启高效开发新时代。
|
负载均衡 Cloud Native 持续交付
云原生时代的微服务架构:优势、挑战与实践
云原生时代的微服务架构:优势、挑战与实践
438 20
|
机器学习/深度学习 人工智能 运维
智能化运维:从被动响应到主动预防####
【10月更文挑战第29天】 本文探讨智能化运维(AIOps)如何通过融合大数据、机器学习与自动化技术,推动IT运维管理从传统的被动响应模式向主动预防机制转变。不同于传统摘要概述全文内容的方式,本文摘要旨在直接揭示智能化运维的核心价值——利用智能算法预测潜在故障,减少系统停机时间,提升运维效率与服务质量,同时强调其在现代企业IT架构中的关键作用。 ####
538 9
|
Python
【Python】【Pandas】将符合条件行的某列数值改为负数
在此顺便记录几个常用代码写法: 1.不重复取出一列的值data[列名].unique()或者data[列名].value_counts(sort=False) 2.对取出的列值进行格式处理
594 0