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

(完整代码在底部)


解决样本不平衡问题:SMOTE 过采样实战讲解

在实际的机器学习任务中,数据集往往存在类别不平衡问题,尤其是在信用卡欺诈检测、疾病预测等场景中,正样本极其稀少。若不处理这一问题,模型更倾向于预测多数类,导致 recall 值(召回率)偏低。

SMOTE 的核心思想是:不是复制已有少数类样本,而是通过“插值”方式生成新的样本点,使少数类样本在特征空间中更丰富、分布更自然。

说白了就是在每两个同类别的点之间插入新点,也同样是此类别

工作步骤如下:

  1. 找邻居
    对于每一个少数类样本,SMOTE 会在该类中找到若干个(如 5 个)“最近邻”样本。

  2. 随机选择邻居
    从这几个邻居中,随机选一个作为“参考点”。

  3. 插值生成新样本
    在原样本和参考点之间,以一定比例随机插值,生成一个“新的样本点”。
    也就是说,这个新样本不是原样本的复制,也不是邻居样本的复制,而是它们之间的“连线上的点”。

    数学公式如下(对特征向量来说):

    • xi​:原始少数类样本

    • xn​:其某个邻居

    • λ:0~1之间的随机数,决定插值比例

  4. 重复以上过程,直到少数类样本数量和多数类一样多,达到“类别平衡”。

本篇文章将通过信用卡欺诈检测数据集(creditcard.csv),演示如何使用 SMOTE 方法对训练集进行过采样,并对比模型在过采样前后的性能表现差异。


一、引入所需模块

import numpy as np
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
# from imblearn.over_sampling import SMOTE # 过采样

二、数据预处理

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

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

  • 样本总数:284,807 条

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

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

     

读取数据并标准化金额列

# 读取信用卡欺诈数据集
data = pd.read_csv('creditcard.csv')# 对“Amount”金额列进行标准化(均值为0,标准差为1)
scaler = StandardScaler()
data['Amount'] = scaler.fit_transform(data[['Amount']])# 删除无关的“Time”列
data = data.drop("Time", axis=1)

特征与标签划分

# 分离特征和目标变量
X = data.drop("Class", axis=1)  # 特征变量
y = data.Class                  # 目标变量(是否欺诈)

划分训练集与测试集

# 将数据划分为训练集和测试集,比例为7:3
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=100)

三、原始数据模型训练与评估

# 使用原始训练数据训练逻辑回归模型
model = LogisticRegression()
model.fit(X_train, y_train)

查看原始类别分布

# 查看原始数据中正负样本(欺诈/正常交易)的数量
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))

这种情况下,模型可能在类别为“1”(欺诈)的召回率较低,常见表现为:

  • precision 较高,但 recall 偏低

  • 模型倾向于预测为正常交易


四、使用 SMOTE 进行过采样

进行训练集过采样

# ======================== 使用 SMOTE 过采样 ========================
from imblearn.over_sampling import SMOTE
# 对训练数据进行过采样,使正负样本数量相同
oversampler = SMOTE(random_state=100)
X_train_os, y_train_os = oversampler.fit_resample(X_train, y_train)

注意:测试集不要过采样,保持原始分布才能真实评估模型性能。

查看过采样后的数据组成

# 查看过采样后训练数据中正负样本的数量
labels_count_under = pd.value_counts(y_train_os)
print("下采样数据组成:\n", labels_count_under)

示例输出:199014为284807的%70

原理步骤:

  1. 对每个少数类样本,找到其最近的 k 个同类邻居(默认 k=5)

  2. 随机选取若干邻居点

  3. 在原样本和邻居之间插值生成“合成样本”(就是在两两之间多插入几个数据

  4. 不是复制已有样本,而是生成新的样本点,更丰富、更自然


五、使用过采样数据训练模型

# 使用过采样后的数据重新训练逻辑回归模型
model_os = LogisticRegression(C=10, penalty='l2', max_iter=1000)
model_os.fit(X_train_os, y_train_os)

在原始测试集上评估新模型

# 在原始测试集上评估过采样模型的性能
print("‘过采样数据训练得到的模型’ 对 ‘原数据的测试集’ 的测试:")
predictions_test = model_os.predict(X_test)
print(metrics.classification_report(y_test, predictions_test))

评估对比与说明

指标/类别原模型过采样模型解读
类别 1 Recall(召回率)0.650.88过采样显著提高了识别能力
类别 1 Precision(精准率)0.770.06 ❌误报大幅增加,很多 0 被错判为 1(宁杀错
类别 1 F1-score(平衡指标)0.700.11 ❌整体准确性下降
类别 0 Recall1.00 ✅0.98正常交易略受影响
总体 Accuracy1.000.98正确率略下降
Macro avg Recall0.820.93两类平均召回提升

六、结果对比分析

指标原始模型SMOTE过采样模型
Precision(1类)较高较高
Recall(1类)较低明显提升
F1-score(1类)偏低显著提升
Accuracy接近1可能略有下降

🎯 结论:SMOTE 有效提高了模型对少数类(欺诈行为)的识别能力,在保持总体准确率的同时显著改善了 recall 和 F1-score,是处理不平衡问题的有效方法之一。


七、总结与建议

  • SMOTE(Synthetic Minority Over-sampling Technique)通过生成新的少数类样本来平衡数据分布,是一种优于简单复制的过采样方式。

  • 在不平衡数据场景中,评估指标应以 recall/F1-score 为主,而非 accuracy。

  • SMOTE 适合用于训练集,而不应作用于测试集。

  • 逻辑回归 + SMOTE 是一种简单有效的基线方案,可用于模型初步构建与对比。


完整代码:

import numpy as np
import pandas as pd
from sklearn import metrics
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.preprocessing import StandardScaler# 读取信用卡欺诈数据集
data = pd.read_csv('creditcard.csv')# 对“Amount”金额列进行标准化(均值为0,标准差为1)
scaler = StandardScaler()
data['Amount'] = scaler.fit_transform(data[['Amount']])# 删除无关的“Time”列
data = data.drop("Time", axis=1)# 分离特征和目标变量
X = data.drop("Class", axis=1)  # 特征变量
y = data.Class                  # 目标变量(是否欺诈)# 将数据划分为训练集和测试集,比例为7:3
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=100)# 使用原始训练数据训练逻辑回归模型
model = LogisticRegression()
model.fit(X_train, y_train)# 查看原始数据中正负样本(欺诈/正常交易)的数量
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))# ======================== 使用 SMOTE 过采样 ========================
from imblearn.over_sampling import SMOTE
# 对训练数据进行过采样,使正负样本数量相同
oversampler = SMOTE(random_state=100)
X_train_os, y_train_os = oversampler.fit_resample(X_train, y_train)# 使用过采样后的数据重新训练逻辑回归模型
model_os = LogisticRegression(C=10, penalty='l2', max_iter=1000)
model_os.fit(X_train_os, y_train_os)# 查看过采样后训练数据中正负样本的数量
labels_count_under = pd.value_counts(y_train_os)
print("过采样数据组成:\n", labels_count_under)# 在原始测试集上评估过采样模型的性能
print("‘过采样数据训练得到的模型’ 对 ‘原数据的测试集’ 的测试:")
predictions_test = model_os.predict(X_test)
print(metrics.classification_report(y_test, predictions_test))

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

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

相关文章

Ettus USRP X440 进行“超短波个人卫星信号的侦查与干扰”任务

结合 Ettus USRP X440 进行“超短波个人卫星信号的侦查与干扰”任务,可以构建一个高性能、灵活可编程的电子对抗系统原型平台。以下是面向科研/工程/军用验证场景的构思和技术文案: 🛰️ 项目名称建议(可选)&#xff1…

如何在出售Windows11/10/8/7前彻底清除电脑数据

为了保护您的个人数据,在出售电脑前彻底清除数据是一个明智之举。然而,仅仅删除文件是不够的,因为恢复工具通常可以恢复它们。因此,本指南分享了如何在出售电脑前清除数据,包括 Windows 11/10/8/7,确保您的…

Go语言实战案例:多协程并发下载网页内容

本文是《Go语言100个实战案例 网络与并发篇》第6篇,实战演示如何使用 Goroutine 和 Channel,实现多协程并发抓取网页内容,提升网络请求效率,为构建爬虫、内容聚合器、API 批量采集器打下基础。一、实战背景在互联网项目中&#x…

分享链接实现状态共享

有这么一个场景:就是有一些列表页面,然后上面是有一些筛选项的,我去对这个列表做了一些筛选出来一个结果,然后我想把这个链接,或者说把这个筛选结构给分享出去,让别人在打开这个页面的时候,也是…

Fay数字人如何使用GPT-SOVITS进行TTS转换以及遇到的一些问题

一、GPT-SoVITS 简介 GPT-SoVITS 是一款开源的语音合成(TTS)工具,结合了 GPT 模型的文本理解能力与 SoVITS(Sound of Voice In Text-to-Speech)的声纹模拟技术,能够实现高自然度、个性化的语音合成。它支持…

HTML 颜色值

HTML 颜色值 引言 在网页设计和开发中,颜色是一个重要的元素,它能够帮助用户更好地理解内容,提升视觉效果。HTML 颜色值是用于指定网页中元素颜色的一种标准表示方法。本文将详细介绍 HTML 颜色值的种类、表示方法以及在实际应用中的使用技巧。 HTML 颜色值种类 HTML 颜…

关于记录一下“bug”,在做图片上传的时候出现的小问题

项目场景:之前的话写过csdn,最近出现了一些小事情,所以耽误了好久没有更新,最近把以前的项目拿出来然后改了下环境就出现了一些问题,该项目使用SpringBoot3.5 SpringMVC Mybatis-Plus3.5.0,然后权限控制采…

数据结构:基础知识和链表①

一、概念程序数据结构算法1.描述数据存储和操作的结构 2.操作数据对象的方法二、衡量代码的质量和效率 无论代码操作数据量多大,希望程序代码的运行时间保持恒定 随着数据的增长,程序运行时间缓慢增长随着数据的增长,程序运…

进阶向:自动化天气查询工具(API调用)

自动化天气查询工具(API调用)完全指南天气数据是日常生活中经常需要查询的信息之一。本教程将介绍如何使用Python编写一个自动化天气查询工具,通过调用开放的天气API获取实时天气数据。这个工具适合完全不懂编程的新手学习,将从最…

【ROS2】常用命令

1、目录结构在 ROS 2 包中,launch、urdf、rviz(通常指 RViz 配置文件)、config 等文件夹应直接放在包的根目录下(与 robot_arm/ Python 模块目录同级)。这是 ROS 2 社区的通用约定,便于工具(如 …

基础组件(三):mysql连接池

文章目录一、MySQL连接池设计1. 连接池解决了什么问题?连接池的作用 (好处)为什么不创建多条连接而用连接池2. 同步和异步连接池的区别同步连接池(场景局限,应用服务器启动时初始化资源)异步连接池&#xf…

FI文件包含漏洞

本地文件包含(LFI)文件包含开发人员将可重复使用的内容写到单个文件中,使用时直接调用此文件,无需再次编写,这种调用文件的过程一般被称为文件包含。这样编写代码能减少代码冗余,降低代码后期维护难度&…

rapidocr_web v1.0.0发布了

建立RapidOCRWeb独立仓库 终于将web这块代码移了出来,成立了独立仓库RapidOCRWeb (https://github.com/RapidAI/RapidOCRWeb )。这样以来,RapidOCR仓库下的各个衍生项目均有自己的独立仓库,可以单独控制发版和维护。这也算是为RapidOCR减负了…

Arduino IDE离线安装ESP8266板管理工具

文章目录概要官网地址开发板管理地址安装ESP8266开发板支持离线安装额外记录NODE启动服务概要 Arduino IDE离线安装ESP8266板管理工具&#xff0c;在线安装因为网络或者https的问题不能安装 官网地址 Adruino&#xff1a;https://www.arduino.cc/ ESP8266项目&#xff1a;<…

两款免费数据恢复软件介绍,Win/Mac均可用

数据已成为我们生活与工作中不可或缺的重要组成部分。无论是珍贵的家庭照片、关键的工作文档&#xff0c;还是重要的学习资料&#xff0c;都以数据的形式存储在各类设备中。然而&#xff0c;数据丢失的情况却时常发生&#xff0c;可能是误操作删除&#xff0c;可能是设备意外损…

Java开发中敏感信息加密存储全解析:筑牢数据安全防线

Java开发中敏感信息加密存储全解析&#xff1a;筑牢数据安全防线 一、引言 1.1 敏感信息存储的现状与挑战 在数字化时代&#xff0c;数据已然成为企业和组织的核心资产之一&#xff0c;而敏感信息的存储更是重中之重。从日常的用户登录密码、身份证号码&#xff0c;到金融领域…

list的使用和模拟

(一)list的了解 (1)简单了解 list的文档介绍 list是基于双向链表的序列式容器&#xff0c;支持双向迭代和任意位置的常数时间插入删除&#xff0c;相比 array、vector 等容器在这类操作上更高效&#xff0c;但不支持随机访问&#xff08;访问需线性遍历&#xff09;且因额外…

Docker 初学者需要了解的几个知识点 (五):建容器需要进一步了解的概念

之前在《Docker 初学者需要了解的几个知识点》几篇文章里&#xff0c;我们梳理了 Docker 的核心概念&#xff08;如镜像、容器、网络等&#xff09;&#xff0c;但在实际搭建 ThinkPHP 容器环境时&#xff0c;又遇到了一些更具体的术语和配置场景。这些内容和实操结合紧密&…

【数据结构】栈的顺序存储(整型栈、字符栈)

【数据结构】栈的顺序存储&#xff08;整型栈、字符栈&#xff09;一、栈的结构定义二、字符栈的初始化、入栈、出栈、判断是否栈为空、获取栈顶元素、获取栈的当前元素个数等操作三、整型栈的初始化、入栈、出栈、判断是否栈为空、获取栈顶元素、获取栈的当前元素个数等操作一…

【大模型实战】向量数据库实战 - Chroma Milvus

在 RAG&#xff08;检索增强生成&#xff09;场景中&#xff0c;非结构化数据&#xff08;文本、图像等&#xff09;的高效检索是核心需求。传统关系型数据库难以胜任&#xff0c;而向量数据库通过将数据转化为向量、基于相似度快速匹配&#xff0c;成为 RAG 的关键支撑。本文聚…