目录
ROC曲线(Receiver Operating Characteristic Curve):
引言
分类问题,是机器学习的核心应用之一,在许多关键领域中发挥着重要作用。然而,分类模型的性能评估远非如此简单。准确率(Accuracy)是最常见的性能度量标准,但它在某些情况下可能会误导。例如,在不平衡的数据集中,一个模型可能会因为总是预测“负例”而获得很高的准确率,但这并不代表它对我们的任务有用。这就是为什么我们需要深入研究其他性能指标,其中Precision-Recall(PR)曲线和Receiver Operating Characteristic(ROC)曲线是两个非常重要的工具。在本篇博客中,我们将探讨PR和ROC曲线的概念及其在机器学习中的应用。
PR曲线和ROC曲线
引入混淆矩阵:
在了解PR曲线和ROC曲线之前,让我们先介绍混淆矩阵的概念,它是评估分类模型性能的基础。
混淆矩阵是一个二维表格,用于总结模型对不同类别的分类结果。它包括四个关键的元素:真正例(True Positives, TP)、真负例(True Negatives, TN)、假正例(False Positives, FP)和假负例(False Negatives, FN)。这些元素表示了模型对数据的不同预测结果:
- True Positives (TP):模型正确地预测了正例。
- True Negatives (TN):模型正确地预测了负例。
- False Positives (FP):模型错误地将负例预测为正例。
- False Negatives (FN):模型错误地将正例预测为负例。
混淆矩阵为我们提供了分类模型性能的详细信息,以及后续计算Precision、Recall、True Positive Rate(TPR)和False Positive Rate(FPR)所需的元素。
PR曲线和混淆矩阵:
PR曲线是基于混淆矩阵中的TP、FP和FN计算出来的。Precision是TP/(TP+FP),Recall是TP/(TP+FN)。PR曲线以不同的阈值为横轴,基于混淆矩阵的元素计算出不同的Precision和Recall值,然后将这些值绘制成曲线。
ROC曲线和混淆矩阵:
ROC曲线则基于混淆矩阵中的TPR和FPR。TPR是TP/(TP+FN),FPR是FP/(FP+TN)。ROC曲线也以不同的阈值为横轴,计算出不同的TPR和FPR值,绘制成曲线。ROC曲线下方的面积(AUC)表示了模型的性能。
PR曲线(Precision-Recall Curve):
PR曲线是一种用于评估二分类模型性能的图形工具。它基于两个关键性能度量:Precision(精确率)和Recall(召回率)。
-
Precision(精确率) 衡量了模型在所有正例预测中的正确性。它的计算方式是:Precision = TP / (TP + FP),其中TP代表真正例,FP代表假正例。高精确率表示模型的正例预测非常可靠,很少有错误。
-
Recall(召回率) 衡量了模型在所有实际正例中成功捕获的比例。它的计算方式是:Recall = TP / (TP + FN),其中TP代表真正例,FN代表假负例。高召回率表示模型成功捕获了大多数正例,但可能伴随更多的假正例。
可以用以下这个例子进行理解:
有好瓜和坏瓜共25个,其中有20个是好瓜。我想买好瓜,于是我进行挑选,挑了10个觉得是好的瓜,但是最后发现只有9个是好瓜。那么精确率 (Pre)就为9/10;召回率(recall)=9/20.
(如图所示,平衡点在y=x线上即为该分类器性能较好)
PR曲线以不同的阈值值为横轴,以对应的Precision和Recall值为纵轴,绘制出一条曲线。这个曲线通常呈现出一个平衡点,其中精确率和召回率之间存在权衡。高PR曲线表明模型在同时优化精确率和召回率方面表现良好,而低PR曲线可能表明模型在这两个方面难以达到平衡。
ROC曲线(Receiver Operating Characteristic Curve):
ROC曲线是另一种用于评估分类模型性能的工具,它不同于PR曲线,侧重于真正例率(True Positive Rate)和假正例率(False Positive Rate)。
-
True Positive Rate(真正例率) 也称为召回率,是指模型正确识别正例的能力,计算方式是:TPR = TP / (TP + FN)。它与PR曲线中的召回率是相同的。
-
False Positive Rate(假正例率) 衡量了模型将负例错误分类为正例的频率,计算方式是:FPR = FP / (FP + TN),其中FP代表假正例,TN代表真负例。
ROC曲线以不同的阈值值为横轴,以对应的TPR和FPR值为纵轴,绘制出一条曲线。理想情况下,ROC曲线应该尽可能靠近左上角,这表示模型在最小化假正例率的同时最大化真正例率。曲线下面积(AUC)是ROC曲线下方的面积,通常用于度量分类模型性能,AUC值越接近1,表示模型性能越好。
绘制PR和ROC曲线
绘制PR曲线:
Scikit-Learn库中导入make_classification
函数,用于创建模拟的分类数据集。
导入train_test_split
函数,用于将数据集划分为训练集和测试集。
导入K-Nearest Neighbors (KNN) 分类器。
导入precision_recall_curve, auc用于计算PR曲线和AUC的函数。
1.在本代码中创建一个模拟的分类数据集,其中包括1000个样本和20个特征。
#X是特征矩阵,y是目标标签。
X, y = make_classification(n_samples=1000, n_features=20, random_state=42)
2.划分数据集为训练集和测试集
#将数据集划分为训练集和测试集,其中测试集占总数据集的30%。
#random_state 参数用于确保结果的可重现性。
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42):
3.选择分类器
knn = KNeighborsClassifier(n_neighbors=3)
knn.fit(X_train, y_train)
knn = KNeighborsClassifier(n_neighbors=3):创建一个KNN分类器,其中 n_neighbors 参数设置为3,表示K值为3。
knn.fit(X_train, y_train):使用训练数据对KNN模型进行训练。
4.计算数据
# 获取模型的概率分数(KNN不直接输出概率,但可以用于PR曲线)
y_scores = knn.predict_proba(X_test)[:, 1]
# 计算PR曲线的Precision和Recall
precision, recall, _ = precision_recall_curve(y_test, y_scores)
# 计算PR曲线下方的面积
pr_auc = auc(recall, precision)
y_scores = knn.predict_proba(X_test)[:, 1]:获取模型的概率分数,这里选择的是模型预测为正例的概率。
precision, recall, _ = precision_recall_curve(y_test, y_scores):使用precision_recall_curve函数计算PR曲线的Precision和Recall值。y_test 是测试集的真实标签,y_scores 是模型的概率分数。
pr_auc = auc(recall, precision):使用auc函数计算PR曲线下方的面积(AUC)。
5.绘制PR曲线
plt.figure(figsize=(8, 6))
plt.plot(recall, precision, color='darkorange', lw=2, label='PR Curve (AUC = %0.2f)' % pr_auc)
plt.xlabel('Recall')
plt.ylabel('Precision')
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.title('Precision-Recall Curve')
plt.legend(loc='lower left')
plt.grid(True)
plt.plot([0, 1], [1, 0], color='navy', lw=2, linestyle='--', label='Random Guess')
pr_auc = auc(recall, precision):使用auc函数计算PR曲线下方的面积(AUC)。
创建一个图形窗口(plt.figure)并绘制PR曲线,包括Precision和Recall的曲线,以及AUC值的标签。
设置横轴和纵轴的标签、标题,并添加图例。
使用plt.grid(True) 添加网格。
添加反对角线的虚线,表示随机猜测的性能,其中从(0,1)到(1,0)。
最后,使用 plt.show() 显示绘制的PR曲线图形。
效果如下:
绘制ROC曲线
与PR曲线绘制类似,区别在于是从Scikit-Learn库中导入roc_curve, auc
用于计算ROC曲线和AUC的函数。
1.在创建数据集、2.划分数据集、3.选择分类器大体相同
# 创建模拟的分类数据集
X, y = make_classification(n_samples=1000, n_features=20, random_state=42)
# 划分数据集为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
# 创建并训练KNN分类器
knn = KNeighborsClassifier(n_neighbors=3)
knn.fit(X_train, y_train)
4.计算数据
# 获取模型的概率分数(KNN不直接输出概率,但可以用于ROC曲线)
y_scores = knn.predict_proba(X_test)[:, 1]
# 计算ROC曲线的FPR和TPR
fpr, tpr, _ = roc_curve(y_test, y_scores)
# 计算ROC曲线下方的面积
roc_auc = auc(fpr, tpr)
y_scores = knn.predict_proba(X_test)[:, 1]:获取模型的概率分数,这里选择的是模型预测为正例的概率。需要注意的是,KNN模型本身不提供概率估计,但可以通过一些方法来获取近似的概率值。
fpr, tpr, _ = roc_curve(y_test, y_scores):使用roc_curve函数计算ROC曲线的False Positive Rate (FPR) 和 True Positive Rate (TPR) 值。y_test 是测试集的真实标签,y_scores 是模型的概率分数。
roc_auc = auc(fpr, tpr):使用auc函数计算ROC曲线下方的面积(AUC)。
5.绘制ROC曲线
plt.figure(figsize=(8, 6))
plt.plot(fpr, tpr, color='darkred', lw=2, label='ROC Curve (AUC = %0.2f)' % roc_auc)
plt.plot([0, 1], [0, 1], color='navy', lw=2, linestyle='--', label='Random Guess')
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.title('Receiver Operating Characteristic Curve')
plt.legend(loc='lower right')
plt.grid(True)
plt.show()
曲线绘制过程与PR曲线大致一致,效果如下:
优化
根据上一次KNN算法的学习,我们知道可以更改邻居值来优化我们的实验,不妨多做几组比较
当n_neighbors=5时:
当n_neighbors=8时:
当n_neighbors=30时:
在KNN 分类器中增加 n_neighbors 参数的值,并且观察到AUC值增加,通常是因为增加了K值,模型变得更加平滑和稳定。然而,需要注意的是,增加K值也可能导致模型的偏差增加,因为它可能无法捕获数据中的细微特征。
小结
ROC曲线和PR曲线是用于评估二元分类器性能的重要工具。ROC曲线显示了真正例率与假正例率之间的关系,而PR曲线显示了精确率(Precision)与召回率(Recall)之间的关系。
AUC是ROC曲线或PR曲线下方的面积,用于度量分类器性能。AUC值越大,表示分类器的性能越好。如果可能,使用交叉验证来评估模型的性能,而不仅仅是单一的测试集。这可以提供更稳定和可靠的性能估计。