前言
T P TP TP,即 T r u e P o s i t i v e True\ Positive True Positive,表示实际是正类,同时也被判定为正类;
真正例
F P FP FP,即 F a l s e P o s i t i v e False\ Positive False Positive,表示实际是负类,但被判定为正类;第一类错误 ( T y p e I E r r o r ) (Type \ I\ Error) (Type I Error)假正例(误检)
T N TN TN,即 T r u e N e g a t i v e True\ Negative True Negative,表示实际是负类,同时也被判定为负类;真负例
F N FN FN,即 F a l s e N e g a t i v e False\ Negative False Negative,表示实际是正类,但被判定为负类。第二类错误 ( T y p e I I E r r o r ) (Type \ II\ Error) (Type II Error)假负例(漏检)
1. 准确率
准确率(accuracy)
是分类问题中最常用的度量。使用准确率时,我们要求算法返回明确的类别。准确率的定义如下:
a
c
c
u
r
a
c
y
=
正确分类的样本数
总样本数
accuracy=\frac {正确分类的样本数} {总样本数}
accuracy=总样本数正确分类的样本数 有上述定义可知,准确率的取值区间为
[
0
,
1
]
[0,1]
[0,1],取值越大,分类效果越好。
在实际应用中,只用准确率一项来衡量分类结果会有失偏颇。比如,如果在分类问题中有一类样本占大多数,而分类的重点在样本数较少的那一类,那么简单计算准确率并不能较好地反映算法的性能。举个栗子:
假设我们有一个包含100个样本的数据集,其中97个是正常交易,3个是欺诈交易。如果算法 A A A 将所有样本都判定为正常交易,而算法 B B B 将8个样本判定为欺诈交易(包括3个真正的欺诈交易),根据准确率的计算公式,算法 A A A 的准确率为0.97,算法 B B B 的准确率为0.95。虽然算法 A A A 的准确率更高,但是它本质上没有给我们提供关于欺诈的任何有效信息,算法 B B B 的准确率虽然较低些,它是我们认为算法 B B B 在这个人物场景中更适用。
2. 混淆矩阵
混淆矩阵(confusion matrix)
,又称为错误矩阵或者可能性表格。混淆矩阵全面考虑了各种错分的情况,并将分类的结果以类别a被判定为类别b的样本数为多少
的形式展示。其中,每一行代表一个实际的类别,每一列代表一个预测的类别。
根据上面的那个栗子,我们可以知道错位的分类有两种:正常的交易被判定为欺诈、欺诈的交易被判定为正常。由此可以得出算法
A
A
A 和算法
B
B
B 的混淆矩阵:
基于混淆矩阵,可以定义
T
P
R
(
T
r
u
e
P
o
s
i
t
i
v
e
R
a
t
e
)
TPR(True\ Positive\ Rate)
TPR(True Positive Rate),又称为灵敏度(sensitivity)
,表示正类样本中被正确分类的比例:
s
e
n
s
i
t
i
v
i
t
y
=
T
P
R
=
T
P
T
P
+
F
N
sensitivity=TPR=\frac {TP} {TP+FN}
sensitivity=TPR=TP+FNTP 同样可以定义
T
N
R
(
T
r
u
e
P
o
s
i
t
i
v
e
R
a
t
e
)
TNR(True\ Positive\ Rate)
TNR(True Positive Rate),又称为特异度(specificity)
,表示负类样本中被正确分类的比例:
s
p
e
c
i
f
i
c
i
t
y
=
T
N
R
=
T
N
T
N
+
F
P
specificity=TNR=\frac {TN} {TN+FP}
specificity=TNR=TN+FPTN 可以定义
F
P
R
(
F
a
l
s
e
P
o
s
i
t
i
v
e
R
a
t
e
)
FPR(False\ Positive\ Rate)
FPR(False Positive Rate),表示负类样本中被错误分类的比例:
F
P
R
=
F
P
F
P
+
T
N
FPR=\frac {FP} {FP+TN}
FPR=FP+TNFP 同样可以定义
T
N
R
(
T
r
u
e
P
o
s
i
t
i
v
e
R
a
t
e
)
TNR(True\ Positive\ Rate)
TNR(True Positive Rate),又称为特异度(specificity)
,表示负类样本中被正确分类的比例:
s
p
e
c
i
f
i
c
i
t
y
=
T
N
R
=
T
N
T
N
+
F
P
specificity=TNR=\frac {TN} {TN+FP}
specificity=TNR=TN+FPTN 根据混淆矩阵,可以计算出准确率为:
a
c
c
u
r
a
c
y
=
T
P
+
T
N
T
P
+
F
P
+
T
N
+
F
N
accuracy=\frac {TP+TN} {TP+FP+TN+FN}
accuracy=TP+FP+TN+FNTP+TN
3. 精确率
精确率(precision)
表示的是在算法判定为正类的所有样本中,真正的正类样本所占的比例,计算公式如下:
p
r
e
c
i
s
i
o
n
=
T
P
T
P
+
F
P
precision=\frac {TP} {TP+FP}
precision=TP+FPTP 精确度越高,说明在判定为正类的样本中负类样本越少,即误检的样本越少。
准确率,精确率,傻傻分不清楚???博主在这里说一下自己的记法:
准确率
:只要分类正确(准)
就可以,正类样本被判定为正类,是正确的,负类样本被判定为负类,也是正确的,这两类加起来除以总样本数就是准确率。
精确率
:注意精
字,从这一个字可以看出要更加精准,要求更加严格,只算正类样本中被判定为正类的,负类样本被判定为负类可不算,然后再除以所有被判定为正类的样本数目。
可见,我大中华文化博大精深!!!!
也叫查准率,表示的是在所有检测出的正样本中是不是实际都为正样本,即正确个数(正样本个数) / 检测到的个数(目标检测)。
4. 召回率
召回率(recall)
表示的是所有的正类样本被正确分类的比例,计算公式如下:
r
e
c
a
l
l
=
T
P
T
P
+
F
N
recall=\frac {TP} {TP+FN}
recall=TP+FNTP 召回率越高,说明正类样本被错误分类的比例越小,即漏检的样本越少。
也叫查全率,表示的是所有的正样本是不是都被检测出来了,即正确个数(正样本个数) / 标记的的个数(目标检测)。
假设某个类别有
10
个框,检测到8
个框,其中6
个预测正确,2
个预测错误,那么recall=6/10=0.6
,precision=6/8=0.75
。
5. P-R曲线
精确率和召回率是一对矛盾的度量。一般来说,精确率高时,召回率往往偏低;而召回率高时,精确率往往偏低。
举个栗子,若希望将所有好瓜尽可能多地选出来,则可通过增加选瓜的数量来实现,如果将所有西瓜都选上,那么所有的好瓜也必然都被选上了,但这样精确率就会较低; 若希望选出的瓜中好瓜比例尽可能高,则可只挑选最有把握的瓜,但这样就难免会漏掉不少好瓜,使得召回率较低。
为了更好地衡量模型的性能,这里引入了P-R曲线
,即Precision-Recall曲线
。
6. F1度量
F1度量(F1-Measure)
同时考虑了精确率和召回率,是精确率和召回率的调和平均数,计算公式如下:
F
1
=
2
1
p
r
e
c
i
s
i
o
n
+
1
r
e
c
a
l
l
=
2
×
p
r
e
c
i
s
i
o
n
×
r
e
c
a
l
l
p
r
e
c
i
s
i
o
n
+
r
e
c
a
l
l
=
2
T
P
2
T
P
+
F
P
+
F
N
F1=\frac {2} {\frac {1} {precision} + \frac {1} {recall}} \\[5pt] =\frac {2\times precision \times recall} {precision + recall} \\[5pt] =\frac {2TP} {2TP+FP+FN}
F1=precision1+recall12=precision+recall2×precision×recall=2TP+FP+FN2TP
F
1
F1
F1越高,说明精确率和召回率都较高,算法的性能越好。
7. ROC曲线
前面几个介绍的评价指标都针对于分类器的输出是离散值,即输出是明确的类别,当分类器的输出是连续值时,比如概率值,这时候我们就需要用到其他的评价标准了。
ROC曲线
,即接收者操作特征曲线
(
r
e
c
e
i
v
e
r
o
p
e
r
a
t
i
n
g
c
h
a
r
a
c
t
e
r
i
s
t
i
c
c
u
r
v
e
)
(receiver\ operating\ characteristic\ curve)
(receiver operating characteristic curve)。在
R
O
C
ROC
ROC曲线中,横坐标是
F
P
R
FPR
FPR(False Positive Rate)
,纵坐标为
T
P
R
TPR
TPR(True Positive Rate)
。使用ROC曲线的前提就是分类算法能够输出连续值。在画ROC曲线时,我们需要得到所有的分类结果,即通过调解阈值使所有样本从最初的都判定为负类到最后的都判定为正类,这样就可以得到不同的FPR和TPR的值。
在ROC曲线中,曲线越接近左上角(0,1)
,分类器的性能越好。
8. AUC
虽然ROC曲线给出了丰富的信息,但是在很多情况下,我们需要一个类似于准确率的单个值来衡量分类器模型的好坏。在实际中,经常使用ROC曲线下的面积来衡量分类算法的好坏,称为AUC
,即Area Under ROC Curve
,顾名思义,表示的是ROC曲线下的面积,其取值范围为
0
≤
A
U
C
≤
1
0\leq AUC \leq 1
0≤AUC≤1。
对于一个正常的分类器,AUC的值应该大于0.5,如果低于0.5,则说明该分类的性能还不如随机猜想。
9 代码实现
在
scikit-learn
库中包含了许多算法的评估方法,详细参数说明可以参阅官方文档。
9.1 混淆矩阵
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_wine
from sklearn.model_selection import train_test_split
from sklearn.metrics import confusion_matrix, precision_score, accuracy_score, recall_score, f1_score, roc_auc_score, roc_curve, auc
from sklearn.metrics import plot_confusion_matrix
import matplotlib.pyplot as plt
import numpy as np
winedata = load_wine()
x_train, x_test, y_train, y_test = train_test_split(winedata.data, winedata.target, test_size=0.3, random_state=1024)
rf_model = RandomForestClassifier(n_estimators=100, criterion='gini', random_state=1024)
rf_model.fit(x_train, y_train)
y_pred = rf_model.predict(x_test)
y_true = y_test
class_names = winedata.target_names
disp = plot_confusion_matrix(rf_model, x_test, y_test,
display_labels=class_names,
cmap=plt.cm.BuPu,
normalize='true')
disp.ax_.set_title(label='Normalized confusion matrix')
plt.show()
混淆矩阵可视化效果如下:
from sklearn.metrics import confusion_matrix, precision_score, accuracy_score, recall_score, f1_score, roc_auc_score, roc_curve, auc
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.ensemble import RandomForestClassifier
t1 = time.time()
rf_model = RandomForestClassifier(n_estimators=100, criterion='gini', random_state=1024, oob_score=True)
rf_model.fit(tf_idf, y_label)
y_pred = rf_model.predict(tf_idf_test)
t2 = time.time()
t = t2 - t1
accuracy = accuracy_score(y_test_label, y_pred)
c_matrix = confusion_matrix(y_test_label, y_pred)
precision = precision_score(y_test_label, y_pred, average="micro")
recall = recall_score(y_test_label, y_pred, average="micro")
f1 = f1_score(y_test_label, y_pred, average="micro")
roc_auc = roc_auc_score(y_test_label, rf_model.predict_proba(tf_idf_test), average="macro", multi_class='ovo')
print('[RF] accuracy: {0:.4f}, precision: {1:.4f}, recall: {2:.4f}, '
'f1: {3:.4f}, roc_auc: {4:.4f}, time: {5:.4f}'.format(accuracy, precision, recall, f1, roc_auc, t))