摘要

SMOTE是一种综合采样人工合成数据算法,用于解决数据类别不平衡问题(Imbalanced class problem),以Over-sampling少数类和Under-sampling多数类结合的方式来合成数据。本文将以Nitesh V. Chawla(2002)的论文为蓝本,阐述SMOTE的核心思想以及实现其朴素算法,在传统分类器(贝叶斯和决策树)上进行对比算法性能并且讨论其算法改进的途径。

1. 引言

类别不平衡是一种在分类器模型训练过程中常见的问题之一,如通过大量胸透图片来学习判断一个人是否有癌症,又如在网络流日志中学习检测可能是攻击行为的数据模式,这一类的任务中都是正常的类多于异常(诊断属于癌症,属于攻击行为)的类,在类别不平衡数据下训练出来的分类器要非常的小心,即使该分类器拥有很高的精度,因为它很可能会习得大部分的都是正常的,而我们可能需要的是它能够最大程度的识别异常行为,哪怕精度低于前者。

为了解决这一问题,业内已经有以下5种公认的方法去扩充数据集[1],以至于类别均匀:

  1. 随机的增大少数类的样本数量。
  2. 随机的增大特定少数类样本的数量。
  3. 随机的减少多数类样本的数量。
  4. 随机的减少特定多数类样本的数量。
  5. 修改代价函数,使得少数类出错的代价更高。

本文要介绍的SMOTE算法就是一种综合1,3方法的改进方式,它以每个样本点的k个最近邻样本点为依据,随机的选择N个邻近点进行差值乘上一个[0,1]范围的阈值,从而达到合成数据的目的。这种算法的核心是:特征空间上邻近的点其特征都是相似的。它并不是在数据空间上进行采样,而是在特征空间中进行采样,所以它的准确率会高于传统的采样方式。这也是为什么到目前为止SMOTE以及其派生的算法仍然是较为主流的采样技术的原因。

Figure 1

在Figure 1中,假设数据点A在特征空间上有4个邻近点,若N为2,则SMOTE会随机选择其中2个邻近点B,C,分别计算A->B, A->C的距离,如图中绿线和红线所示,在绿线或红线上的所有采样点都是合理的,如点A1。为了确保数据点尽可能的多样(不重叠),故乘上一个[0, 1]之间的随机因子。

本文将会在第2章根据SMOTE的核心以及其伪代码实现该算法,并应用在测试数据集上;第3章会使用第三方imbalanced-learn库中实现的SMOTE算法进行采样,以验证我们实现的算法的准确性,当然这个库中的算法要优于朴素的SMOTE算法,之后我们会以决策树和高斯贝叶斯分类器为工具,对测试原始数据、应用我们所实现的SMOTE采样后产生的数据以及应用第三方库SMOTE产生的数据三者分别产生的数据集进行性能比较;第4章会讨论朴素SMOTE算法更加鲁棒和表现更好的优化途径;第5章是对本文的总结。

2. 算法分析与实现

Fig. 2是在SMOTE论文中提出的伪代码,由两个函数SMOTE(T, N, K)Populate(N, i, nnarray)组成。

Figure 2: algorithm

SMOTE负责接受要采样的类数据集X,返回一个经过SMOTE采样后的数据集,大小为(N/100)*T,函数有三个参数,分别是T: 需要处理的数据集X的样本数量; N: 采样比例,一般为100, 200, 300等整百数,对应即1倍,2倍,3倍;K: 为采样的最近邻数量,论文中默认为5SMOTE代码思想非常简单,扫描每一个样本点,计算每一个样本点的K个最近邻,将每一个最近邻样本点的索引记录在nnarray中,之后传入Populate(N, i, nnarray)中即完成一个样本点的采样。

Populate则负责根据nnarray中的索引去随机生成N个与观测样本i相似的样本。该函数会计算随机邻近点nn与观测样本i点的每一个特征之间的差距dif,将其差距乘上一个[0, 1]随机因子gap,再将dif*gap的值加上观测点i即完成了一个特征的合成。

在Python中实现如下:

注:为了保证本文中所有代码的可复现性,设置的random_state均为666

def NaiveSMOTE(X, N=100, K=5):"""{X}: minority class samples;{N}: Amount of SMOTE; default 100;{K} Number of nearest; default 5;"""# {T}: Number of minority class samples; T = X.shape[0]if N < 100:T = (N/100) * TN = 100N = (int)(N/100)numattrs = X.shape[1]samples = X[:T]neigh = NearestNeighbors(n_neighbors=K)neigh.fit(samples)Synthetic = np.zeros((T*N, numattrs))newindex = 0def Populate(N, i, nns, newindex):"""Function to generate the synthetic samples."""for n in range(N):nn = np.random.randint(0, K)for attr in range(numattrs):dif = samples[nns[nn], attr] - samples[i, attr]gap = np.random.random()Synthetic[newindex, attr] = samples[i, attr] + gap*difnewindex += 1return newindexfor i in range(T):nns = neigh.kneighbors([samples[i]], K, return_distance=False)newindex = Populate(N, i, nns[0], newindex)return Synthetic

这里没有采用矩阵运算,而是完完全全的按照论文中的方式复现(所以称为NaiveSMOTE),其中最近邻的计算我们使用scikit-learn提供的NearestNeighbors类完成。

接下来我们使用scikit-learn中的make_classification来生成测试分类数据集,模拟不平衡类数据,当然有兴趣的读者也可以去寻找论文中所使用的数据集。

from sklearn.datasets import make_classification
X, y = make_classification(n_samples=500,n_features=9,n_redundant=3,weights=(0.1, 0.9),n_clusters_per_class=2,random_state=666)   # 为了可复现性
print(X.shape, y.shape)       # ((500, 9), (500,))# 查看y的各类样本数
print(view_y(y))              # class 0: 50  class 1: 450

原数据集的分布如Fig. 3所示,其中红色圆圈为正类即少数类,蓝色×为负类即多数类。

Figure 3: original_dataset

将我们实现的NaiveSMOTE应用在此测试数据上:

X_over_sampling = NaiveSMOTE(X[y==0], N=800)
print(X_over_sampling.shape)         # (400, 9) 新增了400个样本# 将合成数据与原数据集合并
new_X = np.r_[X, X_over_sampling]
new_y = np.r_[y, np.zeros((X_over_sampling.shape[0]))]
print(new_X.shape, new_y.shape)      # ((900, 9), (900,))print(view_y(new_y))                 # class 0: 450 class 1: 450

接下来我们将原数据集与经过NaiveSMOTE合成后的数据集进行比对:

可以很清晰的看见原来的类增大至一个满意的水平,并且生成的类之间距离都相距不远。

扩展:

探索SMOTE算法 - 知乎 (zhihu.com)

过采样算法之SMOTE - wqbin - 博客园 (cnblogs.com)

过采样算法之SMOTE相关推荐

  1. 青源 LIVE 预告 | 北大王一飞:高效 GAN 采样算法 (ECML 最佳论文解读)

    近期北京大学林宙辰教授所带领的 ZERO 实验室获得了 ECML-PKDD 机器学习方向最佳论文奖(因为一作是学生,同时也是最佳学生论文.) 论文标题: Reparameterized Samplin ...

  2. 【LDA学习系列】MCMC之Metropolis-Hastings采样算法python代码理解

    Metropolis-Hastings采样算法的流程: 代码一:有助于理解算法流程 # -*- coding: utf-8 -*- ''' Created on 2018年5月15日@author: ...

  3. 【机器学习算法-python实现】采样算法的简单实现

    1.背景     采样算法是机器学习中比较常用,也比较容易实现的(出去分层采样).常用的采样算法有以下几种(来自百度知道): 一.单纯随机抽样(simple random sampling)将调查总体 ...

  4. 采样算法哪家强?一个针对主流采样算法的比较

    论文标题: A Systematic Characterization of Sampling Algorithms for Open-ended Language Generation 论文作者: ...

  5. 机器学习 —— 概率图模型(推理:采样算法)

    基于采样的推理算法利用的思想是  概率 = 大样本下频率.故在获得图模型以及CPD的基础上,通过设计采样算法模拟事件发生过程,即可获得一系列事件(联合概率质量函数)的频率,从而达到inference的 ...

  6. 单片机ADC采样算法----递推平均值采样法

    在上一篇文章单片机ADC采样算法---平均值采样法中分析了平均值采样法的使用,上篇文章中的平均值采样法是连续采样100个数据,然后求平均值,这种方法存在一个问题,就是采集100个值之后,下一次又重新采 ...

  7. 路径规划之空间采样算法研究现状简述

    关注同名微信公众号"混沌无形",有趣好文! 原文链接:机器人空间采样算法研究现状简述(包含原文PDF百度云下载链接) 摘要:运动规划是移动机器人自主导航系统中的重要模块之一,相关算 ...

  8. 基本采样算法及Python实现

    本文代码见于 code 时不时地我们会在机器学习乃至深度神经网络中瞥见采样算法的身影.本文只关键简单的入门级的采样算法及其Python实现. use more samples for the more ...

  9. 【采样算法】拉丁超立方采样

    [采样算法]拉丁超立方采样 简介 过程 一维拉丁超立方采样 多维拉丁超立方采样 python编程 结论 参考 简介 LHS(Latin Hypercube Sampling)是一种分层采样方法,相较于 ...

最新文章

  1. 连接被远程计算机621,拨号上网常见错误代码提示及解决方法
  2. Tengine 安装和基本使用
  3. Apache Kafka-SpringBoot整合Kafka发送复杂对象
  4. 计算机操作系统还能这样玩?这一篇计算机操作系统的总结为你保驾护航(零风险、高质量、万字长文、建议收藏)
  5. TensorFlow12CIFAR-CNN实现
  6. 还记得吗?可我摸了摸的太空堡垒
  7. 信息审计服务器功能,审计服务器是什么意思?如何使用Audit和目录审计
  8. HNU 程序设计课 函数公式题
  9. 如何禁用 7 个完全不必要的设置来优化 Mac?
  10. Windows 如何设置新建文本文档快捷键
  11. python做图像识别好还是c++好_用于图像识别的顶级编程语言
  12. 各纬度气候分布图_【地理】气候类型的分布规律及分布图的判读 [图片]
  13. Deeplearning4j 快速入门
  14. vim生成连续数字列
  15. 微信小程序--红色星球
  16. KDEUnivariate.fit 参数详解
  17. 【学术期刊】2023CCF推荐的A,B,C类英文科技期刊目录最新发布
  18. 科技无障碍盛会举办,人工智能和创新成为高频词
  19. STA setup/hold time可以是负数么?
  20. SpringBoot + Redis实现事件的发布订阅功能

热门文章

  1. 对图标的坐标轴进行调整
  2. matlab 提取极值,利用matlab 进行极值统计的一个例子——gev 方法.pdf
  3. easyx的基础应用教程
  4. 清华姚班陈丹琦获斯隆奖!博士毕业论文是近十年最热之一
  5. wpa_supplicant 工具操作wifi模块
  6. WebGL着色器内置变量gl_PointSize、gl_Position、gl_FragColor、gl_FragCoord、gl_PointCoord
  7. 为什么MySql每晚12点都会弹出这个?
  8. Js数组里删除指定的元素(不是指定的位置)
  9. NeoCognitron
  10. 仿ZAKER的windows phone风格主界面