【Python预处理系列】深入理解过采样技术及其Python实现

目录

一、过采样简介

二、过采样的实现方法

三、过采样和欠采样是数据增强吗

四、Python实现SMOTE过采样

(一) 生成不平衡数据集

(二)  将数据集转换为DataFrame,便于展示

(三) 应用SMOTE算法进行过采样

(四) 可视化原始数据分布

 (五) 可视化过抽样后的数据分布

(六)补充:X_pca 和y是怎么联系的,当时X_pca = pca.fit_transform(X) 其中也没有用到y呀  

本文旨在为读者提供一个关于过采样技术的全面概述,包括其基本概念、实现方法以及与数据增强的关系。过采样是处理不平衡数据集的常用技术之一,通过增加少数类的样本来平衡类别分布。我们将重点介绍SMOTE(合成少数过采样技术)算法,并通过Python代码示例演示如何在不平衡数据集上应用SMOTE进行过采样。文章还将探讨过采样和欠采样是否属于数据增强的范畴,并解释在PCA降维过程中X_pca与y之间的内在联系。最后,我们将对比展示过采样前后的数据分布情况,以直观地理解过采样对数据集的影响。无论您是数据科学新手还是希望深化对不平衡学习问题处理方法的理解,本文都将为您提供有价值的见解和实用技巧。

一、过采样简介

过采样(Oversampling)是一种用于处理数据集中类别不平衡问题的技术。在数据集中,当一个类的样本数量远少于另一个类时(例如,正类样本远少于负类样本),模型训练可能会偏向于数量较多的类,导致模型在少数类上的性能不佳。过采样通过增加少数类的样本数量来尝试解决这个问题,使得类别分布更加均匀。

二、过采样的实现方法

  1. 简单复制(Random Oversampling): 这是最简单的过采样方法,直接通过随机复制少数类中的样本来实现。这种方法操作简单,但容易导致过拟合,因为复制的数据并没有增加新的信息。

  2. SMOTE(Synthetic Minority Oversampling Technique): SMOTE是一种更为先进的过采样技术。它不是简单复制现有的少数类样本,而是通过在少数类样本之间进行插值来创建新的合成样本。具体来说,对于每个少数类样本,算法会找到其k个最近邻,然后在这些近邻之间随机选择一个点,并与原始样本之间进行线性插值来生成新的样本。

  3. ADASYN(Adaptive Synthetic Sampling): ADASYN是一种改进的SMOTE算法,它根据少数类样本在特征空间中的分布自动调整采样过程。在类别边界附近,ADASYN会更多地生成新的合成样本。

  4. SMOTE-ENN(SMOTE with Edited Nearest Neighbors): 结合了SMOTE和Tomek Links的过采样方法。在生成合成样本之后,使用ENN(Edited Nearest Neighbors)方法删除那些可能导致过拟合的样本。

  5. SMOTE-RSB(SMOTE with Repeated Simplified Basic): 该方法结合了SMOTE和简化基本过采样(Simplified Basic Oversampling)的策略,通过重复采样来增强少数类的样本。

  6. 其他变种: 还有一些其他基于SMOTE的变种方法,比如使用不同的距离度量(如马氏距离)或考虑样本权重等因素。

过采样方法的选择取决于具体的数据集和任务。需要注意的是,过采样可能会引入噪声,增加模型的复杂度,因此在实际应用中需要谨慎使用,并常常结合交叉验证等技术来评估模型性能。在Python中,imbalanced-learn(或imblearn)库提供了多种过采样方法的实现。

三、过采样和欠采样是数据增强吗

过采样和欠采样通常不被视为数据增强技术。虽然它们都涉及到对数据集的操作,但它们的目的和方法与数据增强有所不同。

数据增强(Data Augmentation): 数据增强是一种在训练数据集中创建新的训练样本的技术,通常用于图像、语音和文本等领域。数据增强的目的是通过增加数据的多样性来提高模型的泛化能力。例如,在图像处理中,数据增强可能包括旋转、缩放、裁剪、翻转等操作。

四、Python实现SMOTE过采样

(一) 生成不平衡数据集

我们使用sklearn的make_classification函数来生成一个不平衡的数据集,然后使用SMOTE算法对少数类进行过采样

from sklearn.datasets import make_classification
from imblearn.over_sampling import SMOTE
from collections import Counter
import pandas as pd# 生成一个不平衡的数据集
X, y = make_classification(n_classes=2, class_sep=2, weights=[0.1, 0.9], n_informative=3, n_redundant=1,  n_features=20, n_clusters_per_class=1, n_samples=1000, random_state=10)
print('原始数据集的类别分布:', Counter(y))

make_classification:这是用于生成分类数据集的函数。

n_classes=2:指定生成的数据集应该有2个类别(二分类问题)。

class_sep=2:指定类别之间的分离程度。值越大,类别之间的分离越明显。

weights=[0.1, 0.9]:指定每个类别的样本权重,或者可以理解为每个类别在总样本中的比例。这里,类别0的样本占总样本的10%,类别1的样本占90%,这表明生成的数据集是不平衡的。

n_informative=3:指定有多少特征是信息性的,即这些特征与目标变量有关联。

n_redundant=1:指定有多少特征是冗余的,即这些特征与信息性特征相关联,但与目标变量关联不大。

n_features=20:指定生成的数据集应该有多少个特征。

n_clusters_per_class=1:指定每个类别是否由一个单独的聚类中心生成。这里设置为1,意味着每个类别由一个聚类中心生成。

n_samples=1000:指定每个类别的样本数量。由于weights参数指定了类别比例,这里的1000是对总样本数的近似值,实际上会根据指定的权重来生成具体的样本数。

random_state=10:指定随机种子,以确保每次生成的数据集都是相同的,便于重现结果。

(二)  将数据集转换为DataFrame,便于展示

df = pd.DataFrame(X)
df['target'] = y

(三) 应用SMOTE算法进行过采样

# 应用SMOTE算法进行过采样
# sampling_strategy = {0: 100, 1: 100} 
smote = SMOTE(random_state=42,sampling_strategy=0.6,k_neighbors=4)
X_resampled, y_resampled = smote.fit_resample(X,y)
sampling_strategy这个参数定义了少数类的采样策略。它可以是一个浮点数或字典。
  • 如果是浮点数,表示最终少数类占多数类的比例,sampling_strategy=0.6意味着最终的少数类样本的数量将是多数类样本数量的0.6倍。
  • 如果是字典,可以针对数据集中的每个类别指定不同的采样策略。如:sampling_strategy = {0: 540, 1: 900} ,就是希望0类样本是540个,1类样本是900个。

k_neighbors这个参数指定了在合成新样本时考虑的最近邻的数量。在SMOTE中,合成样本是基于少数类的现有样本和它们在特征空间中的最近邻之间的差异生成的。k_neighbors=4意味着在合成新样本时,将考虑每个少数类样本的4个最近的邻居。这个值应该是一个整数,且大于1。

# 打印过采样后的类别分布
print('过采样后数据集的类别分布:', Counter(y_resampled))

(四) 可视化原始数据分布

# 可视化原始和过采样后的数据分布
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA# 使用PCA降维以便可视化
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X)
from matplotlib.ticker import FormatStrFormatter
# 绘制原始数据集
plt.rcParams['font.sans-serif']=['SimHei']
plt.figure(figsize=(8, 6),dpi=100)
plt.scatter(X_pca[y == 0, 0], X_pca[y == 0, 1], s=30, edgecolors='k', c='blue', label='Class #0')
plt.scatter(X_pca[y == 1, 0], X_pca[y == 1, 1], s=30, edgecolors='k', c='red', label='Class #1')
# X_pca[y == 0, 0] 表示所有标签为0的样本在PCA降维后的第一个主成分上的坐标。
# X_pca[y == 0, 1] 表示所有标签为0的样本在PCA降维后的第二个主成分上的坐标。
plt.title('原始数据集')
plt.legend()
plt.tight_layout()
# 获取当前坐标轴并设置格式化
ax = plt.gca()
ax.xaxis.set_major_formatter(FormatStrFormatter('%f'))  # 设置x轴格式化为浮点数
ax.yaxis.set_major_formatter(FormatStrFormatter('%f'))  # 设置y轴格式化为浮点数
plt.show()

 (五) 可视化过抽样后的数据分布

X_resampled_pca = pca.transform(X_resampled)
# 绘制过采样后的数据集
plt.figure(figsize=(8, 6),dpi=100)
plt.scatter(X_resampled_pca[y_resampled == 0, 0], X_resampled_pca[y_resampled == 0, 1], s=30, edgecolors='k', c='blue', label='Class #0')
plt.scatter(X_resampled_pca[y_resampled == 1, 0], X_resampled_pca[y_resampled == 1, 1], s=30, edgecolors='k', c='red', label='Class #1')
plt.title('过采样后的数据集')
plt.legend()
plt.tight_layout()
# 获取当前坐标轴并设置格式化
ax = plt.gca()
ax.xaxis.set_major_formatter(FormatStrFormatter('%f'))  # 设置x轴格式化为浮点数
ax.yaxis.set_major_formatter(FormatStrFormatter('%f'))  # 设置y轴格式化为浮点数
plt.show()

(六)补充:X_pca 和y是怎么联系的,当时X_pca = pca.fit_transform(X) 其中也没有用到y呀  

X_pca 和 `y` 的联系并不体现在PCA的计算过程中,而是在于后续的数据分析和可视化过程中。

当执行 `X_pca = pca.fit_transform(X)` 时,PCA算法仅作用于输入的特征数据 `X`,目的是找出数据中的主要变化模式(即主成分),并将数据投影到这些主成分上以实现降维。这个过程是完全独立于标签 `y` 的,因为PCA是一种无监督的降维技术,它不考虑数据的类别标签。

尽管PCA的计算与 `y` 无关,但 `X_pca` 和 `y` 的联系体现在以下两个方面:

1.  样本对应:`X_pca` 和 `y` 是按照样本顺序对应的。即使PCA计算时没有用到 `y`,但 `X_pca` 中的每一行仍然代表 `X` 中相应行的降维表示,而 `y` 中的每一个标签仍然对应于 `X` 中相应行的类别。这种对应关系是数据分析的基础,因为我们需要知道每个降维后的样本点属于哪个类别。
    
2.  数据分析与可视化:在PCA计算完成后,我们通常希望了解不同类别在降维空间中的分布情况。为了实现这一点,我们需要将 `y` 中的类别标签与 `X_pca` 中的样本点结合起来。例如,在绘制散点图时,我们可以根据 `y` 中的值将样本点分类,并用不同的颜色或形状来表示不同的类别。这样,我们就可以直观地看到哪些样本点属于同一类别,以及不同类别在降维空间中的相对位置和重叠程度。
    

简而言之,尽管PCA的计算独立于类别标签 `y`,但在进行数据解释和可视化时,`y` 提供了必要的上下文,使我们能够将降维后的样本点与它们各自的类别关联起来,从而进行更深入的数据分析。

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

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

相关文章

【Centos7】CentOS 7下的PyTorch安装策略:高效实践指南

【Centos7】CentOS 7下的PyTorch安装策略:高效实践指南 大家好 我是寸铁👊 总结了一篇【Centos7】CentOS 7下的PyTorch安装策略:高效实践指南✨ 喜欢的小伙伴可以点点关注 💝 前言 由于需要跑深度学习,要用到pytorch&a…

重塑楼宇管理:智慧管控可视化开启高效新篇章

借助图扑智慧楼宇管控可视化技术,实现实时监控与智能化管理,快速响应潜在问题,确保楼宇安全、节能和高效运行。

Git之解决重复输入用户名和密码(三十九)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏:多媒…

快速入门Linux及使用VSCode远程连接Linux服务器

在当前的技术环境中,Linux操作系统因其强大的功能和灵活性而广受欢迎。无论你是开发人员、系统管理员还是技术爱好者,学习Linux都是提升技术技能的重要一步。本文将介绍如何快速入门Linux,并使用Visual Studio Code(VSCode&#x…

时光正好保剑锋的抱治百病与成年人的世界

《时光正好》:保剑锋的“抱治百病”与成年人的世界在繁忙的都市里,每个角落上演着各自的人生戏码。而在这些戏码中,由保剑锋主演的《时光正好》无疑成为了近期引人注目的焦点。这部电视剧以其真实而深刻的剧情,让我们看到了成年人…

SpringBoot+Vue实现前后端分离基本的环境搭建

目录 一、Vue项目的搭建 (1)基于vite创建vue项目 (2)引入elementplus (3)启动后端服务,并测试 二、SpringBoot项目的搭建 (1)通过idea创建SpringBoot项目 &#x…

有效的括号(oj题)

一、题目链接 https://leetcode.cn/problems/valid-parentheses/submissions/538110206 二、题目思路 利用栈的性质,后进先出 1.依次读取字符串,判断是否为左括号,如果是,就将其入栈。 2.如果读取的不是左括号,就说…

【网络教程】Iptables官方教程-学习笔记7-简单理解IPTABLES规则的作用流程

前面学习了IPTABLES的所有功能介绍后,一个Linux设备里的IPTABLES规则集是如何运行的,这里简单做个介绍。 在Linux设备里输入"iptables -nvl",得到该设备的所有防火墙规则,得到的结果中可以看到这个设备防火墙里所有的链以及链里的…

Git从入门到放弃

由于我的Git学的不太好,所以为了能够将以后我的学习笔记能够整理的更好,我先要系统的学习一下git,文章由此产生。 文章笔记源自尚硅谷Git入门到精通全套教程视频内容 1 进入官网 学习新技术的第一步需要熟悉官网,Git也不例外。ht…

【Python报错】已解决AttributeError: ‘Series’ object has no attribute ‘columns’

成功解决“AttributeError: ‘Series’ object has no attribute ‘columns’”错误的全面指南 一、引言 在Python的数据处理和分析中,Pandas库是一个不可或缺的工具。然而,在使用Pandas时,可能会遇到各种错误,其中之一就是“Att…

HTML静态网页成品作业(HTML+CSS)—— 24节气立夏介绍网页(1个页面)

🎉不定期分享源码,关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 🏷️本套采用HTMLCSS,未使用Javacsript代码,共有1个页面。 二、作品演示 三、代…

使用Python创建Word文档

使用Python创建Word文档 安装python-docx库创建Word文档代码效果 在这篇文章中,我们将介绍如何使用 Python创建一个Word文档。首先,我们需要安装python-docx库,然后通过一段简单的代码示例展示如何创建和编辑Word文档。 安装python-docx库 …

RPA影刀 | 变量的使用

1.什么是变量 2.变量的作用 作用1:方便后续流程调用 这里在后续流程“点击元素”中,就可以选中这个变量 作用2:区分相同属性的变量 如果要打开两个网页,总不能都叫web_page吧。 所以这里一个叫百度web_page,一个叫…

C++期末复习总结(2)

目录 1.运算符重载 2.四种运算符重载 (1)关系运算符的重载 (2) 左移运算符的重载 (3)下标运算符的重载 (4)赋值运算符的重载 3.继承的方式 4.继承的对象模型 5.基类的构造 6…

易飞销货单出货时审核库存检查

公司接到一客户因品种多而数量少,单一出货计划行比较多,而只上了生产ERP易飞,审核时经常会出现倒催货,提前做销售单,行数有时超30行以上,审核跳窗报错时也不方便查找,特写一外挂程序&#xff0c…

How to: Build a Custom End-User Skin Selector

This section explains how to populate a ComboBoxEdit control with DevExpress skin items. 本节介绍如何使用DevExpress皮肤项填充ComboBoxEdit控件。 To populate a combo box editor, iterate through the SkinManager.Skins collection, which returns all currently a…

【c语言】自定义类型----结构体

结构体是c语言的一种自定义类型,自定义类型对于开发者及其重要的类型,它可以随意由开发者进行谱写功能,而今天的结构体可以用来表示一种变量的单个或多种具体属性,再编写代码时有着不可替代的作用!!&#x…

一个简单的消息队列

目录 原理 实现代码 示例 原理 消息队列是一个先进先出栈,每次都处理第一项,处理完了过后会删除这个消息,这是一个简单的消息队列图: 实现代码 首先消息队列需要一个队列,我们用Python里的列表: self.…

常见的api: BigInteger

一.获取一个大的随机整数 1.代码: BigInteger bd1 new BigInteger(4, new Random());System.out.println(bd1); 2.打印的结果:2 3.注释获取的是0-16之间的随机整数 二.获取一个指定的大的数 1.代码: BigInteger bd2 new BigInteger("100");System.o…

人工智能--教育领域的运用

文章目录 🐋引言 🐋个性化学习 🦈体现: 🦈技术解析: 🐋智能辅导与虚拟助手 🦈体现: 🦈技术解析: 🐋自动评分与评估 &#x1f…