记法:第一个字母代表,代表预测正确与否,第二个字母代表预测的结果是正例还是负例。 例如TP,P代表正例,即预测为P(正例),预测结果为T(正确)
正负样本自己定义,例如故障为1,正常为0,也可以反过来。
所以对于二分类,根据给哪一类不同的正负样本定义,混淆矩阵也不一样。
A c c u r a c y = 预 测 的 正 确 样 本 总 数 样 本 总 数 = T P + T N T P + T N + F P + F N Accuracy=\frac{预测的正确样本总数}{样本总数} =\frac{TP+TN}{TP+TN+FP+FN} Accuracy=样本总数预测的正确样本总数=TP+TN+FP+FNTP+TN
如果特别关注正类或者负类有没有被检测出来,这个并不适用。
在预测的正样本总数中,是真正的正样本所占的比例。
(在预测的正样本总数中,预测对的所占的比例。)
P r e c i s i o n = 预 测 为 正 样 本 且 预 测 对 的 个 数 预 测 为 正 样 本 的 个 数 = T P T P + F P Precision =\frac{预测为正样本且预测对的个数}{预测为正样本的个数}= \frac{TP}{TP+FP} Precision=预测为正样本的个数预测为正样本且预测对的个数=TP+FPTP
代表预测的正样本中有多少是预测对了。
在实际的正样本中,被预测为正样本的比例。
R e c a l l = 预 测 为 正 样 本 的 个 数 实 际 为 正 样 本 的 个 数 = T P T P + F N Recall=\frac{预测为正样本的个数}{实际为正样本的个数}= \frac{TP}{TP+FN} Recall=实际为正样本的个数预测为正样本的个数=TP+FNTP
宁愿把负样本预测为正样本,也不愿把实际为正样本的预测错误。
宁可检错,也不可能放过一个正样本。
比如得病或者故障检错,宁愿把正常检测成得病或者故障,也不愿意把真正得病或者故障的样本检测为正常。
Precision和Recall是此消彼长的,如果要兼顾二者,就需要 F1 Score,即为一种调和平均数。
主要用于二分类问题。
F 1 = 2 ∗ P ∗ R P + R F1 = \frac{2*P*R}{P+R} F1=P+R2∗P∗R
F β = ( 1 + β 2 ) ∗ P ∗ R β 2 ∗ P + R F_β = \frac{(1+β^2)*P*R}{β^2*P+R} Fβ=β2∗P+R(1+β2)∗P∗R
β是影响Recall和Precison的权重比。当β=2即 F 2 F_2 F2时表明Recall的权重要比Precision高。反之,当β=0.5即 F 0.5 F_{0.5} F0.5时表明Precison的权重要比Recall高。
对于一个多分类问题可以按照每一类都是二分类的问题,比如狗、猫、鸡三类可以看成【是否为狗类(0 or 1),是否为猫类(0 or 1),是否为鸡类(0 or 1)】,每一个类别 i i i,都有 T P i , F P i , T N i , F N i TP_i, FP_i, TN_i, FN_i TPi,FPi,TNi,FNi,所以对于多分类的F1有 宏平均(Macro F1)、微平均(Micro F1)。
R e c a l l m a c r o Recall_{macro} Recallmacro同理,其中L为类别的总数。
所以,
M a c r o F 1 = 2 ∗ P r e c i s i o n m a c r o ∗ R e c a l l m a c r o P r e c i s i o n m a c r o + R e c a l l m a c r o Macro F1 = \frac{2*Precision_{macro}*Recall_{macro}}{Precision_{macro}+Recall_{macro}} MacroF1=Precisionmacro+Recallmacro2∗Precisionmacro∗Recallmacro
宏平均可以看出比较注重大局观,本质上是所有类别的统计指标求平均值,缺点为忽略掉了样本间可能存在的极大样本不均衡情况。
所以,
M i c r o F 1 = 2 ∗ P r e c i s i o n m i c r o ∗ R e c a l l m i c r o P r e c i s i o n m i c r o + R e c a l l m i c r o Micro F1 = \frac{2*Precision_{micro}*Recall_{micro}}{Precision_{micro}+Recall_{micro}} MicroF1=Precisionmicro+Recallmicro2∗Precisionmicro∗Recallmicro
Micro考虑到了样本不均衡的情况。
总结:①类别比较均衡,都可以。②认为样本多的类别更重要,使用Micro。③认为样本少的类别也同样重要,使用Macro。
所以 m i c r o < < m a c r o micro << macro micro<<macro时,样本多的类别严重出现了分类错误。
所以 m a c r o < < m i c r o macro << micro macro<<micro时,样本多的类别严重出现了分类错误。
Recall同理。
M a c r o w e i g h t e d F 1 = 2 ∗ P r e c i s i o n w e i g h t e d ∗ R e c a l l w e i g h t e d P r e c i s i o n w e i g h t e d + R e c a l l w e i g h t e d Macro{\ }weighted{\ }F1 = \frac{2*Precision_{weighted}*{Recall_{weighted}}}{Precision_{weighted}+Recall_{weighted}} Macro weighted F1=Precisionweighted+Recallweighted2∗Precisionweighted∗Recallweighted
ROC曲线对角线的位置表示模型预测的效果和随机猜测的效果一样差。
ROC曲线在测试样本分布变化时能够保持不变。
0.5 < A U C < 1 0.5
0.5<AUC<1 :设订好分类阈值,有预测价值;
A U C = 1 AUC=1 AUC=1:在0.5附近,几乎没有预测价值,因为随机预测也是0.5;
A U C < 0.5 AUC<0.5 AUC<0.5:还不如随机预测,可以反向预测,还有点价值。
AUC相等不代表模型效果相同,因为只是ROC曲线下的面积相等,不能代表ROC曲线是完全一样的。
sklearn库的评价指标包为:from sklearn.metrics import xxx
深度学习中,一般输出的结果都是一个batch size 输出的,如果要统计全部样本,就需要每次把batch size的结果使用list 或np array存储起来,因为sklearn的y_ture和y_pred都要求是一维的,所以一般设置一个全局的
all_labels = np.array([], dtype=int)
,并使用np.append()方法存储每次batch size的结果,最后再进行计算。
不同库的混淆矩阵的顺序不一样,以上图为sklearn库中的混淆矩阵index的逻辑。
sklearn.metrics.confusion_matrix((y_true, y_pred, *, labels=None, sample_weight=None, normalize=None)
y_true: 真实类别标签,如[0, 0, 3, 1, 2],一维的。
y_pred: 预测的类别标签,如[1, 0, 3, 1, 1],一维的。
labels: ①可以按照给定的labels顺序排序(混淆矩阵中的哪一类在第一列);②可以任意选择所有类别的子集的几个类别求得混淆矩阵。
sample_weight:
normalize: 对混淆矩阵进行归一化。可选参数{‘true’, 'pred', 'all' }, defaut=None
。true
为按行进行归一化,pred
为按列进行归一化,all
为按照全局的混淆矩阵进行归一化。
return: 返回混淆矩阵
# 多分类的混淆矩阵
from sklearn.metrics import confusion_matrix
y_pred = [0, 0, 2, 2, 0, 2]
y_true = [2, 0, 2, 2, 0, 1]
confusion_mat = confusion_matrix(y_true, y_pred)
print(confusion_mat)
# result
[[2 0 0]
[0 0 1]
[1 0 2]]
如果分类的标签没有转为数字即0,1,2…,则可以通过设置
labels=["cat", "dog", "bird"]
等等,labels
列表中的顺序即用0,1,2…的顺序。
# 二分类的混淆矩阵
from sklearn.metrics import confusion_matrix
y_pred = [1, 1, 1, 0]
y_true = [0, 1, 0, 1]
confusion_mat = confusion_matrix(y_true, y_pred)
confusion_mat_ravel = confusion_matrix(y_true, y_pred).ravel()
print(confusion_mat)
print(confusion_mat_ravel) # (tn, fp, fn, tp)
# confusion_mat
[[0 2]
[1 1]]
# confusion_mat_ravel # (tn, fp, fn, tp)
[0 2 1 1]
多类别 or 多标签的混淆矩阵
sklearn.metrics.multilabel_confusion_matrix
用于输出一个各个评估指标的报告。
sklearn.metrics.classification_report(y_true, y_pred, *, labels=None, target_names=None, sample_weight=None, digits=2, output_dict=False, zero_division='warn')[source]
y_true: 一维。
y_pred: 一维。
labels: 选择哪些类别需要计算report。default=None
。
**target_names:**输出的report中使用这个代替数字化的类别,使得读者理解0,1,2…这些数字代表的是cat,dog or bird。
output_dict: bool,选择是否以字典dict的形式输出。
zero_division: 如果有0作为除数是否作为警告。
#sklearn.metrics.accuracy_score(y_true, y_pred, *, normalize=True, sample_weight=None)[source]
from sklearn.metrics import accuracy_score
balanced accuracy score
针对数据不均衡,进行计算。首先计算每一个类别的accuracy,然后相加求和,除以类别总数求平均。
#sklearn.metrics.accuracy_score(y_true, y_pred, *, normalize=True, sample_weight=None)[source]
from sklearn.metrics import balanced_accuracy_score
(y_true, y_pred, *, labels=None, pos_label=1, average='binary', sample_weight=None, zero_division='warn'
)
这些参数的含义:
pos_label:
针对的是二分类的问题,谁知正类用1表示还是0表示。
average:
可选参数有{micro’, ‘macro’, ‘samples’, ‘weighted’, ‘binary’} or None, default=’binary’},这个一般应用于多标签多分类问题。weighted可以理解为按照类别增加权重,samples可以理解为按照样本增加权重。
#sklearn.metrics.precision_score(y_true, y_pred, *, labels=None, pos_label=1, average='binary', sample_weight=None, zero_division='warn')
#注意:要指定 pos_label是0还是1,默认情况按照1.
from sklearn.metrics import precision_score
用于输出一个各个评估指标的报告。
from sklearn.metrics import recall_score
from sklearn.metrics import f1_score
#sklearn.metrics.auc(x, y)
#x:真实标签,单调递增或递减。 y:预测标签的概率
>>> import numpy as np
>>> from sklearn import metrics
>>> y = np.array([1, 1, 2, 2])
>>> pred = np.array([0.1, 0.4, 0.35, 0.8])
>>> fpr, tpr, thresholds = metrics.roc_curve(y, pred, pos_label=2)
>>> metrics.auc(fpr, tpr)
0.75