一、模型评估概述
机器学习模型评估是机器学习流程中的一个关键步骤,它帮助我们了解模型的性能和可靠性。评估过程通常涉及一系列的指标和方法,用于衡量模型对新数据的预测能力。
二、常见的分类模型评估指标
1.准确率 (Accuracy)
准确率是分类正确的样本数占总样本数的比例。它是最直观的评估指标,但可能在类别不平衡的情况下产生误导。
2.精确率 (Precision)
精确率是在所有被模型预测为正类的样本中,真正属于正类的样本比例。它关注模型预测正类的准确性。
3. 召回率 (Recall) 或 灵敏度 (Sensitivity)
召回率是在所有真正属于正类的样本中,被模型正确预测为正类的样本比例。它关注模型捕捉正类的能力。
4. F1 分数 (F1 Score)
F1 分数是精确率和召回率的调和平均数,它试图在两个指标之间取得平衡。F1 分数对于不平衡的类别分布较为敏感。
5. ROC 曲线 (Receiver Operating Characteristic Curve)
ROC 曲线是一个用于评估二分类模型的图形工具,它通过绘制不同阈值下的真正类率 (TPR, 即召回率) 和假正类率 (FPR, 1 - 特异度) 来展示模型的性能。
6.AUC (Area Under the Curve)
AUC 是 ROC 曲线下的面积,它提供了一个量化模型整体性能的指标。AUC 的值介于 0 和 1 之间,值越大表示模型性能越好。
7.混淆矩阵
混淆矩阵是一个表格,用于描述分类模型的性能。它通常包含四个部分:真正类(True Positives, TP)、假正类(False Positives, FP)、真负类(True Negatives, TN)和假负类(False Negatives, FN)。
- 真正类 (TP): 正确预测为正类的数量
- 假正类 (FP): 错误预测为正类的数量
- 真负类 (TN): 正确预测为负类的数量
- 假负类 (FN): 错误预测为负类的数量
三、ROC曲线与PR曲线
1.ROC曲线
ROC曲线起源于信号检测理论,用于评估分类模型在各种阈值设置下的性能。ROC曲线通过绘制真正类率(True Positive Rate, TPR)和假正类率(False Positive Rate, FPR)之间的关系,提供了一个模型在所有分类阈值下性能的概览。
真阳率:
含义:TP除以第一列,即预测为1实际为1的样本在所有真实1类别中的占比。
假阳率:
含义:FP除以第二列,即预测为1实际为0的样本在所有真实0类别中的占比。
在模型预测的时候,我们输出的预测结果是一堆[0,1]之间的数值,怎么把数值变成二分类?设置一个阈值,大于这个阈值的值分类为1,小于这个阈值的值分类为0。ROC曲线就是我们从[0,1]设置一堆阈值,每个阈值得到一个(TPR,FPR)对,纵轴为TPR,横轴为FPR,把所有的(TPR,FPR)对连起来就得到了ROC曲线。
AUC即ROC曲线下的面积。曲线越靠近左上角,意味着TPR>FPR,模型的整体表现也就越好。所以我们可以断言,ROC曲线下的面积越大,模型效果越好。
最坏的情况是,总是有TPR=FPR,如下图,表示对于不论真实类别是1还是0的样本,分类器预测为1的概率是相等的。换句话说,分类器对于正例和负例毫无区分能力。如果AUC小于0.5,那么只要把预测类别取反,便得到了一个AUC大于0.5的分类器。
2.PR曲线
PR曲线关注的是模型在不同分类阈值下的精确率(Precision)和召回率(Recall)之间的关系。与ROC曲线不同,PR曲线特别适用于正负样本分布不平衡的情况。
PR曲线的特点是,它能够提供模型在正负样本不平衡情况下的性能信息。在许多实际应用中,如文本分类、图像识别等领域,正负样本的分布往往是不平衡的,这时候PR曲线就显得尤为重要。PR曲线下的面积(AP)同样是一个重要的性能指标,面积越大,模型的性能越好
跟TPR和FPR不一样的是,在PR关系中,是一个此消彼长的关系,但往往我们希望二者都是越高越好,所以PR曲线是右上凸效果越好(也有例外,有比如在风险场景当预测为1实际为0时需要赔付时,大致会要求Recall接近100%,可以损失Precision)。所以除了特殊情况,通常情况都会使用Precision-recall曲线,来寻找分类器在Precision与Recall之间的权衡。
AP就是Precision-recall 曲线下面的面积,通常来说一个越好的分类器,AP值越高。
还有一个mAP的概念,mAP是多个类别AP的平均值。这个mean的意思是对每个类的AP再求平均,得到的就是mAP的值,mAP的大小一定在[0,1]区间,越大越好。该指标是目标检测算法中最重要的一个。
3.ROC曲线、PR曲线优缺点
ROC曲线:
(1)优点
A.兼顾正例和负例的权衡。因为TPR聚焦于正例,FPR聚焦于与负例,使其成为一个比较均衡的评估方法。适用于评估分类器的整体性能。 B.ROC曲线的两个指标, TPR的分母是所有正例,FPR的分母是所有负例,故都不依赖于具体的类别分布。
(2)缺点
在类别不平衡的背景下,当负例N的数量远超正例P时,FP的大幅增长只能换来FPR的增长不明显,导致ROC曲线呈现一个过分乐观的效果估计。 如果主要关心正例的预测准确性的话,这就不太可接受了。
PR曲线:
(1)优点
PR曲线的两个指标都聚焦于正例。类别不平衡问题中由于主要关心正例,所以在此情况下PR曲线被广泛认为优于ROC曲线。
(2)缺点
只关注正例,不关注负例
4.ROC&PR曲线使用场景
(1)如果想兼顾正例与负例,则选用ROC曲线;如果在类别不平衡中,或者更看重正例的场景中比如推荐信息检索,则选用PR曲线
(2)如果有多份数据且存在不同的类别分布,比如信用卡欺诈问题中每个月正例和负例的比例可能都不相同,这时候如果只想单纯地比较分类器的性能且剔除类别分布改变的影响,则ROC曲线比较适合,因为类别分布改变可能使得PR曲线发生变化时好时坏,这种时候难以进行模型比较;反之,如果想测试不同类别分布下对分类器的性能的影响,则PR曲线比较适合。
reference
PR曲线、ROC曲线、AUC、AP简单梳理 - 知乎 (zhihu.com)
四、knn中不同k值的ROC曲线
k=1
k=2
k=3
k=4
k=5
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import roc_curve, auc
import matplotlib.pyplot as plt
# 加载鸢尾花数据集
iris = datasets.load_iris()
X = iris.data
y = iris.target
# 选择一个二分类问题,例如鸢尾花的两个类别
y_binary = (y == 2).astype(int) # 将类别1视为正类,其他视为负类
# 将数据集分为训练集和测试集
X_train, X_test, y_train_binary, y_test_binary = train_test_split(X, y_binary, test_size=0.5, random_state=42)
# 特征缩放
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
# 创建KNN分类器实例,使用加权投票
knn = KNeighborsClassifier(n_neighbors=5, weights='distance')
# 训练模型
knn.fit(X_train_scaled, y_train_binary)
# 进行预测
y_pred_proba = knn.predict_proba(X_test_scaled)[:, 1] # 获取预测为正类的概率
# 计算ROC曲线和AUC
fpr, tpr, thresholds = roc_curve(y_test_binary, y_pred_proba)
roc_auc = auc(fpr, tpr)
# 绘制ROC曲线
plt.figure()
plt.plot(fpr, tpr, color='darkorange', lw=2, label='ROC curve (area = %0.2f)' % roc_auc)
plt.plot([0, 1], [0, 1], color='navy', lw=2, linestyle='--')
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.0])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Receiver Operating Characteristic')
plt.legend(loc="lower right")
plt.show()
这段代码能够正确地绘制ROC曲线,并且不会因为ylim
的范围设置不当而截断曲线。但在运行代码后得到了AUC值为1.0,这可能表明模型在测试集上的表现非常出色,但也可能是由于数据集规模较小或者模型过拟合等原因导致的。
我先后使用了交叉验证的方法,与正则化的方法,但是无法解决貌似过拟合的情况,可能需要一个更大的数据集,才能真正解决这个问题。