以下四个可以这样理解,第一个字母代表你预测的对错T/F,第二个字母代表你预测的是正还是负P/N。例如TP=你预测的是正的,且预测对了。
真正例/真阳性(TP):预测为正,实际为正,预测对了。
真负例/真阴性(TN):预测为负,实际为负,预测对了。
假正例/假阳性(FP):预测为正,实际为负,预测错了。
假负例/假阴性(FN):预测为负,实际为正,预测错了。
所谓正负指的是,对某一类,你认为它是这一类或不是,也就是说每一类都需要计算一遍这四个指标。
比如三类问题
你预测的:
1 | 2 | 3 | 1 | 2 | 3 | 1 | 2 | 3 | 1 |
---|
实际分类:
1 | 1 | 2 | 2 | 2 | 3 | 3 | 3 | 3 | 3 |
---|
对于1类:
TP = 1, TN = 5, FP = 3, FN = 1
对于其它两类同理
准确率(accuracy):(TP + TN) / (TP + TN + FP + FN),分母就是你预测的全部数据P’+N’
精准率(precision):TP / (TP + FP),分母就是你预测的全部正数据P’
召回率(recall):TP / P,真实数据中全部正数据
其中P’和N’表示你预测的正负类,P和N表示真实正负类。往往预测数据与真实数据数量相等,P’和P不需要区分,但如果预测数量与真实数量不等,则需要区分。
接着上面的例子:
总的准确率:
accuracy = 4 / 10 = 0.4
对于1类:
precision = 1 / (1 + 3) = 0.25
recall = 1 / 2 = 0.5
其余两类同理
就是把上面几个值组合一下显示到矩阵中
真实\预测 | 正 | 负 | 合计 |
---|---|---|---|
正 | TP | FN | P |
负 | FP | TN | N |
合计 | P’ | N’ | P+N |
一般多类问题的混淆矩阵不用上述正负,而是计算每个类别的值,用上面例子给出
真实\预测 | 1类 | 2类 | 3类 |
---|---|---|---|
1类 | 1 | 1 | 0 |
2类 | 1 | 1 | 1 |
3类 | 2 | 1 | 2 |
F = (2 * precision * recall) / (precision + recall)
接收者操作特征(Receiver Operating Characteristic, ROC)是比较两个分类模型的可视化工具。计算方式:
TPR = TP / P
FPR = FP / N
你预测的不是分类而是正样本的概率,把这个概率从大到小排序,把每个概率作为一个阈值(大于阈值看为正样本,小于阈值看为负样本),这样每一个阈值都能对应得到一组TPR和FPR(存在概率相等的,只算作一个阈值),把FPR做横轴TPR做纵轴,就能画出一条锯齿型的曲线,可以用一些方法来拟合这条曲线,就是ROC曲线。
预测的数据
0.1 | 0.5 | 0.8 | 0.7 | 0.4 | 0.1 | 0.3 | 0.5 | 0.4 | 0.2 |
---|
真实的数据
0 | 1 | 1 | 1 | 0 | 0 | 1 | 0 | 0 | 1 |
---|
排序
真实 | 预测 | TP | FP | TN | FN | TPR | FPR |
---|---|---|---|---|---|---|---|
1 | 0.8 | 1 | 0 | 5 | 4 | 0.2 | 0 |
1 | 0.7 | 2 | 0 | 5 | 3 | 0.4 | 0 |
1 | 0.5 | 3 | 1 | 4 | 2 | 0.6 | 0.2 |
0 | 0.5 | 3 | 1 | 4 | 2 | 0.6 | 0.2 |
0 | 0.4 | 3 | 3 | 2 | 2 | 0.6 | 0.6 |
0 | 0.4 | 3 | 3 | 2 | 2 | 0.6 | 0.6 |
1 | 0.3 | 4 | 3 | 2 | 1 | 0.8 | 0.6 |
1 | 0.2 | 5 | 3 | 2 | 0 | 1 | 0.6 |
0 | 0.1 | 5 | 5 | 0 | 0 | 1 | 1 |
0 | 0.1 | 5 | 5 | 0 | 0 | 1 | 1 |
x = [0 0 0.2 0.6 0.6 0.6 1 1]
y = [0.2 0.4 0.6 0.6 0.8 1 1]
thresholds = [0.8 0.7 0.5 0.4 0.3 0.2 0.1]
用这个x y就可以画ROC曲线
ROC曲线下面的面积
python的sklearn.metrics包提供了充足的评价指标计算方法
数据准备:
import numpy as np
from sklearn import metrics
pred_prob = [0.1, 0.5, 0.8, 0.7, 0.4, 0.1, 0.3, 0.5, 0.4, 0.2] # 预测二分类的概率
real_prob = [0, 1, 1, 1, 0, 0, 1, 0, 0, 1] # 真实二分类
pred_bin = [0, 1, 1, 0, 0, 1, 1, 1, 0, 1] # 预测二分类
pred = [1,2,3,1,2,3,1,2,3,1] # 预测多分类
real = [1,1,2,2,2,3,3,3,3,3] # 真实多分类
准确率、召回率、精准率、F1值
accuracy1 = metrics.accuracy_score(real, pred) # 多分类,返回准确率
accuracy2 = metrics.accuracy_score(real, pred, normalize=False) # 多分类,返回正确分类的数量
accuracy3 = metrics.accuracy_score(real_prob, pred_bin) # 二分类
recall1 = metrics.recall_score(real, pred, labels=[1,2,3], average=None) # 多分类召回率,返回每个分类的召回率
recall2 = metrics.recall_score(real, pred, labels=[1,2,3], average="micro") # 平均值的召回率,就是先把TP和P取均值再计算
recall3 = metrics.recall_score(real, pred, labels=[1,2,3], average="macro") # 三个召回率的平均值
recall4 = metrics.recall_score(real_prob, pred_bin, pos_label=0) # 二分类召回率,返回0的召回率
precision1 = metrics.precision_score(real, pred, labels=[1,2,3], average=None) # 多分类精准率,返回每个分类的精准率
precision2 = metrics.precision_score(real, pred, labels=[1,2,3], average="micro") # 平均值的精准率,就是先把TP和P取均值再计算
precision3 = metrics.precision_score(real, pred, labels=[1,2,3], average="macro") # 三个精准率的平均值
precision4 = metrics.precision_score(real_prob, pred_bin, pos_label=0) # 二分类精准率,返回0的精准率
f1score1 = metrics.f1_score(real, pred, labels=[1,2,3], average=None) # 多分类f1_score,返回每个分类的精准率
f1score2 = metrics.f1_score(real, pred, labels=[1,2,3], average="micro") # 平均值的f1_score,就是先把TP和P取均值再计算
f1score3 = metrics.f1_score(real, pred, labels=[1,2,3], average="macro") # 三个f1_score的平均值
f1score4 = metrics.f1_score(real_prob, pred_bin, pos_label=0) # 二分类f1_score,返回0的精准率
print(accuracy1, accuracy2, accuracy3)
print(recall1)
print(recall2, recall3, recall4)
print(precision1)
print(precision2, precision3, precision4)
print(f1score1, 2*precision1*recall1 / (precision1 + recall1))
print(f1score2, 2*precision2*recall2 / (precision2 + recall2))
print(f1score3, f1score1.mean())
print(f1score4, 2*precision4*recall4 / (precision4 + recall4))
结果:
0.4 4 0.7
[0.5 0.33333333 0.4 ]
0.4 0.41111111111111115 0.6
[0.25 0.33333333 0.66666667]
0.4 0.4166666666666667 0.75
[0.33333333 0.33333333 0.5 ] [0.33333333 0.33333333 0.5 ]
0.4000000000000001 0.4000000000000001
0.38888888888888884 0.38888888888888884
0.6666666666666665 0.6666666666666665
混淆矩阵:
confusion_matrix1 = metrics.confusion_matrix(real, pred, labels=[1, 2, 3]) # 多分类混淆矩阵
confusion_matrix2 = metrics.confusion_matrix(real_prob, pred_bin, labels=[0, 1]) # 二分类混淆矩阵
print(confusion_matrix1)
print(confusion_matrix2)
结果:
[[1 1 0]
[1 1 1]
[2 1 2]]
[[3 2]
[1 4]]
ROC、AUC:
fpr, tpr, thresholds = metrics.roc_curve(real_prob, pred_prob, pos_label=1) # roc曲线的FPR, TPR和阈值
auc1 = metrics.auc(fpr, tpr)
auc2 = metrics.roc_auc_score(real_prob, pred_prob, average=None) # 应该是可以计算多类情况,不尝试了
print(fpr, tpr, thresholds)
print(auc1, auc2)
结果:
[0. 0. 0.2 0.6 0.6 1. ] [0.2 0.4 0.6 0.6 1. 1. ] [0.8 0.7 0.5 0.4 0.2 0.1]
0.74 0.74