当前位置: 首页 > news >正文

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

下采样:机器学习——下采样(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.dtcms.com/a/313486.html

相关文章:

  • 前端工程化:Vue3(一)
  • 2025年EAAI SCI1区TOP,森林救援调度与路径规划:一种新型蚁群优化算法应用,深度解析+性能实测
  • 智能化门禁常见问题处理思路
  • Linux mount挂载选项详解(重点关注nosuid)
  • 使用Perl和库WWW::Curl的爬虫程序!
  • [spring-cloud: 服务注册]-源码解析
  • Spring Boot AOP 优雅实现异常重试机制
  • 多线程异步日志系统与实现及 TCP/IP C/S 模型
  • IO流-字节流-FileOutputStream
  • day50预训练模型 CBAM注意力
  • Effective C++ 条款20:宁以pass-by-reference-to-const替换pass-by-value
  • LeetCode 2122.还原原数组
  • centos7安装桌面客户软件并远程连接
  • 学习笔记《区块链技术与应用》第五天 分叉
  • Matlab 高斯牛顿法拟合曲线
  • 力扣-200.岛屿数量
  • 01数据结构-二叉搜索树
  • PAT 甲级题目讲解:1012《The Best Rank》
  • 【硬件-笔试面试题】硬件/电子工程师,笔试面试题-55,(知识点:STM32,外设及其特点)
  • 力扣-124.二叉树中的最大路径和
  • LLM调研
  • 计算用户日活:从数据设计到可视化的全流程(高频场景题)
  • 秋招笔记-8.3
  • AUTOSAR进阶图解==>AUTOSAR_RS_SystemTemplate
  • 元宇宙三维化会给游戏行业带来哪些改变?
  • 什么是列存储(Columnar Storage)?深度解析其原理与应用场景
  • 常见的深度学习模块/操作中的维度约定(系统性总结)
  • io_cancel系统调用及示例
  • e2studio开发RA4M2(6)----GPIO外部中断(IRQ)配置
  • 算法题(181):最大直方矩形面积