金融风控0基础入门-Task1 分类算法评价指标
评价指标:是针对将相同的数据,输入不同的算法模型,或者输入不同参数的同一种算法模型,而给出这个算法或者参数好坏的定量指标。
机器学习分类任务的常用评价指标:
- 混淆矩阵(Confuse Matrix)
- 准确率(Accuracy)
- 精确率(Precision)
- 召回率(Recall)
- P-R曲线(Precision-Recall Curve)
- F1 Score
- ROC
- AUC
混淆矩阵
用一个例子来理解混淆矩阵:
假设有一个用来对猫(cats)、狗(dogs)、兔子(rabbits)进行分类的系统,混淆矩阵就是为了进一步分析性能而对该算法测试结果做出的总结。假设总共有 27 只动物:8只猫, 6条狗, 13只兔子。结果的混淆矩阵如下图:
在这个混淆矩阵中,实际有 8只猫,但是系统将其中3只预测成了狗;对于 6条狗,其中有 1条被预测成了兔子,2条被预测成了猫。从混淆矩阵中我们可以看出系统对于区分猫和狗存在一些问题,但是区分兔子和其他动物的效果还是不错的。所有正确的预测结果都在对角线上,所以从混淆矩阵中可以很方便直观的看出哪里有错误,因为他们呈现在对角线外面。
形式:
sklearn.metrics.confusion_matrix(y_true,y_pred, labels=None, sample_weight=None)
返回一个混淆矩阵;
labels:混淆矩阵的索引(如上面猫狗兔的示例),如果没有赋值,则按照y_true, y_pred中出现过的值排序。
混淆代码如下:
import pandas as pd
from sklearn.metrics import confusion_matrix
y_true = [2, 0, 2, 2, 0, 1]
y_pred = [0, 0, 2, 2, 0, 2]
confusion_matrix(y_true, y_pred)
# array([[2,0, 0],
# [0, 0, 1],
# [1, 0, 2]])
y2_true = ["cat", "ant", "cat", "cat","ant", "bird"]
y2_pred = ["ant", "ant", "cat", "cat","ant", "cat"]
confusion_matrix(y_true, y_pred, labels=["ant", "bird","cat"])
# array([[2,0, 0],
# [0, 0, 1],
# [1, 0, 2]])
准确率(Accuracy)
准确率的定义是预测正确的结果占样本的百分比
A c c u r a c y = T P + T N T P + T N + F P + F N Accuracy = \frac{TP+TN}{TP+TN+FP+FN} Accuracy=TP+TN+FP+FNTP+TN其中:
- 真正例(True Positive, TP):被模型预测为正的正样本;
- 假正例(False Positive, FP):被模型预测为正的负样本;
- 假负例(False Negative, FN):被模型预测为负的正样本;
- 真负例(True Negative, TN):被模型预测为负的负样本;
代码如下:
import pandas as pd
# 2.分类准确率分数
from sklearn.metrics import accuracy_score
y_pred = [0,1,0,1]
y_true = [0,1,1,0]
# sklearn.metrics.accuracy_score(y_true, y_pred, normalize=True, sample_weight=None)
# normalize:默认值为True,返回正确分类的比例;如果为False,返回正确分类的样本数
print('ACC:', skl.metrics.accuracy_score(y_true,y_pred))
精准率(Precision)、召回率(Recall)
精准率(Precision)又叫查准率,它的含义是在所有被预测为正的样本中实际为正的样本的概率。其公式如下:
P
r
e
c
i
s
i
o
n
=
T
P
T
P
+
F
P
Precision = \frac{TP}{TP+FP}
Precision=TP+FPTP
精准率和准确率看上去有些类似,但是完全不同的两个概念。精准率代表对正样本结果中的预测准确程度,而准确率则代表整体的预测准确程度,既包括正样本,也包括负样本。
召回率(Recall)又叫查全率,它是针对原样本而言的,它的含义是在实际为正的样本中被预测为正样本的概率,其公式如下:
R
e
c
a
l
l
=
T
P
T
P
+
F
N
Recall = \frac{TP}{TP + FN}
Recall=TP+FNTP
两者关系如下图:
在不同的应用场景下,我们的关注点不同,例如:
预测股票的时候,我们更关心精准率,而在预测病患的场景下,我们更关注召回率,即真的患病的那些人里我们预测错了情况应该越少越好。
精确率和召回率是一对此消彼长的度量。在实际工程中,我们往往需要结合两个指标的结果,去寻找一个平衡点,使综合性能最大化。
精确率及召回率代码:
import pandas as pd
from sklearn.metrics import precision_score # 3.精度
from sklearn.metrics import recall_score # 4.召回
y_pred = [0,1,0,1]
y_true = [0,1,1,0]
# 精度 Precision 测试数据集必须为0,1二元 若不为则使用R2评估指标
y2_Pre = precision_score(y_true ,y_pred )
print('3.Precision:',y2_Pre)
## recall_score 召回率 = 提取出的正确信息条数 / 样本中的信息条数
print('rc:',skl.metrics.recall_score(y_true,y_pred))
P-R曲线
P-R曲线(Precision Recall Curve)是描述精确率/召回率变化的曲线,定义如下:根据学习器的预测结果(一般为一个实值或概率)对测试样本进行排序,将最可能是“正例”的样本排在前面,最不可能是“正例”的排在后面,按此顺序逐个把样本作为“正例”进行预测,每次计算出当前的P值和R值,如下图所示:
评估方法:
若一个学习器A的P-R曲线被另一个学习器B的P-R曲线完全包住,则称:B的性能优于A。若A和B的曲线发生了交叉,则谁的曲线下的面积大,谁的性能更优。但一般来说,曲线下的面积是很难进行估算的,所以衍生出了“平衡点”(Break-Event Point,简称BEP),即当P=R时的取值,平衡点的取值越高,性能更优。上图中 A > B > C
P-R曲线代码如下:
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.metrics import precision_recall_curve # 6.精确召回
y_true2 = [1,0,1,1,0,1]
y_pred2 = [0,0,1,1,0,1]
# 精确召回 precision_recall_curve()
precision2,recall2,thresholds2 = precision_recall_curve(y_true2,y_pred2)
print('pre:',precision2)
print('recall:',recall2)
print('thresholds:',thresholds2)
# P-R曲线 精确召回曲线
plt.plot(precision2,recall2)
plt.show()
F1-Score
Precision 和 Recall 指标有时是此消彼长的,即精准率高了,召回率就下降,在一些场景下要兼顾精准率和召回率,最常见的方法就是 F-Measure,又称 F-Score。F-Measure 是 P 和 R 的加权调和平均,即:
1
F
β
=
1
1
+
β
2
⋅
(
1
P
+
β
2
R
)
\frac{1}{F_\beta} = \frac{1}{1+\beta^2}\cdot(\frac{1}{P}+\frac{\beta^2}{R})
Fβ1=1+β21⋅(P1+Rβ2)
F
β
=
(
1
+
β
2
)
×
P
×
R
(
β
2
×
P
)
+
R
F_\beta = \frac{(1+\beta^2)\times{P}\times{R}}{(\beta^2\times{P})+R}
Fβ=(β2×P)+R(1+β2)×P×R
当β=1时,也就是常见的F1-Score,是P和R的调和平均,当F1较高时,模型的性能越好。
1
F
1
=
1
2
⋅
(
1
P
+
1
R
)
\frac{1}{F_1} = \frac{1}{2}\cdot(\frac{1}{P} + \frac{1}{R})
F11=21⋅(P1+R1)
F
1
=
2
×
P
×
R
P
+
R
=
2
×
T
P
样
例
总
数
+
T
P
−
T
N
F_1=\frac{2\times{P}\times{R}}{P+R}=\frac{2\times{TP}}{样例总数+TP-TN}
F1=P+R2×P×R=样例总数+TP−TN2×TP
F1-Score分数代码如下:
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.metrics import f1_score # 5.F1-score F1分数
y_true2 = [1,0,1,1,0,1]
y_pred2 = [0,0,1,1,0,1]
# 5.F1-Score分数
y2_F1_score = f1_score(y_true2,y_pred2)
print('F1_score:',y2_F1_score)
ROC曲线
在实际的数据集中经常会出现类别不平衡(Class Imbalance)现象,即负样本比正样本多很多(或者相反),而且测试数据中的正负样本的分布也可能随着时间变化,ROC以及AUC可以很好的消除样本类别不平衡对指标结果产生的影响。
- ROC曲线有个很好的特性:当测试集中的正负样本的分布变化的时候,ROC曲线能够保持不变。
- ROC和上面提到的P-R曲线一样,是一种不依赖于阈值(Threshold)的评价指标
灵敏度(sensitivity)和特异度(specificity),也叫做真正率(TPR)和假正率(FPR),这两个指标的选择使得ROC可以无视样本的不平衡,具体公式如下。
- 真正率(True Positive Rate , TPR),又称灵敏度:
T P R = 正 样 本 预 测 正 确 数 正 样 本 总 数 = T P T P + F N TPR = \frac{正样本预测正确数}{正样本总数}=\frac{TP}{TP+FN} TPR=正样本总数正样本预测正确数=TP+FNTP
其实我们可以发现灵敏度和召回率是一模一样的,只是名字不同 - 假负率(False Negative Rate , FNR) :
F N R = 正 样 本 预 测 错 误 数 正 样 本 总 数 = F N T P + F N FNR = \frac{正样本预测错误数}{正样本总数}=\frac{FN}{TP+FN} FNR=正样本总数正样本预测错误数=TP+FNFN - 假正率(False Positive Rate , FPR) :
F P R = 负 样 本 预 测 错 误 数 负 样 本 总 数 = F P T N + F P FPR = \frac{负样本预测错误数}{负样本总数}=\frac{FP}{TN+FP} FPR=负样本总数负样本预测错误数=TN+FPFP - 真负率(True Negative Rate , TNR),又称特异度:
T N R = 负 样 本 预 测 正 确 数 负 样 本 总 数 = T N T N + F P TNR = \frac{负样本预测正确数}{负样本总数}=\frac{TN}{TN+FP} TNR=负样本总数负样本预测正确数=TN+FPTN
分析上述公式,我们可以可看出,灵敏度(真正率)TPR是正样本的召回率,特异度(真负率)TNR是负样本的召回率,而假负率 F N R = 1 − T P R 、假正率 F P R = 1 − T N R ,上述四个量都是针对单一类别的预测结果而言的,所以对整体样本是否均衡并不敏感。
ROC(Receiver Operating Characteristic)曲线,又称接受者操作特征曲线。ROC曲线中的主要两个指标就是真正率TPR和假正率FPR,其中横坐标为假正率(FPR),纵坐标为真正率(TPR),下面就是一个标准的ROC曲线图。
ROC代码如下:
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.metrics import roc_curve # 7.roc
y_true2 = [1,0,1,1,0,1]
y_pred2 = [0,0,1,1,0,1]
# 7.ROC
y2_roc = roc_curve(y_true2,y_pred2)
print(y2_roc)
roc_fpr,roc_tpr,roc_thresholds = y2_roc
print('FPR:',roc_fpr)
print('TPR:',roc_tpr)
print('thresholds:',roc_thresholds)
# roc曲线
plt.figure()
plt.rcParams['font.sans-serif']=['SimHei']
plt.title('ROC曲线')
plt.xlabel('FPR')
plt.ylabel('TPR')
plt.plot(roc_fpr,roc_tpr)
plt.plot([0,1],[0,1])
plt.show()
AUC
AUC(Area Under Curve)又称为曲线下面积,是处于ROC Curve下方的那部分面积的大小。
ROC曲线下方面积越大表明模型性能越好,于是AUC就是由此产生的评价指标。通常,AUC的值介于0.5到1.0之间,较大的AUC代表了较好的Performance。如果模型是完美的,那么它的AUC = 1,证明所有正例排在了负例的前面,如果模型是个简单的二类随机猜测模型,那么它的AUC = 0.5,如果一个模型好于另一个,则它的曲线下方面积相对较大,对应的AUC值也会较大。
AUC代码如下:
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.metrics import roc_auc_score # 8.auc
y_true2 = [1,0,1,1,0,1]
y_pred2 = [0,0,1,1,0,1]
# 8.AUC
y2_auc = roc_auc_score(y_true2,y_pred2)
print(y2_auc)