【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,一经查实,立即删除!

相关文章

JavaScript html css 字符串对象

字符串对象 字符串所有的方法&#xff0c;都不会修改字符串本身&#xff08;字符串是不可变的&#xff09;&#xff0c;操作完成会返回一个新的字符串。 length属性 作用&#xff1a; 获取字符串长度 示例&#xff1a; <span style"background-color:#f8f8f8&qu…

阿里云ECS服务器部署javaweb项目实操

在阿里云ECS实例上部署Java Web项目涉及几个主要步骤&#xff1a;创建和配置ECS实例、安装必要的软件&#xff08;JDK、Web服务器、数据库等&#xff09;、部署Java Web应用程序以及配置防火墙和安全组。以下是详细的步骤&#xff1a; 步骤1&#xff1a;创建ECS实例 登录阿里云…

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

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

java的序列化与反序列化

一、定义 Java序列化和反序列化&#xff1a;序列化就是指把Java对象转换为字节序列的过程。&#xff08;例如将一个类转化为json类型&#xff09;反序列化就是指把字节序列恢复为Java对象的过程。 在Java实际运用中&#xff0c;,许多方面应用序列化反序列化——持久化、通信、…

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

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

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

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

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

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

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

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

深入了解Linux中的db_dump185命令

深入了解Linux中的db_dump185命令 在Linux系统中&#xff0c;db_dump185可能不是一个广为人知的命令&#xff0c;但它对于某些特定的数据库或文件系统任务来说却是一个非常有价值的工具。特别是当你与旧版的Berkeley DB数据库或类似的存储机制打交道时&#xff0c;db_dump185可…

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

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

有效的括号(oj题)

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

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

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

Git从入门到放弃

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

【区分vue2和vue3下的element UI ¶Upload 上传组件,分别详细介绍属性,事件,方法如何使用,并举例】

在 Vue 2 中&#xff0c;我们通常使用 Element UI 的 el-upload 组件来实现文件上传功能。然而&#xff0c;在 Vue 3 中&#xff0c;由于 Element UI 没有官方支持 Vue 3 的版本&#xff0c;我们通常会使用 Element Plus&#xff08;Element UI 的 Vue 3 版本&#xff09;的 el…

海豚调度器调用api接口启动工作流(亲试可用)

一、前言 在大数据时代,工作流调度器成为了数据管道和ETL任务中不可或缺的工具。DolphinScheduler作为一款强大的工作流调度器,支持多种任务类型和工作流的可视化管理。除了通过Web界面操作外,DolphinScheduler也提供了API接口,使得第三方系统集成和自动化脚本调用成为可能…

理论学习-自动控制

自动控制 前馈控制简介表现形式前馈 - 反馈 结合使用 前馈控制 简介 前馈控制 什么&#xff1f;作用 &#xff1f;条件&#xff1f; 没有表达形式&#xff08;具体的&#xff09;&#xff0c;控制方法。提高响应速度&#xff0c;减小误差&#xff0c;增加带宽而不改变稳定性…

Langchain的向量存储 - Document与简单字符串列表的区别

文章目录 前言一、 使用简单字符串列表1. 示例2. 优点3. 缺点 二、 使用 Document 类1. 示例2. 优点3. 缺点 三、 综合比较四、 示例对比1&#xff1a;简单字符串列表2&#xff1a;使用 Document 类 总结 前言 在 LangChain 中&#xff0c;使用简单字符串列表&#xff08;如 t…

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

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

【C++】、【Redis】、【人工智能】与【大数据】的深度整合

C++、Redis、人工智能和大数据的深度整合涉及多个方面,包括数据存储、处理、优化以及在不同技术栈之间的交互。以下是对这四个领域深度整合的详细分析: 一、C++与Redis的整合 数据存储与访问: Redis作为一个高性能的Key-Value数据库,非常适合作为C++应用的缓存层。通过hir…

k8s 对外发布(ingress)

在k8s中&#xff0c;service的作用体现在两个方面&#xff0c;对集群内部&#xff0c;它不断跟踪pod的变化&#xff0c;更新endpoint中对应pod的对象&#xff0c;提供了ip不断变化的pod的服务发现机制&#xff1b; 对集群外部&#xff0c;他类似负载均衡器&#xff0c;可以在集…