承接上文《混杂矩阵》,本文经过混杂矩阵获取几个常见的评估目标准确率(Accuracy)、精确度(Precision、召回率(Recall)、F1(F-score)。运用sklearn、tensorflow和手搓混杂矩阵这3种方法进行目标的核算
import sklearn
import numpy as np
import seaborn as sns
import tensorflow as tf
from matplotlib import pyplot as plt
Accuracy 准确率
sklearn.metrics.accuracy_score 核算
# 设置猜测成果
pred = [0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5]
# 设置正确标签
true = [0, 1, 2, 3, 1, 5, 0, 1, 2, 3, 1, 5, 0, 1, 2, 3, 4, 5]
accuracy = sklearn.metrics.accuracy_score(y_true=true, y_pred=pred)
print(accuracy)
==============================
输出:
0.8888888888888888
tf.keras.metrics.Accuracy 核算
accuracy = tf.keras.metrics.Accuracy()
accuracy.update_state(y_true=true, y_pred=pred)
print(accuracy.result().numpy())
==============================
输出:
0.8888889
Precision 精准度
sklearn.metrics.precision_score 核算
precision = sklearn.metrics.precision_score(y_true=true, y_pred=pred, average='macro')
print(precision)
==============================
输出:
0.8888888888888888
tf.keras.metrics.Precision 核算
precision = tf.keras.metrics.Precision()
precision.update_state(y_true=tf.one_hot(true,6), y_pred=tf.one_hot(pred,6))
print(precision.result().numpy())
==============================
输出:
0.8888889
Recall 召回率
sklearn.metrics.recall_score 核算
recall = sklearn.metrics.recall_score(y_true=true, y_pred=pred, average='micro')
print(recall)
==============================
输出:
0.8888888888888888
tf.keras.metrics.Recall 核算
recall = tf.keras.metrics.Recall()
recall.update_state(y_true=tf.one_hot(true,6), y_pred=tf.one_hot(pred,6))
print(recall.result().numpy())
==============================
输出:
0.8888889
F1 F-score
sklearn.metrics.f1_score
f1 = sklearn.metrics.f1_score(y_true=true, y_pred=pred, average='macro')
print(f1)
==============================
输出:
0.875
tf.keras.metrics.F1Score
f1 = tf.keras.metrics.F1Score(average='macro')
f1.update_state(y_true=tf.one_hot(true,6), y_pred=tf.one_hot(pred,6))
print(f1.result().numpy())
==============================
输出:
0.875
手搓混杂矩阵
对于核算得到的混杂矩阵,手搓核算准确率(Accuracy)、精确度(Precision、召回率(Recall)、F1(F-score)
别问为啥手搓的目标和sklearn、tensorflow核算的有收支,笔者也不知道呀
构造混杂矩阵
先得出混杂矩阵,对各个类别核算TP、TN、FP、FN,进一步的去核算这些杂七杂八的目标
构造混杂矩阵这里就看懵的,先去look look《混杂矩阵》吧
cm = sklearn.metrics.confusion_matrix(y_true=true, y_pred=pred)
print(cm)
# 核算混杂矩阵的总和
total = np.sum(cm)
# 核算那条深色斜线的总和
line = np.sum([cm[i, i] for i in range(len(cm))])
# 储存每个类别的 TP TF NP NF
classes_list = []
for i in range(len(cm)):
TP = cm[i, i]
TN = line - TP
FP = sum(cm[:, i]) - TP
FN = total - TP - TN - FP
classes_list.append({i: {'tp': TP, 'tn': TN, 'fp': FP, 'fn': FN}})
classes_list
==============================
输出:
[[3 0 0 0 0 0]
[0 3 0 0 2 0]
[0 0 3 0 0 0]
[0 0 0 3 0 0]
[0 0 0 0 1 0]
[0 0 0 0 0 3]]
[{0: {'tp': 3, 'tn': 13, 'fp': 0, 'fn': 2}},
{1: {'tp': 3, 'tn': 13, 'fp': 0, 'fn': 2}},
{2: {'tp': 3, 'tn': 13, 'fp': 0, 'fn': 2}},
{3: {'tp': 3, 'tn': 13, 'fp': 0, 'fn': 2}},
{4: {'tp': 1, 'tn': 15, 'fp': 2, 'fn': 0}},
{5: {'tp': 3, 'tn': 13, 'fp': 0, 'fn': 2}}]
手搓 Accuracy
Accuracy=TP+TNTP+TN+FP+FNAccuracy = frac{TP+TN}{TP+TN+FP+FN}
方法1
mean = 0
for element in classes_list:
# 获取各个类别的 TP TN FP FN
tp, tn, fp, fn = list(element.values())[0].values()
# 核算 Accuracy
print(f'类别{list(element.keys())[0]} Accuracy={(tp+tn)/(tp+tn+fp+fn)}')
mean+=(tp+tn)/(tp+tn+fp+fn)
print(f'n均匀 Accuracy={mean/6}')
==============================
输出:
类别0 Accuracy=0.8888888888888888
类别1 Accuracy=0.8888888888888888
类别2 Accuracy=0.8888888888888888
类别3 Accuracy=0.8888888888888888
类别4 Accuracy=0.8888888888888888
类别5 Accuracy=0.8888888888888888
均匀 Accuracy=0.888888888888889
方法2
total = len(pred)
correct = tf.math.count_nonzero(tf.equal(pred, true)).numpy()
accuracy = correct/total
print(accuracy)
==============================
输出:
0.8888888888888888
手搓 Precision
Precision=TPTP+FPPrecision= frac{TP}{TP+FP}
mean = 0
for element in classes_list:
# 获取各个类别的 TP TN FP FN
tp, tn, fp, fn = list(element.values())[0].values()
# 核算 Precision
print(f'类别{list(element.keys())[0]} Precision={(tp)/(tp+fp)}')
mean += (tp)/(tp+fp)
print(f'均匀 Precision={mean/6}')
==============================
输出:
类别0 Precision=1.0
类别1 Precision=1.0
类别2 Precision=1.0
类别3 Precision=1.0
类别4 Precision=0.3333333333333333
类别5 Precision=1.0
均匀 Precision=0.8888888888888888
手搓 Recall
Recall=TPTP+FNRecall = frac{TP}{TP+FN}
mean = 0
for element in classes_list:
# 获取各个类别的 TP TN FP FN
tp, tn, fp, fn = list(element.values())[0].values()
# 核算 Recall
print(f'类别{list(element.keys())[0]} Recall={(tp)/(tp+fn)}')
mean += (tp)/(tp+fn)
print(f'均匀 Recall={mean/6}')
==============================
输出:
类别0 Recall=0.6
类别1 Recall=0.6
类别2 Recall=0.6
类别3 Recall=0.6
类别4 Recall=1.0
类别5 Recall=0.6
均匀 Recall=0.6666666666666666
手搓 F1
F1=2∗precision∗recallprecision+recallF1 = 2 * frac{precision * recall}{precision + recall}
mean = 0
for element in classes_list:
# 获取各个类别的 TP TN FP FN
tp, tn, fp, fn = list(element.values())[0].values()
# 核算 Precision、Recall
precision = (tp)/(tp+fp)
recall = (tp)/(tp+fn)
print(f'类别{list(element.keys())[0]} F1={2*(precision*recall)/(precision+recall)}')
mean+=2*(precision*recall)/(precision+recall)
print(f'均匀 F1={mean/6}')
==============================
输出:
类别0 F1=0.7499999999999999
类别1 F1=0.7499999999999999
类别2 F1=0.7499999999999999
类别3 F1=0.7499999999999999
类别4 F1=0.5
类别5 F1=0.7499999999999999
均匀 F1=0.7083333333333331