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

SMOTE算法深度解析及代码实现

SMOTE算法介绍

 SMOTE算法是较为常用的数据增广算法,其核心思路是在少数类别样本内部进行数据合成,更具体的说,其后隐藏的猜想是假定样本 x 0 , x 1 , . . , x N x_0,x_1,..,x_N x0,x1,..,xN都为同一类别,那么他们的线性组合 x 0 + a 1 ∗ x 1 + . . . + a N ∗ x N x_0+a_1*x_1+...+a_N*x_N x0+a1x1+...+aNxN也应该和它们属于同一类别。 给出SMOTE原论文中的算法伪代码如下:
在这里插入图片描述
其基本思路和刚刚所介绍的一致,但是引入了基于KNN检索的数据合成方案。让我们来一步步拆解。

SMOTE函数

 函数SMOTE(T,N,K)三个参数含义为:
N:int(N/100)生成数据的倍数,为100的倍数。距离而言,如果设置N=200,那么少数类别样本的数目就会增加2倍,变为原来的3倍;
T:少数类别样本的数目
K:用于合成的最近邻样本的数目

 接下来我们分析一下SMOTE的运行逻辑:

  1. 首先会判断要增广的倍数是否大于1(即N是否大于100),基于此计算出增广倍数N=N/100
  2. 遍历每个少数类别样本 x i , i ∈ 1 , . . , T x_i,i\in {1,..,T} xi,i1,..,T,对其进行增广,增广步骤如下:
    1. 计算出 x i x_i xi同类样本(即少数类别样本) 的k个最近邻样本,记录这k个样本在样本集中索引,构成nnarray
    2. 调用Populate()函数进行增广。

Populate函数

 函数Populate(N,i,nnarray)的三个参数的含义为:
N: 增广倍数
i: 要进行增广的样本的索引
nnarray:样本 x i x_i xi的最近邻样本的索引集合

 Popluate函数会按照我们之前提过的SMOTE核心思路–同类样本的线性组合来进行样本的生成。具体而言,总共会执行N次生成过程,每一次生成过程中,我们都会从其最近邻样本中挑选一个,然后对特征进行线性组合作为合成样本。值得注意的是,在合成新样本过程中,不同特征的线性系数都是不同的,特征向量中含numattrs个特征就会包含numattrs个合成系数gap。

小结

 SMOTE函数总结起来就是对每个少数类别样本都寻找其同类最相似的K个样本,然后进行N次样本合成,每次合成过程中都会随机从K个样本中采样一个,然后用采样的近邻样本和当前样本的特征进行线性组合得到新样本,最终得到T*K个增广样本。

代码实现

 实际应用SMOTE算法时,调用imbalanced-learn中的库即可实现,如果想要手动实现的话,可以参见笔者给出的实现方案如下:

def smote(feature,labels,K):'''这份代码实现的是最为简单的smote算法,也就是核心是同类样本特征的线性组合,:param feature: 特征matrix:param labels:  标签向量:param K: SMOTE算法中样本考量的近邻个数:return: new_features-生成的样本特征;new_labels-生成样本的标签'''from sklearn.neighbors import NearestNeighborsfrom collections import Countervalue_cnts=dict(Counter(labels))max_sampels=max(value_cnts.values())new_features=[]new_labels=[]for label,cnt in value_cnts.items():if cnt<=1:continue# 提取当前label对应的featurecur_feats=feature[np.where(labels==label)]if(cur_feats.shape[0]>K):Neighbors = NearestNeighbors(n_neighbors=K)Neighbors.fit(cur_feats)neighbor_index=Neighbors.kneighbors()[1]else:Neighbors = NearestNeighbors(n_neighbors=cur_feats.shape[0]-1)Neighbors.fit(cur_feats)neighbor_index=Neighbors.kneighbors()[1]# 采样max_samples-cnt个样本来进行增广base_sampe_idxs=np.random.choice(np.arange(cur_feats.shape[0]),max_sampels-cnt)for idx in base_sampe_idxs:base_sample=cur_feats[idx]# 随机采样一个邻居random_neighbor_idx=np.random.choice(neighbor_index[idx])neighbor=cur_feats[random_neighbor_idx]coff=np.random.rand(feature.shape[1]) # n_dim个位于0-1间的特征系数dif=base_sample-neighbornew_features.append((base_sample+coff*dif).reshape(1,-1))new_labels.append(label)new_features=np.vstack(new_features)new_labels=np.array(new_labels)return new_features,new_labels

需要注意的是,笔者实现的方案和原始SMOTE算法并不完全一致。具体而言,这份实现中舍弃了对增广倍数的控制,改为了强制要求所有类别样本数目相同,逐类别的进行样本合成,每次合成过程中都随机选取一个当前类的样本,然后再基于SMOTE的思路在类别内采样、线性合成。

参考

探索SMOTE算法


http://www.mrgr.cn/news/69672.html

相关文章:

  • RabbitMQ集群搭建
  • 创新培养:汽车零部件图像分割
  • 雷池waf安装并部署防护站点
  • LeetCode【0028】找出字符串中第一个匹配项的下标
  • 小面馆叫号取餐流程 佳易王面馆米线店点餐叫号管理系统操作教程
  • 解决msvcr100.dll丢失的方法,5个实测可靠的解决方法
  • 「QT」几何数据类 之 QLine 整型直线类
  • UVC 输出视频格式修改和windows下数据分析
  • 【Linux系统编程】第四十四弹---从TID到线程封装:全面掌握线程管理的核心技巧
  • 树莓派(Raspberry Pi)产品介绍-硬件篇
  • ABC 379 D - Home Garden(队列+前缀和)
  • 「QT」几何数据类 之 QPointF 浮点型点类
  • 免费送源码:Java+springboott+MySQL+Tomcat 游戏攻略网站设计与实现 计算机毕业设计原创定制
  • 基于springboot的公益服务平台的设计与实现
  • 【论文复现】MSA+抑郁症模型总结(三)
  • 国际刑警组织在全球打击网络犯罪行动中捣毁了22000多台恶意服务器!思科为工业无线系统中的关键URWB漏洞发布补丁 | 安全周报1110
  • 人脸识别率低怎么办?如何通过代码提高准确率?
  • 第18篇 :深入剖析systemverilog中 randomize 失败案例启示录(二)
  • JavaAPI(2)
  • 关于git使用的图文教程(包括基本使用,处理冲突问题等等)超详细
  • 在.NET中正确捕获C++程序的cout输出
  • Qt_day4_Qt_UI设计
  • 互联网基础思维
  • 小白速成教程:私有化大模型+知识库
  • 深入解析Python的上下文管理器与资源管理:实现自定义的with语句
  • 简记Vue3(五)—— Pinia