目录
5.ROC 曲线(Receiver Operating Characteristic Curve)和 AUC(Area Under the Curve)
6.PR 曲线(Precision-Recall Curve)
一、模型评估概述
模型评估是对训练好的模型性能进行评估,用于确定模型在未知数据上的表现。它可以帮助我们了解模型的泛化能力、稳健性和适用性,从而做出更好的决策并优化模型。
二、常见的分类模型评估指标
当评估分类模型时,常见的评估指标包括准确率(Accuracy)、精确率(Precision)、召回率(Recall)、F1 分数(F1 Score)、ROC 曲线和AUC(Area Under the Curve)、PR 曲线(Precision-Recall Curve)。下面是这些指标的定义和计算方法:
1.准确率 (Accuracy)
准确率是最常见的分类模型评估指标之一,它衡量了模型在所有样本中正确分类的比例。具体而言,准确率是指分类器正确分类的样本数占总样本数的比例。
公式 P=(TP + TN) / (TP + TN + FP + FN)
换句话说,准确率等于所有正确分类的样本数(真正例和真负例)除以总样本数。
准确率的优点是简单直观,易于理解和解释。然而,当样本类别不平衡时,准确率可能会产生误导,因为即使模型只是简单地将所有样本都预测为占比较高的类别,也可能获得较高的准确率。
2.精确率(Precision)
精确率(Precision)是评估分类模型性能的重要指标之一,它衡量了模型在预测为正例的样本中有多少是真正例。换句话说,精确率表示了模型在所有预测为正例的样本中,有多少是真正例。
公式 P = TP / (TP + FP)
换句话说,精确率等于模型正确预测为正例的样本数除以所有预测为正例的样本数。
精确率的优点是它提供了一种对模型预测正例的质量进行评估的方式。如果我们对模型的预测准确性更加关注,那么精确率是一个非常重要的指标。例如,在医学诊断中,我们可能更关心模型预测为阳性的样本中有多少是真阳性。
3.召回率(Recall)
召回率(Recall),也称为灵敏度(Sensitivity)或真正例率(True Positive Rate),是评估分类模型性能的重要指标之一,它衡量了模型在所有真正例中有多少被成功预测为正例。换句话说,召回率表示了模型在所有真实为正例的样本中,有多少被成功预测为正例。
公式 R= TP / (TP + FN)
换句话说,召回率等于模型正确预测为正例的样本数除以所有真实为正例的样本数。
召回率的优点是它提供了一种对模型捕获正例的能力进行评估的方式。如果我们对模型尽可能捕获所有正例更感兴趣,那么召回率是一个非常重要的指标。例如,在医学诊断中,我们可能更关心模型能够捕获所有的真阳性,即尽可能避免漏报疾病
4.F1分数 (F1 Score)
F1 分数是综合考虑精确率(Precision)和召回率(Recall)的一种评价指标,它是二者的调和平均数。F1 分数的优点在于能够同时考虑模型的预测准确性和捕获能力。
公式 F1=2*(P*R)/(P+R)
F1 分数的取值范围在 0 到 1 之间,值越接近 1 表示模型的性能越好。当模型的精确率和召回率都很高时,F1 分数也会很高。
F1 分数的优点在于它能够综合考虑模型在正例预测准确性和捕获能力之间的平衡。与单独使用精确率或召回率相比,F1 分数能够更全面地评估模型的性能。
然而,F1 分数也有一些缺点。首先,它对精确率和召回率的权重是相同的,这意味着在某些情况下,可能更关注精确率或召回率而不是二者平衡的性能。其次,F1 分数对于不平衡数据集可能不够敏感,因为它将精确率和召回率看作同等重要,而在某些情况下,可能更关心其中一个。
5.ROC 曲线(Receiver Operating Characteristic Curve)和 AUC(Area Under the Curve)
ROC 曲线是一种以假阳性率(False Positive Rate,FPR)为横轴,真阳性率(True Positive Rate,TPR)为纵轴的图形,它展示了模型在不同阈值下的表现情况。ROC 曲线的横轴表示假阳性率,即被错误预测为正例的负例样本占所有负例样本的比例,ROC 曲线的纵轴表示真阳性率,即被正确预测为正例的正例样本占所有正例样本的比例,也就是召回率(Recall),在 ROC 曲线中,点(0,0)表示将所有样本都预测为负例,点(1,1)表示将所有样本都预测为正例。ROC 曲线越靠近左上角(0,1),模型的性能越好。
AUC 是 ROC 曲线下的面积,它代表了分类器的性能。AUC 的取值范围在 0 到 1 之间,数值越大表示模型性能越好。当 AUC 等于 1 时,表示模型完美地将正例排在负例前面;当 AUC 等于 0.5 时,表示模型的预测性能等同于随机预测。
AUC 的解释非常直观:它代表了模型对于随机选择一个正例样本和一个负例样本,能够正确判断哪个样本为正例的概率。因此,AUC 越大,模型性能越好。
6.PR 曲线(Precision-Recall Curve)
PR 曲线是以精确率为纵轴,召回率为横轴的曲线图,展示了在不同阈值下模型的表现情况。在 PR 曲线中,横轴表示召回率,即被正确预测为正例的正例样本占所有正例样本的比例,纵轴表示精确率,即被正确预测为正例的正例样本占所有预测为正例的样本的比例,在 PR 曲线中,点(0,1)表示将所有样本都预测为正例时的情况,点(1,0)表示将所有样本都预测为负例时的情况。
PR 曲线反映了在不同阈值下模型的精确率和召回率之间的权衡情况。PR 曲线越靠近右上角,表示模型在保持高精确率的同时,能够有较高的召回率,即模型的性能越好。
三、ROC和PR曲线分析
1.PR 曲线与 ROC 曲线的比较
1.关注的指标不同:ROC 曲线关注真阳性率(召回率)和假阳性率的变化,即横轴是假阳性率(False Positive Rate,FPR),纵轴是真阳性率(True Positive Rate,TPR)。PR 曲线关注精确率(Precision)和召回率之间的权衡,即横轴是召回率(Recall),纵轴是精确率(Precision)。
2.适用场景不同:ROC 曲线适用于各类样本平衡和不平衡的情况,但在数据严重不平衡时,ROC 曲线可能会给出过于乐观的评估。PR 曲线更适用于数据不平衡的情况,因为它专注于正例的精确率和召回率。
3.性能评估侧重点不同:ROC 曲线主要用于评估模型在不同阈值下的分类能力,特别关注模型的分类准确性。PR 曲线更关注模型在不同阈值下的预测准确性,特别关注模型对正例的预测效果。
2.ROC曲线
1.优点:适用性广泛: ROC 曲线适用于不同类别分布的数据集,包括平衡和不平衡数据。全面性能比较: 可以通过比较曲线下面积(AUC)来评估模型的整体性能,而且在不同阈值下提供了全面的性能比较。不受正负样本比例影响: ROC 曲线的横轴是假阳性率,纵轴是真阳性率,因此不受数据不平衡的影响。
2.缺点:对数据不平衡敏感: 当数据不平衡且负样本数量远远大于正样本数量时,ROC 曲线可能会给出过于乐观的评估。无法反映类别不平衡下的性能: ROC 曲线无法提供关于正例预测准确性的信息,因此在类别不平衡的情况下可能不够准确。
3.PR曲线
1.优点:适用于不平衡数据集: PR 曲线更适用于处理严重不平衡的数据,因为它关注的是正例的精确率和召回率。更准确地评估正例预测性能: PR 曲线能够更准确地反映模型对正例的预测效果,尤其是在正负样本比例差异较大时。
2.缺点:无法全面比较模型性能: PR 曲线相比于 ROC 曲线,缺乏全面性能比较的直观性。不适用于不同阈值下的性能比较: PR 曲线没有提供在不同阈值下的全面性能比较,因此无法像 ROC 曲线那样进行模型选择。
四、绘制ROC曲线
1.代码及结果
基于一个K最近邻(KNN)的水果分类器,并使用ROC曲线评估其性能。
import numpy as np
import matplotlib.pyplot as plt
from sklearn.metrics import roc_curve, auc
from sklearn.preprocessing import StandardScaler
import collections
# 定义水果分类器
class FruitKNNClassifier:
# 初始化KNN分类器
def __init__(self, k, distance_metric='euclidean'):
self.k = k
self.distance_metric = distance_metric
# 训练模型
def fit(self, X_train, y_train):
self.X_train = np.array(X_train)
self.y_train = y_train
# 计算两个样本之间的距离
def _distance(self, x1, x2):
if self.distance_metric == 'euclidean':
return np.sqrt(np.sum((x1 - x2) ** 2))
elif self.distance_metric == 'manhattan':
return np.sum(np.abs(x1 - x2))
elif self.distance_metric == 'minkowski':
return np.power(np.sum(np.power(np.abs(x1 - x2), self.p)), 1/self.p)
# 预测测试集样本的分类概率
def predict_proba(self, X_test):
y_proba = []
for x in X_test:
distances = [self._distance(x, x_train) for x_train in self.X_train]
k_indices = np.argsort(distances)[:self.k]
k_nearest_labels = [self.y_train[i] for i in k_indices]
class_counts = collections.Counter(k_nearest_labels)
probabilities = {label: count / self.k for label, count in class_counts.items()}
y_proba.append(probabilities)
return y_proba
# 创建水果数据集
def createFruitDataSet():
fruits = np.array([[150, 1], [130, 1], [200, 2], [180, 2], [80, 3], [100, 3], [120, 4], [160, 4], [140, 5], [190, 5]])
labels = ['苹果', '苹果', '香蕉', '香蕉', '橙子', '橙子', '梨子', '梨子', '桃子', '桃子']
return fruits, labels
if __name__ == '__main__':
# 创建数据集
fruits, labels = createFruitDataSet()
# 特征标准化
scaler = StandardScaler()
fruits_scaled = scaler.fit_transform(fruits)
# 初始化KNN分类器
knn_classifier = FruitKNNClassifier(k=1) # 尝试不同的K值
# 训练模型
knn_classifier.fit(fruits_scaled, labels)
# 测试集
test = np.array([[120, 1]])
# 预测分类概率
test_proba = knn_classifier.predict_proba(scaler.transform(test))
# 提取分类概率
proba_apple = test_proba[0].get('苹果', 0)
proba_banana = test_proba[0].get('香蕉', 0)
proba_orange = test_proba[0].get('橙子', 0)
# 计算ROC曲线
fpr, tpr, _ = roc_curve([1, 1, 0], [1 - proba_apple, 1 - proba_banana, 1 - proba_orange])
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.05])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Receiver Operating Characteristic')
plt.legend(loc="lower right")
plt.show()
k值为1时ROC曲线如下
k值为5时ROC曲线如下
2.结果分析
这个结果反映了模型在不同k值下的性能差异。在k值为1时,模型只考虑了单一最近邻的标签,因此可能过度拟合了训练数据,导致在测试数据上表现不佳,ROC AUC较低。而在k值为5时,模型考虑了更多的近邻样本,可能更能够捕捉到数据的整体分布规律,从而在测试数据上表现更好,ROC AUC较高。
这种情况下,我们可以认为k值为5时的模型性能更好,因为它能够更好地泛化到新的数据上,而不是过度拟合到训练数据。