news 2026/5/2 8:34:56

别再只盯着准确率了!用Python手把手教你画出分类模型的PR和ROC曲线(附代码)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
别再只盯着准确率了!用Python手把手教你画出分类模型的PR和ROC曲线(附代码)

实战指南:用Python绘制分类模型的PR与ROC曲线

在机器学习项目中,评估分类模型性能时,很多开发者习惯性地依赖单一准确率指标,这往往会导致对模型真实效果的误判。特别是在样本分布不均衡的场景下,准确率可能给出极具误导性的乐观结果。本文将带你用Python实战演练两种更可靠的评估工具——PR曲线和ROC曲线,通过可视化手段全面把握模型在不同阈值下的表现差异。

1. 环境准备与数据加载

首先确保你的Python环境已安装以下核心库:

# 基础数据处理与建模 import numpy as np import pandas as pd from sklearn.datasets import make_classification # 模型训练与评估 from sklearn.model_selection import train_test_split from sklearn.linear_model import LogisticRegression from sklearn.ensemble import RandomForestClassifier # 评估指标与可视化 from sklearn.metrics import precision_recall_curve, roc_curve, auc import matplotlib.pyplot as plt import seaborn as sns

我们使用make_classification生成模拟数据,刻意构造样本不均衡场景:

# 生成1000个样本,其中正类仅占20% X, y = make_classification(n_samples=1000, n_classes=2, weights=[0.8, 0.2], random_state=42) # 划分训练集和测试集 X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.3, random_state=42) print(f"正样本比例 - 训练集: {y_train.mean():.2%}, 测试集: {y_test.mean():.2%}")

提示:实际项目中建议使用class_weight='balanced'参数或过采样技术处理样本不均衡问题

2. 训练基准分类模型

我们选择逻辑回归和随机森林作为对比模型:

# 初始化模型(逻辑回归设置class_weight以处理样本不均衡) lr = LogisticRegression(class_weight='balanced', random_state=42) rf = RandomForestClassifier(class_weight='balanced_subsample', random_state=42) # 训练模型 lr.fit(X_train, y_train) rf.fit(X_train, y_train) # 获取预测概率(注意使用predict_proba而非predict) lr_probs = lr.predict_proba(X_test)[:, 1] # 正类的预测概率 rf_probs = rf.predict_proba(X_test)[:, 1]

关键点说明:

  • class_weight参数帮助模型关注少数类
  • 必须使用predict_proba获取概率值而非硬分类结果
  • 概率值将作为绘制曲线的阈值调节依据

3. PR曲线绘制与解读

PR曲线展示的是精确率(Precision)与召回率(Recall)之间的权衡关系:

def plot_pr_curve(y_true, y_probs, model_name): precision, recall, _ = precision_recall_curve(y_true, y_probs) pr_auc = auc(recall, precision) plt.plot(recall, precision, label=f'{model_name} (AUC = {pr_auc:.2f})') plt.xlabel('Recall') plt.ylabel('Precision') plt.title('PR Curve') plt.legend() plt.grid(True) plt.figure(figsize=(10, 6)) plot_pr_curve(y_test, lr_probs, 'Logistic Regression') plot_pr_curve(y_test, rf_probs, 'Random Forest') # 添加基准线(正样本比例) baseline = y_test.mean() plt.axhline(y=baseline, color='gray', linestyle='--', label=f'Baseline ({baseline:.2%})') plt.legend() plt.show()

PR曲线的关键特征:

特征解释实际意义
曲线位置越靠近右上角越好模型在精确率和召回率间取得更好平衡
AUC值曲线下面积(0-1)综合评估指标,值越大性能越好
基准线正样本比例随机猜测模型的性能水平

典型应用场景:

  • 欺诈检测(关注少数类)
  • 疾病筛查(不能漏检病例)
  • 推荐系统(确保推荐内容精准)

4. ROC曲线绘制与对比分析

ROC曲线展示的是真正率(TPR)与假正率(FPR)的关系:

def plot_roc_curve(y_true, y_probs, model_name): fpr, tpr, _ = roc_curve(y_true, y_probs) roc_auc = auc(fpr, tpr) plt.plot(fpr, tpr, label=f'{model_name} (AUC = {roc_auc:.2f})') plt.plot([0, 1], [0, 1], 'k--') # 随机猜测线 plt.xlabel('False Positive Rate') plt.ylabel('True Positive Rate') plt.title('ROC Curve') plt.legend() plt.grid(True) plt.figure(figsize=(10, 6)) plot_roc_curve(y_test, lr_probs, 'Logistic Regression') plot_roc_curve(y_test, rf_probs, 'Random Forest') plt.show()

ROC曲线与PR曲线的核心区别:

特性ROC曲线PR曲线
关注点整体分类性能正类识别能力
横坐标FPR (假正率)Recall (召回率)
纵坐标TPR (真正率)Precision (精确率)
样本不均衡影响相对稳定非常敏感
适用场景均衡数据集不均衡数据集

注意:当正样本比例低于10%时,优先参考PR曲线评估模型

5. 高级技巧与实战建议

5.1 多模型对比可视化

将PR和ROC曲线组合展示更直观:

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(18, 6)) # PR曲线 for model, probs in [('LR', lr_probs), ('RF', rf_probs)]: precision, recall, _ = precision_recall_curve(y_test, probs) ax1.plot(recall, precision, label=f'{model} (AUC={auc(recall, precision):.2f})') ax1.set_title('PR Curve Comparison') ax1.legend() # ROC曲线 for model, probs in [('LR', lr_probs), ('RF', rf_probs)]: fpr, tpr, _ = roc_curve(y_test, probs) ax2.plot(fpr, tpr, label=f'{model} (AUC={auc(fpr, tpr):.2f})') ax2.plot([0, 1], [0, 1], 'k--') ax2.set_title('ROC Curve Comparison') ax2.legend() plt.show()

5.2 阈值选择策略

通过曲线确定最佳分类阈值:

# 寻找PR曲线上F1分数最大的阈值 def find_optimal_threshold(y_true, y_probs): precision, recall, thresholds = precision_recall_curve(y_true, y_probs) f1_scores = 2 * (precision * recall) / (precision + recall + 1e-8) optimal_idx = np.argmax(f1_scores) return thresholds[optimal_idx], f1_scores[optimal_idx] lr_threshold, lr_f1 = find_optimal_threshold(y_test, lr_probs) rf_threshold, rf_f1 = find_optimal_threshold(y_test, rf_probs) print(f"逻辑回归最佳阈值: {lr_threshold:.4f} (F1={lr_f1:.2f})") print(f"随机森林最佳阈值: {rf_threshold:.4f} (F1={rf_f1:.2f})")

5.3 实际应用中的陷阱

常见问题与解决方案:

  1. 曲线波动剧烈

    • 检查样本量是否足够
    • 尝试使用平滑技术
  2. AUC值异常高

    • 验证是否存在数据泄露
    • 检查特征工程合理性
  3. 测试集与训练集表现差异大

    • 确保数据分布一致
    • 考虑使用交叉验证

在电商用户流失预测项目中,我们发现当正样本比例低于5%时,ROC曲线的AUC值仍然保持在0.85以上,但PR曲线的AUC仅为0.3,这提示模型的实际业务价值可能被高估。通过调整分类阈值和引入代价敏感学习,最终将召回率从0.6提升到0.8,虽然精确率有所下降,但更符合业务需求。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/2 8:32:54

MAA明日方舟自动化助手:5个步骤轻松实现全日常一键长草

MAA明日方舟自动化助手:5个步骤轻松实现全日常一键长草 【免费下载链接】MaaAssistantArknights 《明日方舟》小助手,全日常一键长草!| A one-click tool for the daily tasks of Arknights, supporting all clients. 项目地址: https://gi…

作者头像 李华
网站建设 2026/5/2 8:32:40

3步搞定网页媒体资源嗅探:猫抓浏览器扩展终极使用指南

3步搞定网页媒体资源嗅探:猫抓浏览器扩展终极使用指南 【免费下载链接】cat-catch 猫抓 浏览器资源嗅探扩展 / cat-catch Browser Resource Sniffing Extension 项目地址: https://gitcode.com/GitHub_Trending/ca/cat-catch 你是否曾经遇到过这样的困境&…

作者头像 李华
网站建设 2026/5/2 8:31:39

数据管道优化:重构百度网盘资源获取的工作流架构

数据管道优化:重构百度网盘资源获取的工作流架构 【免费下载链接】baidu-wangpan-parse 获取百度网盘分享文件的下载地址 项目地址: https://gitcode.com/gh_mirrors/ba/baidu-wangpan-parse 数据获取效率瓶颈的系统性分析 在现代数字工作环境中&#xff0c…

作者头像 李华
网站建设 2026/5/2 8:24:31

告别Element UI?手把手教你用LayUI快速搭建一个后台管理系统界面

轻量级后台管理系统开发实战:LayUI从入门到精通 1. 为什么选择LayUI开发后台管理系统? 在当今前端框架百花齐放的时代,Vue、React等现代框架确实提供了强大的功能,但对于需要快速交付的中小型项目或内部管理系统来说&#xff0c…

作者头像 李华