机器学习——下采样(UnderSampling),解决类别不平衡问题,案例:逻辑回归 信用卡欺诈检测

过采样:

机器学习——过采样(OverSampling),解决类别不平衡问题,案例:逻辑回归 信用卡欺诈检测-CSDN博客

(完整代码在底部)


使用下采样解决类别不平衡问题 —— 以信用卡欺诈识别为例

在实际机器学习任务中,**类别不平衡问题(Imbalanced Classification Problem)**极为常见,特别是在金融风控、医疗诊断等领域。例如,信用卡欺诈交易仅占总交易数的一小部分,而模型往往容易“偏向”多数类,导致模型虽有高精度但检测效果极差。

本文将演示一种常用的应对策略:下采样(undersampling)


一、什么是下采样?

下采样是指从样本数量较多的类别中随机抽取一部分样本,使其与少数类的数量一致,从而达到类别平衡的目的。它的优点是简洁快速,缺点是可能舍弃有价值的信息,但在数据量非常大的情况下,通常是一种高效方案。


二、完整代码解析与步骤讲解

🔹 1. 导入依赖并读取数据

import pandas as pd
from sklearn import metrics
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler# 读取信用卡欺诈数据集
data = pd.read_csv('creditcard.csv')

 信用卡欺诈检测数据集 creditcard.csv

  • 数据来源信用卡欺诈检测实战数据集_数据集-阿里云天池https://tianchi.aliyun.com/dataset/101562?accounttraceid=c1258603818f44d6a57fe125248cc969rkgu

  • 样本总数:284,807 条

  • 特征数:30(28个匿名特征 + 金额 Amount + 时间 Time

  • 目标变量Class(0=正常交易,1=欺诈交易)

    

🔹 2. 数据预处理

# 标准化 Amount 字段(转换为均值为0、标准差为1的分布)
scaler = StandardScaler()
data['Amount'] = scaler.fit_transform(data[['Amount']])  # 用标准化结果替换原始 'Amount'# 删除无关的 Time 字段
data = data.drop("Time", axis=1)

标准化 Amount 字段有助于模型更快收敛;而 Time 特征在本任务中并无实际贡献,故直接删除。


三、原始数据训练模型

🔹 拆分训练集和测试集

# 将特征和标签分开
X = data.drop("Class", axis=1)  # 特征变量
y = data.Class                  # 标签变量# 拆分原始数据为训练集和测试集(70%训练,30%测试)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=100)

🔹 构建并训练模型

# 在原始数据上训练逻辑回归模型
model = LogisticRegression(C=10, penalty='l2', max_iter=1000)
model.fit(X_train, y_train)

🔍 在原始测试集上评估

# 原数据的‘0’‘1’组成
labels_count = pd.value_counts(data['Class'])
print("原数据组成:\n",labels_count)# 原始数据训练的模型,对原始测试集进行预测
print("‘原数据训练得到的模型’ 对 ‘原数据的测试集’ 的测试:")
predictions_test = model.predict(X_test)
print(metrics.classification_report(y_test, predictions_test))  # 输出分类评估指标

数据组成:可见欺诈交易极少,若不处理,模型训练会极度偏向“正常交易”,导致高精度但低召回。

recall(0)=1 , recall(1)=L:0.65

全部的0都被检查出来了,,但只有%65的1被检测出来。

这一步展示了原始数据训练出来的模型在测试集上的效果,由于训练数据严重不平衡,模型倾向于预测“正常交易”,虽然整体准确率高,但对“欺诈交易”的识别能力可能很差。


四、应用下采样处理数据不平衡

🔹 构造平衡数据集

# ============ 下采样处理开始 ============
# 获取正常交易样本(Class=0)和欺诈交易样本(Class=1)
class_0 = data[data['Class'] == 0]
class_1 = data[data['Class'] == 1]# 从正常交易中随机采样,数量与欺诈交易相同,实现类别平衡
class_0 = class_0.sample(len(class_1))# 合并下采样后的正常交易与全部欺诈交易
data_under = pd.concat([class_0, class_1])

此处,原始正常交易有数十万条,而欺诈交易不足千条。下采样使得两个类别数量一致。

🔹 拆分下采样后的训练与测试集

# 构建下采样数据的特征和标签
X_under = data_under.drop("Class", axis=1)
y_under = data_under.Class# 拆分下采样数据为训练集和测试集
X_train_under, X_test_under, y_train_under, y_test_under = train_test_split(X_under, y_under, test_size=0.3, random_state=100)

五、用下采样数据训练新模型

# 使用下采样数据训练逻辑回归模型
model_under = LogisticRegression(C=10, penalty='l2', max_iter=1000)
model_under.fit(X_train_under, y_train_under)

这一步训练的是“下采样数据训练出来的模型”,它更公平地学习了两类样本特征,更有可能识别欺诈交易


六、评估新模型在原始测试集的效果

# 下采样数据的‘0’‘1’组成
labels_count_under = pd.value_counts(data_under['Class'])
print("下采样数据组成:\n",labels_count_under)# 用下采样模型对原始测试集进行预测
print("‘下采样数据训练得到的模型’ 对 ‘原数据的测试集’ 的测试:")
predictions_test = model_under.predict(X_test)
print(metrics.classification_report(y_test, predictions_test))  # 输出评估报告

  • 从正常交易中随机抽取492条样本

  • 再与所有欺诈交易(492条)组合,得到总共 984 条样本的下采样数据集

  • 这使得逻辑回归模型在训练过程中对两个类别给予相同权重学习,提升模型识别少数类的能力。

此处,我们用下采样模型对原始数据测试集做预测,看看在现实中(多数为正常交易)的表现是否更好地平衡了 recall 与 precision


七、实验对比分析:原始模型 vs 下采样模型

原始模型的特点

  • 正常交易识别非常完美(precision=1.00, recall=1.00)

  • 欺诈交易识别较弱:虽然 precision 有 0.77,但 recall 仅为 0.65,意味着 仍有 35% 欺诈交易未被识别

  • 整体准确率为 1.00,但这种“高准确率”是由数据极度不平衡带来的幻象

下采样模型的特点

  • 正常交易略有误识别(recall 从 1.00 降至 0.95),但仍保持高 precision

  • 对欺诈交易的 recall 高达 0.93,意味着识别出了 93% 欺诈交易,虽然 precision 非常低(0.04)

  • 整体准确率下降为 0.96,但在安全场景中,召回率往往更重要


八、效果分析与建议

✅ 模型优点:

  • 训练集平衡 → 提升对少数类(如欺诈交易)的学习能力

  • 训练速度快 → 数据量减少

⚠️ 模型局限:

  • 丢弃部分多数类样本 → 信息损失

  • 在样本稀缺的场景不推荐使用(建议用过采样)


总结

方案原始模型下采样模型
优势保留全部数据解决类别不平衡
缺点偏向多数类可能舍弃有价值的信息
精度高(总体)偏向 recall
适用场景多数类重要少数类重要(如欺诈识别)

在高度不平衡的分类任务中,下采样是一个简单且常见的解决方案。与模型调参、特征选择配合使用,能取得不错的效果。

所以本专栏还有过采样(OverSampling)文章


完整代码:

import pandas as pd
from sklearn import metrics
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler# 读取信用卡欺诈数据集
data = pd.read_csv('creditcard.csv')# 标准化 Amount 字段(转换为均值为0、标准差为1的分布)
scaler = StandardScaler()
data['Amount'] = scaler.fit_transform(data[['Amount']])  # 用标准化结果替换原始 'Amount'# 删除无关的 Time 字段
data = data.drop("Time", axis=1)# 将特征和标签分开
X = data.drop("Class", axis=1)  # 特征变量
y = data.Class                  # 标签变量# 拆分原始数据为训练集和测试集(70%训练,30%测试)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=100)# 在原始数据上训练逻辑回归模型
model = LogisticRegression(C=10, penalty='l2', max_iter=1000)
model.fit(X_train, y_train)# 原数据的‘0’‘1’组成
labels_count = pd.value_counts(data['Class'])
print("原数据组成:\n",labels_count)
# 原始数据训练的模型,对原始测试集进行预测
print("‘原数据训练得到的模型’ 对 ‘原数据的测试集’ 的测试:")
predictions_test = model.predict(X_test)
print(metrics.classification_report(y_test, predictions_test))  # 输出分类评估指标# ============ 下采样处理开始 ============# 获取正常交易样本(Class=0)和欺诈交易样本(Class=1)
class_0 = data[data['Class'] == 0]
class_1 = data[data['Class'] == 1]# 从正常交易中随机采样,数量与欺诈交易相同,实现类别平衡
class_0 = class_0.sample(len(class_1))# 合并下采样后的正常交易与全部欺诈交易
data_under = pd.concat([class_0, class_1])# 构建下采样数据的特征和标签
X_under = data_under.drop("Class", axis=1)
y_under = data_under.Class# 拆分下采样数据为训练集和测试集
X_train_under, X_test_under, y_train_under, y_test_under = train_test_split(X_under, y_under, test_size=0.3, random_state=100)# 使用下采样数据训练逻辑回归模型
model_under = LogisticRegression(C=10, penalty='l2', max_iter=1000)
model_under.fit(X_train_under, y_train_under)# 下采样数据的‘0’‘1’组成
labels_count_under = pd.value_counts(data_under['Class'])
print("下采样数据组成:\n",labels_count_under)
# 用下采样模型对原始测试集进行预测
print("‘下采样数据训练得到的模型’ 对 ‘原数据的测试集’ 的测试:")
predictions_test = model_under.predict(X_test)
print(metrics.classification_report(y_test, predictions_test))  # 输出评估报告

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/917372.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/917372.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Qt 槽函数被执行多次,并且使用Qt::UniqueConnection无效【已解决】

Qt 槽函数被执行多次,并且使用Qt::UniqueConnection无效引言一、问题描述二、解决方案三、深入了解信号和槽绑定机制引言 之前刚遇到 - 信号和槽正常连接返回true,但发送信号后槽函数无响应问题,现在又遇到槽函数执行多次,使用Qt…

Autosar Nm-网管报文PNC停发后无法休眠问题排查

文章目录前言Autosar CanNm标准中的相关参数CanNmAllNmMessagesKeepAwakePN过滤功能CanNm_ConfirmPnAvailability问题描述问题原因排查解决方案扩展总结前言 Autosar Nm中针对于支持PN功能的收发器,要求PNC停发后允许进入休眠模式,开发过程中遇到PNC停发…

RK3568下的进程间通信:基于UDP的mash网络节点通信

基于UDP的mash网络节点通信系统实现: 最近的项目中需要实现一个功能,类似mash网络的功能,比如 类似下图中的多个节点之间,相互之间通信, 节点A自身的通信列表中,只有B和C,所以A发出的消息给B和C,依次类推,A发送的消息所有节点都能收到,同理,其他节点比如K节点发送的…

Effective C++ 条款17:以独立语句将newed对象置入智能指针

Effective C 条款17:以独立语句将newed对象置入智能指针核心思想:使用智能指针管理动态分配的对象时,必须确保new操作与智能指针构造在同一独立语句中完成,避免编译器优化顺序导致的内存泄漏。 ⚠️ 1. 跨语句初始化的危险性 资源…

Linux iptables防火墙操作

资料: 网络运维相关 - iptables 【Main】 https://www.zsythink.net/archives/tag/iptables/ netfilter 在 Linux 内核 TCP/IP协议栈中的位置 【框架】【Aulaxiry】 https://zhuanlan.zhihu.com/p/93630586 1 概念详解 ● 防火墙概念 ○ 主机防火墙 网络防火墙 ○…

飞书推送工具-自动化测试发送测试报告一种方式

飞书推送工具 要获取飞书开发所需的 APP_ID、APP_SECRET 以及用户的 USER_ID,需通过飞书开放平台和飞书客户端的相关设置操作。以下是详细步骤: 一、获取 APP_ID 和 APP_SECRET(飞书应用凭证) APP_ID 和 APP_SECRET 是飞书开放…

从零开始的云计算生活——第三十七天,跬步千里,ansible之playbook

目录 一.故事剧情 二.Playbook简介 三.Playbook核心元素(重要) 四.Playbook语法 五.Playbook的运行方式 六.Playbooks中tasks语法使用 1、file 2、lineinfile 3、replace 4、shell 5、debug 6、template/copy 7、fetch 8、unarchive 9、wait_for 10、yum 11、…

AI驱动下的数据新基建:腾讯游戏数据资产治理与湖仓架构革新

在大模型技术迅猛发展的今天,AI 正深度重塑数据基础设施,推动其向智能化快速演进。如何将 AI 深度融入数据管理,释放数据的潜在价值、提升运营效率,成为企业在构建 AI 驱动的数据资产管理体系的核心问题。在近期举办的“DataFun A…

ubuntu 系统风扇控制软件 CoolerControl

背景 A6000显卡的温度一直都是86度左右,GPU的风扇转速不够大。 我首先把 nvidia的驱动更新了,但是发现风扇依然依然保持在较低的转速。 后面无意间搜到了CoolerControl 这个linux平台的风扇控制软件。设置之后,增加了风扇的转速,…

Oracle 11gR2 Clusterware应知应会

Oracle 11gR2 Clusterware应知应会 关键特性 启动顺序 日志路径 资源状态 资源管理 关键特性 📖 Oracle 11gR2 Clusterware的一些关键特性如下: 在安装运行11gR2的Real Application Clusters数据库之前需要先安装11gR2 Clusterware。 GRID home包括Oracle Clusterware和AS…

微信小程序苹果手机和安卓,怎么做适配

1. 基于 rpx 单位进行布局适配微信小程序采用 rpx 作为尺寸单位,以实现不同设备的布局适配。小程序的屏幕宽度固定为 750rpx,在不同设备上通过动态计算 1rpx 对应的像素值进行适配。例如,在 iPhone 6 中,屏幕宽度为 375px&#xf…

XGBoost三部曲:XGBoost参数详解

之前已经介绍了XGBoost三部曲:XGBoost原理。本文详细介绍XGBoost参数,让大家在使用XGBoost的过程中能得心应手。后续会更新XGBoost实战,敬请期待。 文章目录 一、核心概念回顾 二、XGBoost算法参数整体介绍 1 原生接口和Scikit-learn接口的区别 2 参数分类详解 三、核心Boos…

【python】转移本地安装的python包

我们现在需要将某个环境已经安装的 python 包离线传递到另外一个环境,且确保这种安装行为最终不需要对 PYPI 中央仓库的有效连接,也能完成。下面给出两种办法: docker container 如果你的 python 环境位于某个容器内,那最好的办法…

TGD第十篇:当神经网络遇到TGD特征

目录一、实验背景二、实验设置三、实验结果和分析四、结语TGD 是我们定义的一种新的“变化率表征”,对连续函数而言是一种新的“广义导数”,对离散序列而言是一种新的差分。TGD 是一个名字,一个代号。在基于 TGD 的图像边缘检测以及视频边缘检…

FreeRTOS源码分析二:task启动(RISCV架构)

系列文章目录 FreeRTOS源码分析一:task创建(RISCV架构) 文章目录系列文章目录前言vTaskStartScheduler 调度器启动函数xPortStartScheduler架构特定调度器启动函数vPortSetupTimerInterrupt启动 RISCV 定时器中断xPortStartFirstTask启动第一…

Python编程基础与实践:Python基础运算符与表达式入门

Python运算符与表达式实战 学习目标 通过本课程的学习,学员可以掌握Python中算术运算符、比较运算符、逻辑运算符及赋值运算符的使用方法,并能够构建简单的表达式来解决实际问题。 相关知识点 Python运算符与表达式 学习内容 1 Python运算符与表达式 1.1…

Git下载全攻略(未更新完)

一、在 Windows 上安装 Git​ ​​​ 1.1 下载安装包​ 官方版本可在 Git 官方网站下载,打开Redirecting…,下载会自动开始。此安装包来自名为 Git for Windows 的项目(也称作 msysGit),它与 Git 本身是相互独立的项目,更多相关信息可访问Redirecting Git for Windows…

rocky\centos安装docker镜像的命令

1.安装依赖: sudo yum install -y yum-utils device-mapper-persistent-data lvm22. 选择仓库源: sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo阿里源: sudo yum-config-manager --add-r…

扣子,正式拥抱开源!

资料来源:火山引擎-开发者社区 扣子 是新一代 AI Agent 平台,旗下有四款子产品:「扣子空间」、「扣子开发平台」、「扣子罗盘」 及 Eino 。 我们始终坚信,AI Agent 的未来属于每一位开发者和创造者。为了让前沿的 AI 技术能够更快…

Git 各场景使用方法总结

以下是对 Git 各场景使用方法的全面总结,涵盖 20+ 核心场景和 100+ 命令,包含详细参数、使用示例及原理说明: 一、基础操作场景 1. 仓库初始化 # 本地初始化 git init git init --bare # 创建裸仓库(无工作区) git init -b main # 指…