news 2026/7/15 3:04:07

Day16 ROC曲线和PR曲线

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Day16 ROC曲线和PR曲线

@浙大疏锦行

一、前置代码

# 先运行之前预处理好的代码 import pandas as pd import pandas as pd #用于数据处理和分析,可处理表格数据。 import numpy as np #用于数值计算,提供了高效的数组操作。 import matplotlib.pyplot as plt #用于绘制各种类型的图表 import seaborn as sns #基于matplotlib的高级绘图库,能绘制更美观的统计图形。 import warnings warnings.filterwarnings("ignore") # 设置中文字体(解决中文显示问题) plt.rcParams['font.sans-serif'] = ['SimHei'] # Windows系统常用黑体字体 plt.rcParams['axes.unicode_minus'] = False # 正常显示负号 data = pd.read_csv('E:\study\PythonStudy\python60-days-challenge-master\data.csv') #读取数据 # 先筛选字符串变量 discrete_features = data.select_dtypes(include=['object']).columns.tolist() # Home Ownership 标签编码 home_ownership_mapping = { 'Own Home': 1, 'Rent': 2, 'Have Mortgage': 3, 'Home Mortgage': 4 } data['Home Ownership'] = data['Home Ownership'].map(home_ownership_mapping) # Years in current job 标签编码 years_in_job_mapping = { '< 1 year': 1, '1 year': 2, '2 years': 3, '3 years': 4, '4 years': 5, '5 years': 6, '6 years': 7, '7 years': 8, '8 years': 9, '9 years': 10, '10+ years': 11 } data['Years in current job'] = data['Years in current job'].map(years_in_job_mapping) # Purpose 独热编码,记得需要将bool类型转换为数值 data = pd.get_dummies(data, columns=['Purpose']) data2 = pd.read_csv("E:\study\PythonStudy\python60-days-challenge-master\data.csv") # 重新读取数据,用来做列名对比 list_final = [] # 新建一个空列表,用于存放独热编码后新增的特征名 for i in data.columns: if i not in data2.columns: list_final.append(i) # 这里打印出来的就是独热编码后的特征名 for i in list_final: data[i] = data[i].astype(int) # 这里的i就是独热编码后的特征名 # Term 0 - 1 映射 term_mapping = { 'Short Term': 0, 'Long Term': 1 } data['Term'] = data['Term'].map(term_mapping) data.rename(columns={'Term': 'Long Term'}, inplace=True) # 重命名列 continuous_features = data.select_dtypes(include=['int64', 'float64']).columns.tolist() #把筛选出来的列名转换成列表 # 连续特征用中位数补全 for feature in continuous_features: mode_value = data[feature].mode()[0] #获取该列的众数。 data[feature].fillna(mode_value, inplace=True) #用众数填充该列的缺失值,inplace=True表示直接在原数据上修改。 # 最开始也说了 很多调参函数自带交叉验证,甚至是必选的参数,你如果想要不交叉反而实现起来会麻烦很多 # 所以这里我们还是只划分一次数据集 from sklearn.model_selection import train_test_split X = data.drop(['Credit Default'], axis=1) # 特征,axis=1表示按列删除 y = data['Credit Default'] # 标签 # 按照8:2划分训练集和测试集 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # 80%训练集,20%测试集 from sklearn.ensemble import RandomForestClassifier #随机森林分类器 from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score # 用于评估分类器性能的指标 from sklearn.metrics import classification_report, confusion_matrix #用于生成分类报告和混淆矩阵 import warnings #用于忽略警告信息 warnings.filterwarnings("ignore") # 忽略所有警告信息 # --- 1. 默认参数的随机森林 --- # 评估基准模型,这里确实不需要验证集 print("--- 1. 默认参数随机森林 (训练集 -> 测试集) ---") rf_model = RandomForestClassifier(random_state=42) rf_model.fit(X_train, y_train) # 在训练集上训练 rf_pred = rf_model.predict(X_test) # 在测试集上预测 print("\n默认随机森林 在测试集上的分类报告:") print(classification_report(y_test, rf_pred)) print("默认随机森林 在测试集上的混淆矩阵:") print(confusion_matrix(y_test, rf_pred))

二、ROC曲线

from sklearn.metrics import roc_curve, auc import matplotlib.pyplot as plt # 预测测试集上的概率(注意:ROC曲线需要的是预测概率,而不是最终的类别预测) # predict_proba() 返回一个 n_samples x n_classes 的数组,我们需要正类(1)的概率,即第二列 rf_pred_proba = rf_model.predict_proba(X_test)[:, 1] # 1. 计算 ROC 曲线的 FPR 和 TPR # y_test 是真实标签,rf_pred_proba 是正类的预测概率 fpr, tpr, thresholds = roc_curve(y_test, rf_pred_proba) # 2. 计算 AUC (Area Under the Curve) roc_auc = auc(fpr, tpr) # 3. 绘制 ROC 曲线 plt.figure(figsize=(8, 6)) plt.plot(fpr, tpr, color='darkorange', lw=2, label='ROC curve (area = %0.4f)' % roc_auc) plt.plot([0, 1], [0, 1], color='navy', lw=2, linestyle='--', label='Random Guess') # 对角线 plt.xlim([0.0, 1.0]) # 设置 x 轴范围 plt.ylim([0.0, 1.05]) # 设置 y 轴范围,稍微超出 1.0 plt.xlabel('False Positive Rate (FPR)') # x 轴标签 plt.ylabel('True Positive Rate (TPR)') # y 轴标签 plt.title('Receiver Operating Characteristic (ROC) Curve') # 图表标题 plt.legend(loc="lower right") # 图例位置 plt.grid(True) # 显示网格 plt.show() print("\n模型在测试集上的 AUC (Area Under the Curve): %0.4f" % roc_auc) import numpy as np import matplotlib.pyplot as plt from sklearn.metrics import roc_curve, auc # 设置中文字体 plt.rcParams['font.sans-serif'] = ['SimHei'] plt.rcParams['axes.unicode_minus'] = False def plot_distribution_and_roc(mu_neg, mu_pos, title_prefix): # --- 1. 模拟数据 (完全沿用之前的逻辑) --- # 负样本分布 (好人,分数低) n_neg = 10000 neg_scores = np.random.normal(loc=mu_neg, scale=0.15, size=n_neg) # 正样本分布 (坏人,分数高) n_pos = 1000 pos_scores = np.random.normal(loc=mu_pos, scale=0.15, size=n_pos) # 合并 y_true = np.array([0] * n_neg + [1] * n_pos) y_scores = np.concatenate([neg_scores, pos_scores]) # 归一化 y_scores = (y_scores - y_scores.min()) / (y_scores.max() - y_scores.min()) # --- 2. 计算 ROC 曲线的关键差异点 --- # 这里的输入和 PR 曲线一模一样,但输出变成了 FPR 和 TPR fpr, tpr, thresholds = roc_curve(y_true, y_scores) roc_auc = auc(fpr, tpr) # --- 绘图 --- fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(16, 5)) # === 左图:分布图 (保持不变) === ax1.hist(y_scores[y_true==0], bins=50, alpha=0.5, color='blue', label='负样本 (好人/蓝山)', density=True) ax1.hist(y_scores[y_true==1], bins=50, alpha=0.5, color='red', label='正样本 (坏人/红山)', density=True) ax1.set_title(f'{title_prefix}:预测分数分布 (重叠度)', fontsize=14) ax1.set_xlabel('预测概率 (阈值刀从右往左切)') ax1.set_ylabel('密度') ax1.legend() # === 右图:ROC 曲线 (核心变化) === # 绘制 ROC 曲线 ax2.plot(fpr, tpr, color='darkorange', lw=2, label=f'ROC curve (AUC = {roc_auc:.2f})') # 绘制对角线 (随机猜测基准线) ax2.plot([0, 1], [0, 1], color='navy', lw=2, linestyle='--', label='随机猜测 (AUC=0.5)') # 填充曲线下面积 ax2.fill_between(fpr, tpr, color='darkorange', alpha=0.2) ax2.set_title(f'{title_prefix}:对应的 ROC 曲线', fontsize=14) ax2.set_xlabel('FPR (假正率 - 误伤的好人比例) -> 代价', fontsize=12) ax2.set_ylabel('TPR (真正率 - 抓到的坏人比例) -> 收益', fontsize=12) ax2.set_xlim([-0.02, 1.0]) ax2.set_ylim([0.0, 1.05]) ax2.legend(loc="lower right") ax2.grid(True) plt.show() # --- 运行对比 --- # 情况一:模型很差 (山峰严重重叠) # 逻辑:你想抓红球,必然会抓到一大把蓝球。 plot_distribution_and_roc(mu_neg=0.4, mu_pos=0.5, title_prefix="情况A:模型较差(山峰重叠)") # 情况二:模型很好 (山峰分得很开) # 逻辑:你可以先把红球抓干净,都还碰不到蓝球。 plot_distribution_and_roc(mu_neg=0.3, mu_pos=0.8, title_prefix="情况B:模型优秀(山峰分离)")

三、PR曲线

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

7、无线网络与复杂网络配置指南

无线网络与复杂网络配置指南 1. 无线网络用户规则配置 在无线网络环境中,不同用户的需求和权限可能存在差异。以Windows用户Peter和OpenBSD用户Christina为例,我们可以为他们分别设置不同的规则。 Peter仅需上网浏览和访问特定机器上的高端口服务,可在 /etc/authpf/user…

作者头像 李华
网站建设 2026/7/14 6:19:25

Perl Socket 编程

Perl Socket 编程 引言 Perl(Practical Extraction and Report Language)是一种强大的编程语言,广泛应用于文本处理、系统管理、网络编程等领域。在众多应用中,Perl Socket 编程以其简洁、高效的特点备受青睐。本文将详细介绍Perl Socket编程的基础知识、常用方法以及在实…

作者头像 李华
网站建设 2026/7/14 3:06:05

SSC Tools配置项中文详解

一、基础工程与版本配置 在 SSC Tool 主页面&#xff08;SSC-Device界面&#xff09;&#xff0c;首先显示工程的基础配置信息&#xff0c;决定协议栈版本与核心文件关联&#xff0c;是后续配置的前提&#xff1a; 配置项说明与作用关键约束与示例SSC Version显示当前 SSC Too…

作者头像 李华
网站建设 2026/7/12 15:34:08

深入理解 FactoryBean:定制化 Bean 的秘密武器

前言在 Spring 的日常开发中&#xff0c;我们通常使用 Component、Service 或者 Configuration Bean 的方式来定义 Bean。对于大多数简单的对象&#xff08;比如 Controller、Service&#xff09;&#xff0c;这些方式非常直观且高效。但是&#xff0c;假设我们需要创建一个初…

作者头像 李华
网站建设 2026/7/13 12:56:47

金融合规监控规则设计实战(20年专家经验倾囊相授)

第一章&#xff1a;金融合规 Agent 的监控规则概述在现代金融科技架构中&#xff0c;金融合规 Agent 作为实时监控与风险识别的核心组件&#xff0c;承担着确保交易行为符合监管要求的关键职责。该 Agent 通过预设的监控规则集&#xff0c;对资金流动、用户操作及交易模式进行自…

作者头像 李华