目录
一、分类模型评估指标
对于二分类问题,可将样例根据其真实类别与学习器预测的类别组合成混淆矩阵。在该矩阵中,矩阵中的行代表样例的真实类别,矩阵中的列代表预测器预测的类别(行和列所代表的可以互相交换)。利用混淆矩阵,可以将样本分为以下四种:
预测类别 | |||
0 | 1 | ||
实际类别 | 0 | TN | FP |
1 | FN | TP |
基于这四类样本,延伸出了以下模型评价指标:
1、准确率(Precision)
所有预测为正例的样本(TP+FP)中真正为正例的样本(TP)的比率,又叫“查准率”,即:
2、召回率(Recall)
所有预测样本中真正为正例的样本(TP)与样本中实际正例(TP+FN)的比值,又叫“查全率”,即:
3、P-R曲线和F1值
P-R曲线的横轴是召回率,纵轴是精确率。对于一个排序模型来说,其P-R曲线上的一个点代表着,在某一阈值下,模型将大于该阈值的结果判定为正样本, 小于该阈值的结果判定为负样本,此时返回结果对应的召回率和精确率。整条P-R曲线是通过将阈值从高到低移动而生成的。图1是P-R曲线样例图,其中实线代表模型A的P-R曲线,虚线代表模型B的P-R曲线。原点附近代表当阈值最大时模型的精确率和召回率。
图1 P-R曲线样例图
准确率和召回率是一对相矛盾的量,一种综合指标是F1值,即:
4、ROC曲线和AUC面积
(1)将所有样本的概率输出值prob按从大到小排序;
(2)从高到低依次将prob值作为阈值threshold,计算FPR(横轴)和TPR(纵轴);
(3)将FPR和TPR组成的点连接组成ROC曲线;
图2 ROC曲线样例图
ROC曲线性质:如果一条曲线完全包裹另一条曲线,则外面曲线的性能更优。(ROC曲线下面的面积称为AUC面积)
5、混淆矩阵
混淆矩阵( confusion matrix )是一种评价分类模型好坏的形象化展示工具。
如:有150个样本数据,这些数据分成3类,每类50个。分类结束后得到的混淆矩阵为:
类1 | 类2 | 类3 | |
类1 | 43 | 5 | 2 |
类2 | 2 | 45 | 3 |
类3 | 0 | 1 | 49 |
从上可以看出:如果混淆矩阵中非对角线元素全为0 ,则表示是一个完美的分类器。
二、ROC曲线和P-R曲线
1、ROC曲线
ROC曲线常用于二分类问题中的模型比较,主要表现为一种真正例率 (TPR) 和假正例率 (FPR) 的权衡。具体方法是在不同的分类阈值 (threshold) 设定下分别以TPR和FPR为纵、横轴作图。由ROC曲线的两个指标:
可以看出,当一个样本被分类器判为正例,若其本身是正例,则TPR增加;若其本身是负例,则FPR增加,因此ROC曲线可以看作是随着阈值的不断移动,所有样本中正例与负例之间的“对抗”。曲线越靠近左上角,意味着越多的正例优先于负例,模型的整体表现也就越好。
2、P-R曲线
由图1可见,当召回率接近于0时,模型A的精确率为0.9,模型B的精确率是1, 这说明模型B得分前几位的样本全部是真正的正样本,而模型A即使得分最高的几个样本也存在预测错误的情况。
并且,随着召回率的增加,精确率整体呈下降趋势。
但是,当召回率为1时,模型A的精确率反而超过了模型B。这充分说明,只用某个点对应的精确率和召回率是不能全面地衡量模型的性能,只有通过P-R曲线的整体表现,才能够对模型进行更为全面的评估。
三、绘制ROC曲线
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import precision_recall_curve, roc_curve, auc
import matplotlib.pyplot as plt
#生成样本数据
X, Y = make_classification(n_samples=1000, n_classes=2, random_state=1)
#将数据集分为训练集和测试集
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.3, random_state=1)
#使用knn算法进行训练和预测
k=5
knn = KNeighborsClassifier(n_neighbors=k)
knn.fit(X_train, Y_train)
Y_pred = knn.predict(X_test)
fpr, tpr, thresholds = roc_curve(Y_test, Y_pred)
precision, recall, thresholds = precision_recall_curve(Y_test, Y_pred)
#计算AUC值
roc_auc = auc(fpr, tpr)
pr_auc = auc(recall, precision)
#绘制ROC曲线
plt.plot(fpr, tpr, label='ROC curve (area = %0.2f)' % roc_auc)
plt.plot([0, 1], [0, 1], 'k--')
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Receiver operating characteristic')
plt.legend(loc="lower right")
plt.show()
k=5 k=20
k=50 k=100
由图可知,在一定范围内随着k的增大,ROC曲线下的面积AUC越大,性能越好;但超过一定范围,AUC的变化不大,性能不一定越好。