类别不平衡

news2024/11/23 12:16:01

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

目录

  • 一、介绍
    • 1、过采样
    • 2、欠采样
  • 二、过采样
    • 1、SMOTE(常用)
      • 1、算法流程
      • 2、算法实现
      • 3、参数介绍
    • 2、ADASYN(不常用)
      • 1、算法流程:
      • 2、代码实现
  • 三、欠采样
    • 1、Random under-sampling
    • 2、Cleaning under-sampling
      • 1、TomekLinks
      • 2、Edited nearest neighbours
  • 四、联合采样
    • 1、SMOTE叠加TomekLink
    • 2、SMOTE叠加ENN
  • 五、实例
    • 1、加载数据
    • 2、实现过采样
    • 3、问题
    • 4、SMOTENC

一、介绍

研究算法时均认为数据是对称分布的,即正负样本数据相当。现实数据中少数类占比20%,甚至10%都不到,容易对模型算法产生影响。

1、过采样

过采样会随机复制少数样本以增大它们的规模。
在这里插入图片描述

2、欠采样

通过抽样方法,将多数样本变少。解决二分类问题时,可以使用随机抽样方法降低样本数量;解决多分类问题时,使用分层抽样方法。
在这里插入图片描述

二、过采样

1、SMOTE(常用)

  • 错误说法
    先设置超参数,如4,黑色样本为少数类,每个黑色样本中找到黑色附近的4个黑色样本,在该4个样本的连线中间取一个随机差值,记为新增样本。
    在这里插入图片描述
  • 正确说法
    先设置超参数,如4,黑色样本为少数类,每个黑色样本中找到黑色附近的4个黑色样本,对这四个样本做有放回的随机抽样,然后找到黑色样本与随机抽中样本,并随机取差值,生成一个样本。

1、算法流程

1、计算采样比例N,(默认N= 多数样本量/少数样本量)
2、 对每一个少数类样本 x i x_i xi,从其k近邻个少数类样本中有放回地随机抽样N-1个,记为 x i k x_{ik} xik
3、分别与原样本 x i x_i xi按照如下的公式生成新的插值样本
x n e w = x i + r a n d ( 0 , 1 ) ∗ ( x i − x i k ) x_{new}=x_i+rand(0,1)*(x_i-x_{ik}) xnew=xi+rand(0,1)(xixik)

4、重复进行,直到满足停止条件。

2、算法实现

  • 创建不平衡数据集
    在这里插入图片描述
  • 实现SMOTE
from imblearn.over_sampling import SMOTE

smote = SMOTE(random_state = 42)
X_sm, Y_sm = smote.fit_resample(X, y)

# 查看采样后的比例
pd.DataFrame(Y_sm).value_counts()
# 画图看过采样后的数据集
plt.scatter(X_sm[:, 0], X_sm[:, 1], c = Y_sm, cmap = "rainbow",s = 10)

在这里插入图片描述

  • 调整采样比例
smote = SMOTE(sampling_strategy = 0.5, random_state = 42)
X_sm, Y_sm = smote.fit_resample(X, y)

在这里插入图片描述

3、参数介绍

sampling_strategy: default= "auto" 过采样策略,可以为0.5,即调整样本比例为0.5倍;minority:只过采样类别比例最少的样本,多分类时用;not_minority出了最少、最多的样本,其他类别过采样,过采样到和最多类别的样本数量一样多;not_majority:除了最多的样本,其他都进行过采样;all:所有都过采样;也可以传入字典控制过采样的key(类别)、value(数量).
k_neighbors: int = 5, k值

优点:简单清晰,用差值做出的结果,比较随机;缺点:如果一个分类器在原始的少数类数据集上做出了一个错误的负面错误,那么数据复制几次后,分类器就会在新的数据集上出现多次错误。由于生成的是虚拟数据,在实际中,不容易解释。

2、ADASYN(不常用)

1、算法流程:

1、对于每一个少数类样本 x i x_i xi,选择其k个近邻的样本 x i k x_{ik} xik。注意这里的k个近邻样本的选择不区分多数与少数类。
2、计算这K个近邻样本中多数类的比例 r i r_i ri
3、标准化 r i r_i ri得到采样比例,公式为 r i ^ = r i / ∑ i = 1 m r i \hat{r_i}=r_i/\sum_{i=1}^m{r_i} ri^=ri/i=1mri。标准化后使 ∑ i r i ^ = 1 \sum_i\hat{r_i}=1 iri^=1
4、 对每个少数类样本,依照采样比例 r i ^ \hat{r_i} ri^使用SMOTE方法得到插值样本。可以发现,ADASYN方法更倾向于在多数类样本的附近生成新的插值样本。

2、代码实现

from imblearn.over_sampling import ADASYN

adasyn = ADASYN(random_state = 42)
X_ada, Y_ada = adasyn.fit_resample(X, y)

pd.DataFrame(Y_ada).value_counts()
plt.scatter(X_ada[:, 0], X_ada[:, 1], c = Y_ada, cmap = "rainbow",s = 10)

在这里插入图片描述

三、欠采样

1、Random under-sampling

常用的是Random under-sampling,即随机删除多数类样本。这是唯一一种可以精确设置欠采样样本数量的常用欠采样算法,因此冠以Controlled名号,即Controlled under-sampling(控制过采样)。

from imblearn.under_sampling import RandomUnderSampler

rus= RandomUnderSampler(sampling_strategy= 0.5, random_state= 42)   # sampling_strategy=1,控制采样比例
X_rus, Y_rus = rus.fit_resample(X, y)

# 查看采样后的比例
pd.DataFrame(Y_rus).value_counts()
# 画图看过采样后的数据集
plt.scatter(X_rus[:, 0], X_rus[:, 1], c = Y_rus, cmap = "rainbow",s = 10)

在这里插入图片描述

2、Cleaning under-sampling

Cleaning类的欠采样算法无法精确控制欠采样样本的数量

1、TomekLinks

  • 算法过程

当多数类的某样本y和少数类的某样本x,与另外任意样本z,之间的距离d()存在以下关系
d ( x , y ) < d ( x , z ) a n d d ( x , y ) < d ( y , z ) d(x,y)<d(x,z)\qquad and\qquad d(x,y)<d(y,z) d(x,y)<d(x,z)andd(x,y)<d(y,z)
则称x与y之间存在Tomek Link,此时算法可删除多数类样本y以实现欠采样。
可以发现,TomekLinks算法不适合对有清晰边界的两类样本做欠采样。

  • 代码实现
from imblearn.under_sampling import TomekLinks

tl= TomekLinks()
X_tl, Y_tl= tl.fit_resample(X, y)

# 查看采样后的比例
pd.DataFrame(Y_tl).value_counts()

# 画图看过采样后的数据集
plt.scatter(X_tl[:, 0], X_tl[:, 1], c = Y_tl, cmap = "rainbow",s = 10)

在这里插入图片描述

2、Edited nearest neighbours

  • 算法过程
    应用最近邻算法来编辑(edit)数据集, 找出那些与邻居不太友好的样本然后移除。
    具体来说,对每一个多数类样本 x i x_i xi,若其k近邻的全部/大多数样本是多数类,则该多数类样本 x i x_i xi会被保留,否则会被移除。
  • 代码实现
from imblearn.under_sampling import EditedNearestNeighbours

enn= EditedNearestNeighbours(n_neighbors= 42)  # 改变n_neighbors=3 参数以观察欠采样结果
X_enn, Y_enn= enn.fit_resample(X, y)

# 查看采样后的比例
pd.DataFrame(Y_enn).value_counts()

# 画图看过采样后的数据集
plt.scatter(X_enn[:, 0], X_enn[:, 1], c = Y_enn, cmap = "rainbow",s = 10)

在这里插入图片描述

四、联合采样

联合采样(Combination sampling)如果多数类样本有离群值,SMOTE等过采样方法容易在多数类样本中间错误地插入少数类插值,导致类别重叠。这些问题插值可以通过联合使用欠采样方法来解决。 这里我们分别将Tomeks link和Edited nearest-neighbours联接在SMOTE之后,来清除过采样生成的问题插值,以得到一个尽量干净的数据空间。
数据处理方法一直是先过采样再欠采样,顺序不可反。

1、SMOTE叠加TomekLink

代码实现:

from imblearn.combine import SMOTETomek

smote_tomek = SMOTETomek(random_state= 42)
X_smote_tomek, Y_smote_tomek= smote_tomek.fit_resample(X, y)

# 查看采样后的比例
pd.DataFrame(Y_smote_tomek).value_counts()

# 画图看过采样后的数据集
plt.scatter(X_smote_tomek[:, 0], X_smote_tomek[:, 1], c = Y_smote_tomek, cmap = "rainbow",s = 10)

在这里插入图片描述

2、SMOTE叠加ENN

代码实现

from imblearn.combine import SMOTEENN

smote_enn = SMOTEENN(random_state= 42)
X_smote_enn, Y_smote_enn= smote_enn.fit_resample(X, y)

# 查看采样后的比例
pd.DataFrame(Y_smote_enn).value_counts()

# 画图看过采样后的数据集
plt.scatter(X_smote_enn[:, 0], X_smote_enn[:, 1], c = Y_smote_enn, cmap = "rainbow",s = 10)

在这里插入图片描述

五、实例

1、加载数据

df=pd.read_csv('保险数据_全部数据.csv')
df1= df.dropna()
labels= df1.pop("resp_flag")

# 数据类型区分
cat_cols= df1.select_dtypes(include=["object"])   # 分类型变量
num_cols= df1.select_dtypes(include=["int", "float"])   # 数值型变量

# 数据编码
from sklearn.preprocessing import OrdinalEncoder
cat_encode= OrdinalEncoder()
cat_trans= cat_encode.fit_transform(cat_cols)
df_cat= pd.DataFrame(cat_trans, columns= cat_cols.columns)

# 数据标准化
from sklearn.preprocessing import StandardScaler
num_std= StandardScaler()
num_trans= num_std.fit_transform(num_cols)
df_num= pd.DataFrame(num_trans, columns= num_cols.columns)

# 数据合并
data= pd.concat([df_cat, df_num], axis= 1)

2、实现过采样

实现过采样,并查看原数据比例

# SMOTE
from imblearn.over_sampling import SMOTE

smote = SMOTE(random_state = 42)
X_sm, Y_sm = smote.fit_resample(data, labels)

# 查看采样后的比例
pd.DataFrame(Y_sm).value_counts()

在这里插入图片描述

3、问题

在这里插入图片描述
第一列性别分类数据,0、1之外出现小数,这是因为SMOTE做差值导致。如果模型做预测,不需要可解释性,则可以继续使用该方法;如果需要满足可解释性,数据中存在连续型数据时无问题,如果是分类数据,则出现的新增样本无法解释。

4、SMOTENC

SMOTENC会自动区分数值型、分类型数据,避免了SMOTE数据无法解释的问题。

from imblearn.over_sampling import SMOTENC
smote_nc = SMOTENC(categorical_features= cat_cols.columns) # categorical_features参数传入分类型数据集的列名
X_resampled, y_resampled = smote_nc.fit_resample(data.values, labels)

新问题:大部分电脑运行这部分代码会保错,原因是Python版本间更新出现重大变动时,第三方库未同时更新导致。

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

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

相关文章

车票信息的请求与显示

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 1 发送与分析车票信息的查询请求 得到了获取车票信息的网络请求地址&#xff0c;然后又分析出请求地址的必要参数以及车站名称转换的文件&#xff…

程序猿大战Python——函数——嵌套调用与变量作用域

嵌套调用及执行流程 目标&#xff1a;了解函数的嵌套调用。 函数的嵌套调用指的是&#xff1a;在一个函数中&#xff0c;调用了另一个函数。 嵌套调用语法&#xff1a; def 函数1():代码... ​ def 函数2():代码# 调用函数1函数1()... 说明&#xff1a; 在函数2中&#xff0c…

8个宝藏APP,个个都牛逼哈拉!

AI视频生成&#xff1a;小说文案智能分镜智能识别角色和场景批量Ai绘图自动配音添加音乐一键合成视频https://aitools.jurilu.com/ 目前win7已经逐渐淡出人们的视野&#xff0c;大部分人都开始使用win10&#xff0c;在日常工作和使用中&#xff0c;创客们下载神奇的软件能大幅提…

怎样快速清理电脑里的所有软件 怎么删除干净电脑软件

苹果电脑内的软件来源主要有两个&#xff0c;一是系统预装&#xff0c;二是用户自行下载。但并不是所有应用程序都是高频使用状态&#xff0c;甚至好多是从未打开过的“屏幕装饰”。小编今日独家攻略&#xff0c;内存告急如何快速清理电脑里的所有软件&#xff0c;怎么删除干净…

线程池ThreadPoolExecutor使用指南

线程池ThreadPoolExecutor使用指南 &#x1f9d0;使用线程池的好处是什么&#xff1f; 统一管理&#xff0c;减少资源获取创建的开销&#xff0c;提高利用率。 &#x1f527;线程池的参数 ​ThreadPoolExecutor​ 3 个最重要的参数&#xff1a; ​corePoolSize​ : 任务队列…

问:IP写作如何商业化?

这个问题也是很多朋友&#xff0c;或者新手小白问的最多的问题&#xff0c; 毕竟我们做副业都是为了挣钱嘛&#xff0c; 那么&#xff0c;回到问题&#xff0c;IP写作如何商业化&#xff1f; 这个问题其实对于我现在要日更的目标来说为时尚早&#xff0c;不过也可以先了解一下。…

Javaweb登录校验

登录校验 JWT令牌的相关操作需要添加相关依赖 <dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version> </dependency>一、摘要 场景&#xff1a;当我们想要访问一个网站时&am…

如何用AI提高产品经理的工作效率

最近我跟几个产品经理聊天&#xff0c;发现有些人居然还没有使用过ChatGPT、MidJourney、NotionAI 等AI工具。 产品经理有个重要的素质是好奇心&#xff0c;好奇心能够帮助产品经理发现新机会、了解用户需求、学习新知识和探索竞争对手&#xff0c;从而更好地完成产品开发和管…

mediamtx流媒体服务器测试

MediaMTX简介 在web页面中直接播放rtsp视频流&#xff0c;重点推荐&#xff1a;mediamtx&#xff0c;不仅仅是rtsp-CSDN博客 mediamtx github MediaMTX(以前的rtsp-simple-server)是一个现成的和零依赖的实时媒体服务器和媒体代理&#xff0c;允许发布&#xff0c;读取&…

android13 应用冷启动

1 概述 launcher 通过binder到systemserver中atms中发送startActivity请求 startProcess向zygote发送启动新进程请求 zygote收到请求&#xff0c;fork新进程并调用ActivityThread的main初始化 新进程启动&#xff0c;发送attachApplication给ams&#xff0c;告诉他新进程启动…

C++ 44 之 指针运算符的重载

#include <iostream> #include <string> using namespace std;class Students04{ public:int m_age;Students04(int age){this->m_age age;}void showAge(){cout << "年龄是&#xff1a; " << this->m_age << endl;}~Students0…

155. 最小栈 力扣 python 空间换时间 o(1) 腾讯面试题

设计一个支持 push &#xff0c;pop &#xff0c;top 操作&#xff0c;并能在常数时间内检索到最小元素的栈。 实现 MinStack 类: MinStack() 初始化堆栈对象。void push(int val) 将元素val推入堆栈。void pop() 删除堆栈顶部的元素。int top() 获取堆栈顶部的元素。int get…

RestTemplate远程请求的艺术

1 简说 编程是一门艺术,追求优雅的代码就像追求优美的音乐。 很多有多年工作经验的开发者,在使用RestTemplate之前常常使用HttpClient,然而接触了RestTemplate之后,却愿意放弃多年相处的“老朋友”,转向RestTemplate。那么一定是RestTemplate有它的魅力,有它的艺术风范。…

CCAA质量管理【学习笔记】​​ 备考知识点笔记(三)质量管理方法与常见工具

第二部分 质量管理领域专业知识 《质量管理体系基础考试大纲》中规定的考试内容&#xff1a; 3.2 质量管理领域专业知识 a) 了解质量管理方法与工具相关知识&#xff0c;包括&#xff1a; 质量管理方法与工具的内涵与作用、发展历程与应用现状、分类与选择常用的应用软件…

使用 Vue CLI 脚手架生成 Vue 项目

最近我参与了一个前端Vue2的项目。尽管之前也有过参与Vue2项目的经验&#xff0c;但对一些前端Web技术并不十分熟悉。这次在项目中遇到了很多问题&#xff0c;所以我决定借此机会深入学习Vue相关的技术栈。然而&#xff0c;直接开始深入钻研这些技术可能会显得枯燥&#xff0c;…

随笔-来了,安了

依照领导定的规矩&#xff0c;周五又去了分公司&#xff0c;赋能一线去了。到了地方就是开会->现场解决问题->干饭->开会过需求、提供解决方案&#xff0c;充实得厉害。强度也不小&#xff0c;中午干的一大碗饭&#xff0c;到五点就饿了。 六点带着分公司催着上线的需…

jupyter notebook中使用不同的anaconda环境及常用conda命令

conda命令 在jupyter notebook中使用不同的anaconda环境其他常用conda命令 在jupyter notebook中使用不同的anaconda环境 创建环境 myenvname 需替换为自己的环境名称 conda create --name myenvname python3.7激活环境 conda activate myenvname 在该环境中安装Jupyter N…

MongoDB~事务了解;可调一致性模型功能与因果一致性模型功能分析

背景 MongoDB 从 3.0版本引入 WiredTiger 存储引擎之后开始支持事务&#xff0c;MongoDB 3.6之前的版本只能支持单文档的事务&#xff0c;从 MongoDB 4.0版本开始支持复制集部署模式下的事务&#xff0c;从 MongoDB 4.2版本开始支持分片集群中的事务。 根据官方文档介绍&…

C++11 move左值转化为右值

单纯的左值只能用左值引用和右值只能用右值引用有些局限&#xff0c;在一些情况下&#xff0c;我们也需要对左值去调用右值引用&#xff0c;从而实现将左值里的内容转移到右值中 标准定义&#xff1a; 功能就是将一个左值强制转化为右值&#xff0c;然后实现移动语义 注意&…

IP地址、子网掩码、网段、网关

前面相同就是在同一个网段 如果子网掩码和网络号相与的结果是一样的&#xff0c;那么他们就在同一个子网 IP地址、子网掩码、网络号、主机号、网络地址、主机地址以及ip段/数字-如192.168.0.1/24是什么意思?_掩码248可以用几个ip-CSDN博客