一、理解ROC 曲线
是一种用于评估二分类模型性能的工具。它通过展示模型在不同分类阈值下的表现,帮助我们更好地理解模型的能力。
ROC曲线的绘制是通过设置不同的阈值值,小于该阈值为假,大于该阈值为正,因此不断改变真正例率TPR和假正例率FPR,将不同阈值的真正例率TPR作为y轴坐标,假正例率FPR作为x轴坐标来绘制出ROC曲线
二、真正例率TPR和假正例率FPR
真正例率TPR是真正的正例且被预测为正例的例子TP 除以 所有的正例TP+FN
假正例率FPR是被错误预测为正类的负类样本数FP 除以 所有负类样本TN+FP
通过设置不同的阈值来得出不同的TPR和FPR,然后绘制成曲线,就是我们要的ROC曲线
三、PR曲线
PR曲线横轴:召回率,纵轴精确率。
精确率表示分类器在所有被预测为正例中真正为正例的比例,可以通过以下公式计算:
精确率P=TP/(TP+FP)
召回率表示分类器在所有实际为正例中正确预测为正例的比例,可以通过以下公式计算:
召回率R=TP/(TP+FN)
分类器在不同阈值下会得到一系列不同的精确率和召回率值,通过将这些值以召回率为横坐标、精确率为纵坐标绘制成曲线,即为PR曲线。曲线上每个点表示了在对应召回率下的最大精确率值。当P=R时成为平衡点(BEP),如果这个值较大,则说明学习器的性能较好。所以PR曲线越靠近右上角性能越好。
四、AUC值
ROC 曲线下方的面积(Area Under Curve,AUC)是一个重要的指标,用于量化模型的整体性能:
AUC 越接近 1,模型性能越好。
AUC 等于 0.5 表示模型的表现与随机猜测相当。
AUC 小于 0.5 表示模型性能比随机猜测还差。
五、用Python绘制ROC曲线和PR曲线
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import precision_recall_curve,roc_curve,auc
#第一次使用sklearn需要用命令pip install scikit-learn或py -m pip install scikit-learn进行安装
#随机数据生成
def create_data():
X, Y = make_classification(
n_samples = 5000, #生成的总样本数
n_features = 2, #每个样本的特征数量
n_classes = 2, #分类的类别数
n_informative = 2, #两个特征都具有信息量
n_redundant = 0, #无冗余特征
n_clusters_per_class = 2, #每个类别对应的聚类中心数量
random_state = 35
)
return X, Y
datas,labels = create_data()
#划分训练集和测试集
datas_train,datas_test,labels_train,labels_test = train_test_split(
datas,labels,test_size = 0.3,random_state = 35
)
#数据标准化(仅在训练集上fit,然后转换训练集和测试集)
scaler = StandardScaler()
datas_train = scaler.fit_transform(datas_train) #只在训练集上计算均值和方差
datas_test = scaler.transform(datas_test) #使用训练集的统计量转换测试集
#训练KNN模型(k = 5)
knn = KNeighborsClassifier(n_neighbors=5)
knn.fit(datas_train,labels_train)
#获取预测概率(正类的概率)
labels_scores = knn.predict_proba(datas_test)[:, 1]
#计算精确率与召回率(使用sklearn自动优化阈值)
precision,recall,thresholds = precision_recall_curve(labels_test,labels_scores)
pr_auc = auc(recall,precision) #计算AUC
#计算假正例率和真正例率
FPR,TPR,_ = roc_curve(labels_test,labels_scores)
roc_auc = auc(FPR,TPR) #计算AUC
# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei'] #使用黑体显示中文
plt.rcParams['axes.unicode_minus'] = False #解决负号显示问题
#绘制双图
plt.figure(figsize=(11,5))
#绘制PR曲线
plt.subplot(1,2,1)
plt.plot(recall,precision,color='blue',lw=2,
label=f'PR curve (AUC = {pr_auc:.2f})')
#计算平衡点
#找到最接近 Precision = Recall 的点
diff = np.abs(precision - recall)
be_index = np.argmin(diff)
be_precision = precision[be_index]
be_recall = recall[be_index]
#标记平衡点
plt.scatter(be_recall,be_precision,color='red', s=40,
label=f'平衡点 (P=R={be_precision:.2f})')
plt.annotate(f'阈值={thresholds[be_index]:.2f}',
xy=(be_recall,be_precision),
xytext=(20,-30),
textcoords='offset points',
bbox=dict(boxstyle='round,pad=0.5',fc='white',alpha=0.8),
arrowprops=dict(arrowstyle="->"))
plt.xlabel('Recall(召回率)',fontsize=12)
plt.ylabel('Precision(精确率)',fontsize=12)
plt.title('PR曲线',fontsize=14)
plt.legend(loc='lower left')
#绘制ROC曲线
plt.subplot(1,2,2)
plt.plot(FPR,TPR,color='darkorange',lw=2,
label=f'ROC curve (AUC = {roc_auc:.2f})')
plt.plot([0, 1],[0, 1],'k--',lw=1) #随机猜测线
plt.xlabel('False Positive Rate(假正例率)',fontsize=12)
plt.ylabel('True Positive Rate(真正例率)',fontsize=12)
plt.title('ROC曲线',fontsize=14)
plt.legend(loc='lower right')
#显示图像
plt.tight_layout()
plt.show()
图像显示
六、实验总结
本次实验通过 Python 代码实现了 ROC曲线 和 PR曲线 的绘制,深入理解了 TPR、FPR、Precision、Recall 等核心指标的计算和相互关系,并通过 AUC值 量化模型性能。同时,熟悉了 sklearn 中的 roc_curve、precision_recall_curve 和 auc 等关键函数的使用,并掌握了数据标准化和模型训练的基本流程。这些知识为后续的机器学习模型评估和优化奠定了基础。