本文由 简悦 SimpRead 转码, 原文地址 martinlwx.github.io
每一列表示实际情况,每一行表示我们的预测,这样组合起来就得到了一个混淆矩阵,比如一个二分类的任务,可以画出如下的混淆矩阵![]()
| Positive | Negative | |
|---|---|---|
| True | TP = True Positive | FP = False Positive |
| False | FN = False Negative | TN = True Negative |
有多少样本我们预测正确了
预测正确的其实有下面两种情形![]()
- TP:本来是 positive,你也认为是 positive 的
- TN:本来是 negative,你也认为是 negative 的
那么用 TP + TN(其实就是主对角线)除以总的样本数就可以得到 accuracy,
或者直接看表格,其实就是 四个单元格主对角线=TP+TN+FN+FPTP+TN
一般来说 accuracy 是好用的评估指标,但是在某些情况下不是这样子的,比如样本数据不均衡的时候
| 类别 A | 类别 B | |
|---|---|---|
| 判断是类别 A | 0 | 0 |
| 判断是类别 B | 1 | 99 |
假设类别 A 有 1 个,类别 B 有 99 个,如果不管输入的是什么都返回类别 B 的正确率是多少呢?
答案是 0+0+1+990+99=99,我们可以说这个分类器效果很好吗,这显然是很荒谬的![]()
所有预测为 True 的样本里面,有多少是真的 positive 的
从定义出发可以知道,其实就是表格中判断为 True 的这一行中 positive 的比例,那么就是 TP+FPTP
所有本来是 positive 的,有多少被我们成功预测了出来
从定义出发,所有本来是 positive 的就是 Positive 这一列之和,我们成功预测的是 TP,那么就是 TP+FNTP
我们常常要在 Precision 和 Recall 中进行 tradeoff,因为其中一个升高,另一个就会降低
正是因为 Precision 和 Recall 的互斥特性,在衡量分类器好坏的时候会给我们带来困扰,特别是两者相差不多的情况下,于是就需要将这两个指标合并起来用另一个指标表示,也就是 F1 score
F1 score 的计算方式如下:
F1 score=P+R2PR
其中 Precision = P; Recall = R
- Macro:分别计算每个类别的 P 和 R,再计算总的平均的 P 和 R,最后用这个计算 F1 score
- Micro:合并多个类别的统计结果到一个表格里面,在分别算 P 和 R 和 F1 score
配合后面的例子
食用
- F1 score 永远在 precision 和 recall 之间,
- F1 score 会给低的部分(P or R)更多的权重,所以如果算术平均值是一样的情况下,哪个分类器的短板更短,它的 F1 就会越差
- 情况一:比如 P 和 R 分别是 60 和 60,可以算他们的 F1 score = 60
- 情况二:比如 P 和 R 分别是 50 和 70,可以看到他们和上一种情况的平均值是一样的,但是他们的 F1 score = 58.3
- 由 1. 可知:
高 F1 score 不意味着分类器更好或更适合你的任务,有时候你可能更关注 Precision 或者 Recall 这两个中的一个
| class 0 | class 1 | class 2 | |
|---|---|---|---|
| predict_class0 | 2 | 0 | 0 |
| predict_class1 | 1 | 0 | 1 |
| predict_class2 | 0 | 2 | 0 |
要先得到每一个类别的 Precision 和 Recall,先画出表格![]()
| class 0 | Not class 0 | |
|---|---|---|
| predict_class0 | 2 | 1 |
| predict_not_class0 | 0 | 3 |
| class 1 | Not class 1 | |
|---|---|---|
| predict_class1 | 0 | 2 |
| predict_not_class1 | 2 | 2 |
| class 2 | Not class 2 | |
|---|---|---|
| predict_class2 | 0 | 1 |
| predict_not_class2 | 2 | 3 |
可以得到如下的结果
- class 0:Precision = 32;Recall = 1
- class 1:Precision = 0;Recall = 0
- class 2:Precision = 0;Recall = 0
- 那么平均的 Precision 就是 32∗31=92;平均的 Recall 是 31,代入 F1 score 的计算公式可以得到 154=0.26666
将三个表格叠起来(对应位置相加),可以得到如下的表格
| class ? | Not class ? | |
|---|---|---|
| predict_class? | 2 | 4 |
| predict_not_class? | 4 | 8 |
代入公式算得 F1 score = 1/3=0.333333
from sklearn.metrics import f1_score, confusion_matrix
y_true = [0, 1, 2, 0, 1, 2]
y_pred = [0, 2, 1, 0, 0, 1]
print(confusion_matrix(y_true, y_pred)) # confusion matrix
# [[2 0 0]
# [1 0 1]
# [0 2 0]]
print(f1_score(y_true, y_pred, average='macro')) # 0.26666
print(f1_score(y_true, y_pred, average='micro')) # 0.33333