Python:SMOTE算法

直接用python的库,

imbalanced-learn

imbalanced-learn is a python package offering a number of re-sampling techniques commonly used in datasets showing strong between-class imbalance. It is compatible with scikit-learn and is part of scikit-learn-contrib projects.

---------------------

http://contrib.scikit-learn.org/imbalanced-learn/stable/auto_examples/over-sampling/plot_smote.html#sphx-glr-auto-examples-over-sampling-plot-smote-py

http://contrib.scikit-learn.org/imbalanced-learn/stable/over_sampling.html#from-random-over-sampling-to-smote-and-adasyn 入门

SMOTE

An illustration of the SMOTE method and its variant.

# Authors: Fernando Nogueira
#          Christos Aridas
#          Guillaume Lemaitre <g.lemaitre58@gmail.com>
# License: MITimport matplotlib.pyplot as plt from sklearn.datasets import make_classification from sklearn.decomposition import PCA from imblearn.over_sampling import SMOTE print(__doc__) def plot_resampling(ax, X, y, title): c0 = ax.scatter(X[y == 0, 0], X[y == 0, 1], label="Class #0", alpha=0.5) c1 = ax.scatter(X[y == 1, 0], X[y == 1, 1], label="Class #1", alpha=0.5) ax.set_title(title) ax.spines['top'].set_visible(False) ax.spines['right'].set_visible(False) ax.get_xaxis().tick_bottom() ax.get_yaxis().tick_left() ax.spines['left'].set_position(('outward', 10)) ax.spines['bottom'].set_position(('outward', 10)) ax.set_xlim([-6, 8]) ax.set_ylim([-6, 6]) return c0, c1 # Generate the dataset X, y = make_classification(n_classes=2, class_sep=2, weights=[0.3, 0.7], n_informative=3, n_redundant=1, flip_y=0, n_features=20, n_clusters_per_class=1, n_samples=80, random_state=10) # Instanciate a PCA object for the sake of easy visualisation pca = PCA(n_components=2) # Fit and transform x to visualise inside a 2D feature space X_vis = pca.fit_transform(X) # Apply regular SMOTE kind = ['regular', 'borderline1', 'borderline2', 'svm'] sm = [SMOTE(kind=k) for k in kind] X_resampled = [] y_resampled = [] X_res_vis = [] for method in sm: X_res, y_res = method.fit_sample(X, y) X_resampled.append(X_res) y_resampled.append(y_res) X_res_vis.append(pca.transform(X_res)) # Two subplots, unpack the axes array immediately f, ((ax1, ax2), (ax3, ax4), (ax5, ax6)) = plt.subplots(3, 2) # Remove axis for second plot ax2.axis('off') ax_res = [ax3, ax4, ax5, ax6] c0, c1 = plot_resampling(ax1, X_vis, y, 'Original set') for i in range(len(kind)): plot_resampling(ax_res[i], X_res_vis[i], y_resampled[i], 'SMOTE {}'.format(kind[i])) ax2.legend((c0, c1), ('Class #0', 'Class #1'), loc='center', ncol=1, labelspacing=0.) plt.tight_layout() plt.show() 

Total running time of the script: ( 0 minutes 0.704 seconds)

Python:SMOTE算法

from:https://www.jianshu.com/p/ecbc924860af

首先,看下Smote算法之前,我们先看下当正负样本不均衡的时候,我们通常用的方法:

  • 抽样
    常规的包含过抽样、欠抽样、组合抽样
    过抽样:将样本较少的一类sample补齐
    欠抽样:将样本较多的一类sample压缩
    组合抽样:约定一个量级N,同时进行过抽样和欠抽样,使得正负样本量和等于约定量级N

这种方法要么丢失数据信息,要么会导致较少样本共线性,存在明显缺陷

  • 权重调整
    常规的包括算法中的weight,weight matrix
    改变入参的权重比,比如boosting中的全量迭代方式、逻辑回归中的前置的权重设置

这种方式的弊端在于无法控制合适的权重比,需要多次尝试

  • 核函数修正
    通过核函数的改变,来抵消样本不平衡带来的问题

这种使用场景局限,前置的知识学习代价高,核函数调整代价高,黑盒优化

  • 模型修正
    通过现有的较少的样本类别的数据,用算法去探查数据之间的特征,判读数据是否满足一定的规律
    比如,通过线性拟合,发现少类样本成线性关系,可以新增线性拟合模型下的新点

实际规律比较难发现,难度较高

SMOTE(Synthetic minoritye over-sampling technique,SMOTE)是Chawla在2002年提出的过抽样的算法,一定程度上可以避免以上的问题

下面介绍一下这个算法:

正负样本分布

很明显的可以看出,蓝色样本数量远远大于红色样本,在常规调用分类模型去判断的时候可能会导致之间忽视掉红色样本带了的影响,只强调蓝色样本的分类准确性,这边需要增加红色样本来平衡数据集

Smote算法的思想其实很简单,先随机选定n个少类的样本,如下图

找出初始扩展的少类样本

再找出最靠近它的m个少类样本,如下图

再任选最临近的m个少类样本中的任意一点,

在这两点上任选一点,这点就是新增的数据样本


R语言上的开发较为简单,有现成的包库,这边简单介绍一下:

rm(list=ls())
install.packages(“DMwR”,dependencies=T)
library(DMwR)#加载smote包
newdata=SMOTE(formula,data,perc.over=,perc.under=)
#formula:申明自变量因变量
#perc.over:过采样次数 #perc.under:欠采样次数 

效果对比:

简单的看起来就好像是重复描绘了较少的类
这边的smote是封装好的,直接调用就行了,没有什么特别之处


这边自己想拿刚学的python练练手,所有就拿python写了一下过程:

# -*- coding: utf-8 -*-
import numpy as np
import pandas as pd from sklearn.preprocessing import StandardScaler from numpy import * import matplotlib.pyplot as plt #读数据 data = pd.read_table('C:/Users/17031877/Desktop/supermarket_second_man_clothes_train.txt', low_memory=False) #简单的预处理 test_date = pd.concat([data['label'], data.iloc[:, 7:10]], axis=1) test_date = test_date.dropna(how='any') 

数据大致如下:

test_date.head()
Out[25]: label  max_date_diff  max_pay  cnt_time
0      0           23.0  43068.0        15
1      0           10.0   1899.0         2
2      0          146.0   3299.0        21
3      0           30.0  31959.0        35
4      0            3.0  24165.0        98
test_date['label'][test_date['label']==0].count()/test_date['label'][test_date['label']==1].count()
Out[37]: 67

label是样本类别判别标签,1:0=67:1,需要对label=1的数据进行扩充


# 筛选目标变量
aimed_date = test_date[test_date['label'] == 1]
# 随机筛选少类扩充中心
index = pd.DataFrame(aimed_date.index).sample(frac=0.1, random_state=1)
index.columns = ['id']
number = len(index)
# 生成array格式 aimed_date_new = aimed_date.ix[index.values.ravel(), :] 

随机选取了全量少数样本的10%作为数据扩充的中心点



# 自变量标准化
sc = StandardScaler().fit(aimed_date_new)
aimed_date_new = pd.DataFrame(sc.transform(aimed_date_new))
sc1 = StandardScaler().fit(aimed_date)
aimed_date = pd.DataFrame(sc1.transform(aimed_date))# 定义欧式距离计算
def dist(a, b): a = array(a) b = array(b) d = ((a[0] - b[0]) ** 2 + (a[1] - b[1]) ** 2 + (a[2] - b[2]) ** 2 + (a[3] - b[3]) ** 2) ** 0.5 return d 

下面定义距离计算的方式,所有算法中,涉及到距离的地方都需要标准化去除冈量,也同时加快了计算的速度
这边采取了欧式距离的方式,更多计算距离的方式参考:
多种距离及相似度的计算理论介绍


# 统计所有检验距离样本个数
row_l1 = aimed_date_new.iloc[:, 0].count()
row_l2 = aimed_date.iloc[:, 0].count()
a = zeros((row_l1, row_l2))
a = pd.DataFrame(a)
# 计算距离矩阵 for i in range(row_l1): for j in range(row_l2): d = dist(aimed_date_new.iloc[i, :], aimed_date.iloc[j, :]) a.ix[i, j] = d b = a.T.apply(lambda x: x.min()) 

调用上面的计算距离的函数,形成一个距离矩阵


# 找到同类点位置
h = []
z = []
for i in range(number):for j in range(len(a.iloc[i, :])): ai = a.iloc[i, j] bi = b[i] if ai == bi: h.append(i) z.append(j) else: continue new_point = [0, 0, 0, 0] new_point = pd.DataFrame(new_point) for i in range(len(h)): index_a = z[i] new = aimed_date.iloc[index_a, :] new_point = pd.concat([new, new_point], axis=1) new_point = new_point.iloc[:, range(len(new_point.columns) - 1)] 

再找到位置的情况下,再去原始的数据集中根据位置查找具体的数据


import random
r1 = []
for i in range(len(new_point.columns)):r1.append(random.uniform(0, 1)) new_point_last = [] new_point_last = pd.DataFrame(new_point_last) # 求新点 new_x=old_x+rand()*(append_x-old_x) for i in range(len(new_point.columns)): new_x = (new_point.iloc[1:4, i] - aimed_date_new.iloc[number - 1 - i, 1:4]) * r1[i] + aimed_date_new.iloc[ number - 1 - i, 1:4] new_point_last = pd.concat([new_point_last, new_x], axis=1) print new_point_last 

最后,再根据smote的计算公式new_x=old_x+rand()*(append_x-old_x),计算出新的点即可,python练手到此就结束了

其实,在这个结果上,我们可以综合Tomek link做一个集成的数据扩充的算法,思路如下:
假设,我们利用上述的算法产生了两个青色方框的新数据点:

我们认为,对于新产生的青色数据点与其他非青色样本点距离最近的点,构成一对Tomek link,如下图框中的青蓝两点

我们可以定义规则:
当以新产生点为中心,Tomek link的距离为范围半径,去框定一个空间,空间内的少数类的个数/多数类的个数<最低阀值的时候,认为新产生点为“垃圾点”,应该剔除或者再次进行smote训练;空间内的少数类的个数/多数类的个数>=最低阀值的时候,在进行保留并纳入smote训练的初始少类样本集合中去抽样
所以,剔除左侧的青色新增点,只保留右边的新增数据如下:

参考文献:

  • https://www.jair.org/media/953/live-953-2037-jair.pdf
  • https://github.com/fmfn/UnbalancedDataset
  • Batista, G. E., Bazzan, A. L., & Monard, M. C. (2003, December). Balancing Training Data for Automated Annotation of Keywords: a Case Study. In WOB (pp. 10-18).
  • Batista, G. E., Prati, R. C., & Monard, M. C. (2004). A study of the behavior of several methods for balancing machine learning training data. ACM Sigkdd Explorations Newsletter, 6(1), 20-29.

转载于:https://www.cnblogs.com/bonelee/p/8535045.html

Python:SMOTE算法——样本不均衡时候生成新样本的算法相关推荐

  1. CVPR2022 | ZeroCap:零样本图像到文本生成的视觉语义算法

    CVPR2022 | ZeroCap:零样本图像到文本生成的视觉语义算法 [写在前面] 最近的文本到图像匹配模型将对比学习应用于大量未经管理的图像和句子对.虽然此类模型可以为匹配和后续的zero-sh ...

  2. DL之DCGNN:基于TF利用DCGAN实现在MNIST数据集上训练生成新样本

    DL之DCGNN:基于TF利用DCGAN实现在MNIST数据集上训练生成新样本 目录 输出结果 设计思路 实现部分代码 说明:所有图片文件丢失 输出结果 更新-- 设计思路 更新-- 实现部分代码 更 ...

  3. python加法运算符可以用来连接字符串并生成新字符串_加法运算符可以用来连接字符串并生成新字符串。...

    [其它]请参考附件中的实验程序说明文档,在完成实验,并获得汇总的班级实验数据之后,撰写实验报告.实验报告的格式请参考模版. 心理旋转实验.docx 实验心理学实验报告模板2019.doc 视觉反应时实 ...

  4. SVM+HOG:用初次训练的.xml分类器在负样本原图上检测生成HardExample样本

    难例(或叫做难样本,Hard Example,Hard Negative,Hard Instance)是指利用第一次训练的 分类器在负样本原图(肯定没有人体)上进行行人检测时所有检测到的矩形框,这些矩 ...

  5. python自动寻路算法_PHP生成迷宫及自动寻路算法详解

    如何使用PHP生成迷宫以及寻路求解?本文主要介绍了PHP生成迷宫及自动寻路算法,并对PHP生成迷宫及自动寻路算法详解.希望对大家有所帮助. 本文实例讲述了PHP树的深度编历生成迷宫及A*自动寻路算法. ...

  6. 综述:解决目标检测中的样本不均衡问题

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 作者丨SFXiang 来源丨AI算法修炼营 编辑丨极市平台 极市导 ...

  7. 机器学习-样本不均衡现象

    转载自:http://blog.csdn.net/lujiandong1/article/details/52658675 这几年来,机器学习和数据挖掘非常火热,它们逐渐为世界带来实际价值.与此同时, ...

  8. 正负样本不均衡的解决办法

    转载自:http://blog.csdn.net/lujiandong1/article/details/52658675 这几年来,机器学习和数据挖掘非常火热,它们逐渐为世界带来实际价值.与此同时, ...

  9. 机器学习-10:MachineLN之样本不均衡

    版权声明:本文为博主原创文章,未经博主允许不得转载.有问题可以加微信:lp9628(注明CSDN). https://blog.csdn.net/u014365862/article/details/ ...

最新文章

  1. 智能车竞赛视觉AI组总结 西南科技大学 – 西科二队
  2. 浅析网站排版如何让用户获得良好的访问体验
  3. python显示外部命令_Python 执行外部指令
  4. RNN 怎么用?给初学者的小教程
  5. python之路——网络编程
  6. 联想linux笔记本评测,联想(lenovo)G460AL-ITH Linux笔记本电脑CPU测试评测-ZOL中关村在线...
  7. java接口文档生成工具_【分享】接口文档生成工具apipost
  8. 淘宝API开发系列--开篇概述
  9. 修改webpack配置,在react中使用less
  10. linux系统之编译内核实现iptables应用层过滤
  11. 网页跳转出现内部服务器错误,页面跳转后提示HTTP异常500(InternalServerError):服务器尝试执行请求时遇到了意外情况...
  12. go导出mysql中的excel表_golang web 开发 从数据库 导出到excel案例
  13. ArcGIS土地利用重分类(一)简单的reclass by table方法
  14. java微信退款接口demo_微信公众号接口开发----退款详解
  15. 多个excel工作簿合并_你还在使用复制粘贴合并表格?一个公式搞定Excel多工作簿合并...
  16. U盘无法格式化怎么办?
  17. word导出html乱码怎么办,Word文档文件变成乱码如何完全修复?-修复百科
  18. 最新的AS下载地址,更新及时
  19. APPCAN学习笔记001---app高速开发AppCan.cn平台概述
  20. 数据堂-数加加众包任务招募啦~!说方言,来赚钱

热门文章

  1. volatile和内存屏障(dmb)
  2. linux系统中怎么驱动U盘
  3. JavaScript 的 Promise  和  C# 的 waitone 一样吗?请大家讨论i两句。
  4. python开多少进程合适_python多进程基础
  5. 安师大计算机与信息学院导师,安徽师范大学数学计算机科学学院导师介绍:罗永龙...
  6. java 函数参数 返回值_java中如何用函数返回值作为post提交的参数?
  7. 企业研发人员配备比例_企业管理人员合理配置比例
  8. 3v stm32 供电 晶振起振_避免stm32rtc晶振不能起振的设计参考
  9. node mysql 连接池 超时,关于NodeJS中mysql连接池卡死问题
  10. linux下查找某个文件位置的方法