前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >准确率、精确率、召回率、F1-score

准确率、精确率、召回率、F1-score

作者头像
mathor
发布2020-03-02 14:38:44
4.9K0
发布2020-03-02 14:38:44
举报
文章被收录于专栏:mathormathor

分类是机器学习中比较常见的任务,对于分类任务常见的评价指标有准确率(Accuracy)、精确率(Precision)、召回率(Recall)、F1 score、ROC曲线(Receiver Operating Characteristic Curve)等

这篇文章将结合sklearn对准确率、精确率、召回率、F1-score进行讲解

混淆矩阵

如上图所示,要了解各个评价指标,首先需要知道混淆矩阵,混淆矩阵中的P表示Positive,即正例或者阳性,N表示Negative,即负例或者阴性。你也可以把P和N分别理解为二分类中的1-0

  • TP:实际为正,预测为正的样本数量
  • FP:实际为负,预测为正的样本数量
  • FN:实际为正,预测为负的样本数量
  • TN:实际为负,预测为负的样本数量

另外

  • TP+FP:表示所有预测为正的样本数量
  • TN+FN:表示所有预测为负的样本数量
  • TP+FN:表示实际为正的样本数量
  • TN+FP:表示实际为负的样本数量

准确率

准确率是分类正确的样本占总样本个数,即

$$ accuracy = \frac{n_{correct}}{n_{total}} $$

其中,$n_{correct}$表示被正确分类的样本个数,$n_{total}$表示样本总数

综合上面的混淆矩阵,公式还可以这样写

$$ accuracy=\frac{TP+TN}{TP+TN+FP+FN} $$

准确率是分类问题中最简单最直观的评价指标,但存在明显的缺陷。比如正负样本的比例不均衡,假设样本中正样本占90%,负样本占10%,那分类器只需要一直预测为正,就可以得到90%的准确率,但其实际性能是非常低下的

下面看一下sklearn中计算准确率的示例

代码语言:javascript
复制
import numpy as np
from sklearn.metrics import accuracy_score as accu

y_true = [0, 1, 2, 3]
y_pred = [0, 2, 1, 3]

print(accu(y_true, y_pred)) # 0.5
print(accu(y_true, y_pred, normalize=False)) # 2
# normalize=False 返回分类正确的样本数量

# 在具有二元标签指示符的多标签分类问题中
print(accu(np.array([0, 1], [1, 1]), np.ones((2, 2)))) # 0.5

对于最后两行代码

$$ y_{true}=\begin{bmatrix} {0}&{1}\\ {1}&{1} \end{bmatrix},\ \ \ y_{pred}=\begin{bmatrix} {1}&{1}\\ {1}&{1} \end{bmatrix} $$

矩阵的每一行表示一个样本,列表示标签(每个样本具有两个标签,这两个标签共同确定样本类别)。对于这种情况,此时实际上只有一个样本是预测正确的,因此准确率为0.5

精确率

精确率指模型预测为正的样本中实际也为正的样本 占 被预测为正的样本的比例。计算公式为

$$ precision=\frac{TP}{TP+FP} $$

代码如下

代码语言:javascript
复制
from sklearn.metrics import precision_score as ps

y_true = [0, 1, 2, 0, 1, 2]
y_pred = [0, 2, 1, 0, 0, 1]

print(ps(y_true, y_pred, average="macro"))    # 0.22222
print(ps(y_true, y_pred, average="micro"))    # 0.33333
print(ps(y_true, y_pred, average="weighted")) # 0.22222
print(ps(y_true, y_pred, average=None)) # [0.6666 0. 0.]

average的参数可选值有None, binary(默认), micro, macro, samples, weighted

上面的$y_{true}$有3个类别,分别为类0,类1,类2。我们将每个类别的TP、FP、FN列在下表中

类别

TP

FP

FN

0

2

1

0

1

0

2

2

2

0

1

1

那么每个类别的precision也就得到了

$$ \begin{align*} P_0&=\frac{2}{1+2}=\frac{2}{3}\approx 0.667\\ P_1&=\frac{0}{0+2}=0\\ P_2&=\frac{0}{0+1}=0 \end{align*} $$

于是Macro Precision也就知道了,就是$\frac{P_0+P_1+P_2}{3}\approx 0.222$

Micro Precision的计算要从每个样本考虑,所有样本中预测正确的有两个,那么TP就是2,剩下的4个预测结果都可以看作FP,于是Micro Precision就是$\frac{2}{2+4}=\frac{1}{3}\approx 0.333$

最后还有一个weighted,因为这里每个类别的数量恰好占比都是1/3,所以结果是

$$ P_w=\frac{1}{3}*P_0+\frac{1}{3}*P_1+\frac{1}{3}*P_2\approx 0.222 $$

  • 如果每个类别的样本数量不多,那么Macro和Micro没有太大差异
  • 如果每个类别的样本数量差异很大,那么注重样本量多的类时用Micro,注重样本量少的类时用Macro
  • 如果Macro>>Micro的值,那么检查样本量多的类来确定指标表现差的原因
  • 如果Micro>>Macro的值,那么检查样本量少的类来确定指标表现差的原因

召回率

召回率指实际为正的样本中,预测也为正的样本 占 实际为正的样本的比例。计算公式为

$$ recall=\frac{TP}{TP+FN} $$

代码如下

代码语言:javascript
复制
from sklearn.metrics import recall_score as rs

y_true = [0, 1, 2, 0, 1, 2]
y_pred = [0, 2, 1, 0, 0, 1]

print(rs(y_true, y_pred, average="macro")) # 0.3333
print(rs(y_true, y_pred, average="micro")) # 0.3333
print(rs(y_true, y_pred, average="weighted")) # 0.3333
print(rs(y_true, y_pred, average=None)) # [1. 0. 0.]

Recall和Precision只有计算公式不同,它们average参数的计算方式都是相同的,这里不再赘述

F1-score

F1-score是精确率和召回率的加权平均值,计算公式为

$$ F1-score=\frac{2*precision*recall}{precision+revall} $$

Precision体现了模型对负样本的区分能力,Precision越高,模型对负样本的区分能力越强

Recall体现了模型对正样本的识别能力,Recall越高,模型对正样本的识别能力越强

F1-score是两者的综合,F1-score越高,说明模型越稳健

代码如下

代码语言:javascript
复制
from sklearn.metrics import f1_score as fs

y_true = [0, 1, 2, 0, 1, 2]
y_pred = [0, 2, 1, 0, 0, 1]

print(fs(y_true, y_pred, average="macro")) # 0.2666
print(fs(y_true, y_pred, average="micro")) # 0.3333
print(fs(y_true, y_pred, average="weighted")) # 0.2666
print(fs(y_true, y_pred, averge=None)) # [0.8 0. 0.]

Worked Example

对于正常的邮件

$$ \begin{align*} precision&=\frac{16}{16+2}=\frac{8}{9}\\ Recall&=\frac{16}{16+4}=\frac{4}{5}\\ F1-score&=\frac{2*\frac{8}{9}*0.8}{\frac{8}{9}+0.8} = a \end{align*} $$

对于垃圾邮件

$$ \begin{align*} precision&=\frac{3}{3+4}=\frac{3}{7}\\ Recall&=\frac{3}{3+2}=\frac{3}{5}\\ F1-score&=\frac{2*\frac{3}{7}*0.6}{\frac{3}{7}+0.6} = b \end{align*} $$

对于整体的所有邮件

$$ \begin{align*} P &= \frac{\frac{8}{9}+\frac{3}{7}}{2} \\ R &= \frac{0.8+0.6}{2}\\ F1 &= \frac{a+b}{2} \end{align*} $$

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 混淆矩阵
  • 准确率
  • 精确率
  • 召回率
  • F1-score
  • Worked Example
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档