背景
在机器学习模型评估中,性能度量的选择对于理解模型行为至关重要,在二分类问题中,Precision-Recall曲线(简称PR曲线)是一种常用的可视化方法【也可以扩展到多分类思想与宏平均ROC类似】,特别适用于评价不平衡数据集,本文将说明什么是PR曲线、它的适用场景以及它与常见的ROC曲线之间的差异最后及其实现
什么是PR曲线?
PR曲线是基于模型的精确率(Precision)和召回率(Recall)绘制的曲线,用于评估分类器在不同决策阈值下的表现
精确率(Precision):在模型预测为正类的样本中,实际是正类的比例,公式为:
召回率(Recall):在所有实际为正类的样本中,模型正确预测为正类的比例,公式为:
PR曲线中的每个点对应于模型在某个特定决策阈值下的精确率和召回率,阈值从高到低变化,从而描绘出曲线
PR曲线适用场景
PR曲线的适用场景主要体现在以下两个方面:
- 不平衡数据集:当数据集中正负样本比例严重失衡(例如欺诈检测、疾病诊断)时,PR曲线是一个更好的选择,它强调模型在正类上的表现,避免被多数负类样本的高预测准确率所掩盖
- 关注正类表现:在某些应用场景中,例如筛查癌症或预测罕见事件,往往更关心正类样本的识别效果,这时PR曲线能提供更清晰的性能可视化
PR曲线与ROC曲线的差异
ROC曲线是另一种常用的模型评估工具,它以真阳性率(TPR, Recall)为纵轴,假阳性率(FPR)为横轴绘制曲线,虽然ROC曲线与PR曲线都能衡量分类器的性能,但它们之间存在以下显著差异:
- 纵轴指标不同:PR曲线强调精确率(Precision)与召回率(Recall)的权衡,ROC曲线关注真阳性率(TPR)与假阳性率(FPR)的关系
- 性能解释差异:ROC曲线对不平衡数据集的鲁棒性较差,即使负类样本占比很高,ROC曲线的表现可能仍然较好,但它不能准确反映正类的检测能力,PR曲线更专注于模型对正类样本的处理能力,因此在正负类样本比例严重失衡时表现更优
- 决策阈值优化:PR曲线更适合用来选择阈值,因为它直接反映了Precision和Recall的动态变化,ROC曲线则通常用于比较模型整体的分类能力(通过AUC值)
PR曲线是一种适合不平衡数据集和关注正类表现的评估工具,它通过描绘精确率和召回率的权衡,提供了一种直观且实用的方式来优化模型阈值和理解模型性能,相比之下,ROC曲线适用于全面评估分类器,但在数据不平衡的情况下可能会导致误导
代码实现
数据读取整理
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
plt.rcParams['font.family'] = 'Times New Roman'
plt.rcParams['axes.unicode_minus'] = False
# 读取数据
df = pd.read_excel('2024-11-30公众号Python机器学习AI.xlsx')
# 划分特征和目标变量
X = df.drop(['y'], axis=1)
y = df['y']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2,
random_state=42, stratify=df['y'])
读取Excel文件中的数据并将其划分为训练集和测试集,为二分类机器学习任务做好准备,其中y是目标变量,表示数据集中有两个类别(即二分类)
模型构建
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import classification_report, accuracy_score, roc_auc_score, RocCurveDisplay, PrecisionRecallDisplay
# 创建随机森林分类器
clf = RandomForestClassifier(
class_weight='balanced_subsample',
criterion='entropy',
n_jobs=-1,
random_state=42,
max_features='log2',
n_estimators=20,
min_samples_split=0.01,
min_samples_leaf=0.005,
min_impurity_decrease=1e-2,
bootstrap=True,
ccp_alpha=1e-2,
max_samples=0.75,
oob_score=True
)
# 训练模型
clf.fit(X_train, y_train)
这里通过构建并训练一个随机森林分类器,使用若干超参数来优化模型性能,最终训练的模型将为后续绘制Precision-Recall(PR)曲线提供基础
from_estimator方法绘制
# 绘制 Precision-Recall 曲线,添加随机分类器基线
pr_display = PrecisionRecallDisplay.from_estimator(
clf,
X_test,
y_test,
plot_chance_level=True, # 添加基线
name="RandomForest"
)
_ = pr_display.ax_.set_title("2-class Precision-Recall curve")
plt.savefig('2-class Precision-Recall curve_1.pdf', format='pdf', bbox_inches='tight', dpi=1200)
plt.show()
使用测试数据绘制随机森林分类器的Precision-Recall(PR)曲线,并添加随机分类器基线,具体解读如下:
- 蓝色曲线代表随机森林分类器的PR曲线
- 曲线越靠近右上角,表示模型性能越好,可以看到模型总体上保持了较高的Precision和Recall,说明分类器的表现很好
- 黑色虚线表示随机分类器的表现基线(Chance Level),对应于一个无意义的分类器
- 随机森林模型的曲线明显高于基线,说明模型的性能优于随机猜测
- 图例中AP = 0.95表示模型的平均精度,是PR曲线下的面积,用于量化模型的PR曲线表现
- 对比随机分类器的AP值(0.47),模型的AP值显著更高,进一步说明分类器性能优异
from_predictions方法绘制
# 使用 from_predictions 方法绘制
display = PrecisionRecallDisplay.from_predictions(
y_test, # 真实标签
y_proba, # 模型的预测分数 即正类概率
name="LinearSVC", # 图例中的模型名称
plot_chance_level=True # 显示随机分类器基线
)
_ = display.ax_.set_title("2-class Precision-Recall curve")
plt.savefig('2-class Precision-Recall curve_2.pdf', format='pdf', bbox_inches='tight', dpi=1200)
plt.show()
from_estimator直接使用模型和测试集自动计算预测分数,而from_predictions则需要手动提供真实标签和预测分数,更灵活但稍复杂,但其结果是一致的
多分类PR曲线绘制
多分类 PR 曲线通过 One-vs-Rest 方法,将每个类别分别视为正类,其余类别为负类,计算 Precision 和 Recall,从而为每个类别绘制独立的 PR 曲线。此外,还叠加了微平均曲线(Micro-Average),综合展示了整体分类性能,并通过 Iso-F1 曲线提供不同 F1 值下的参考线,帮助评估 Precision 和 Recall 的权衡。相比二分类 PR 曲线,多分类更侧重分析模型在每个类别上的细粒度表现以及整体性能,代码与数据集获取:如需获取本文完整的源代码和数据集,请添加作者微信联系
往期推荐
从宏平均ROC到Obuchowski指数:如何精准评估多分类模型?
如果你对类似于这样的文章感兴趣。
欢迎关注、点赞、转发~
个人观点,仅供参考