17.11.28更新一下:最近把这个算法集成到了数据预处理的python工程代码中了,不想看原理想直接用的,有简易版的python开发:特征工程代码模版
,进入页面后ctrl+F搜smote就行,请自取


之前一直没有用过python,最近做了一些数量级比较大的项目,觉得有必要熟悉一下python,正好用到了smote,网上也没有搜到,所以就当做一个小练手来做一下。

首先,看下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是样本类别判别标签,0:1=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.5return 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训练的初始少类样本集合中去抽样
所以,剔除左侧的青色新增点,只保留右边的新增数据如下:


欢迎大家关注我的个人bolg,更多代码内容欢迎follow我的个人Github,如果有任何算法、代码疑问都欢迎通过公众号发消息给我哦。

少年,扫一下嘛

参考文献:

  • 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.

作者:slade_sal
链接:https://www.jianshu.com/p/ecbc924860af
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

Python:SMOTE算法相关推荐

  1. python过采样代码实现_过采样中用到的SMOTE算法

    平时很多分类问题都会面对样本不均衡的问题,很多算法在这种情况下分类效果都不够理想.类不平衡(class-imbalance)是指在训练分类器中所使用的训练集的类别分布不均.比如说一个二分类问题,100 ...

  2. Python:SMOTE算法——样本不均衡时候生成新样本的算法

    Python:SMOTE算法 直接用python的库, imbalanced-learn imbalanced-learn is a python package offering a number ...

  3. 当常规的算法都山穷水尽之后,你可以试试python中的SMOTE算法

    点击"阅读原文"直接打开[北京站 | GPU CUDA 进阶课程]报名链接 沙韬伟,苏宁易购高级算法工程师. 曾任职于Hewlett-Packard.滴滴出行. 数据学院特邀讲师. ...

  4. SMOTE算法代码实现-机器学习

    类别不平衡问题 类别不平衡问题,顾名思义,即数据集中存在某一类样本,其数量远多于或远少于其他类样本,从而导致一些机器学习模型失效的问题.例如逻辑回归即不适合处理类别不平衡问题,例如逻辑回归在欺诈检测问 ...

  5. 不平衡分类之逻辑回归,基于python,SMOTE和RFE

    逻辑回归又称logistic回归分析,是一种广义的线性回归分析模型,常用于数据挖掘,疾病自动诊断,经济预测等领域.逻辑回归从本质来说属于二分类问题. 二分类问题是指预测的y值只有两个取值(0或1),二 ...

  6. SMOTE算法代码是什么

    SMOTE算法(Synthetic Minority Over-sampling Technique)是一种用于解决数据集不平衡问题的算法.它主要是通过生成新的数据点来增加少数类的样本数量,以提高分类 ...

  7. smote算法_海量样本无从下手?这五种抽样算法分分钟搞定

    全文共1854字,预计学习时长4分钟 数据科学是研究算法的学科.本文介绍了一些常见的用于处理数据的抽样技术. 图片来源:unsplash.com/@gndclouds 简单随机抽样 假设要从一个群体中 ...

  8. 数据预处理与特征工程—1.不均衡样本集采样—SMOTE算法与ADASYN算法

    文章目录 一.第一种思路:平衡采样 1.SMOTE算法 2.SMOTE与RandomUnderSampler进行结合 3.Borderline-SMOTE与SVMSMOTE 4.ADASYN 5.平衡 ...

  9. GitHub超4.1万星,最全Python入门算法来了

    本文来自公众号:超级数学建模 微信号 :supermodeling 今天,阿广给大家推荐一个好资源,一个在 Github 上超过 2.7 万星标的项目:最全算法及Python实现. 该项目主要包括两方 ...

最新文章

  1. CVPR 2021评审出炉,得分惨不忍睹,面对奇葩评审该如何反击?
  2. VMRC控制台的连接已断开..正在尝试重新连接
  3. python生成回文数
  4. 省市县联动javascript版..
  5. python后台返回cookie_Django框架设置cookies与获取cookies操作详解
  6. 如何配置CentOS或者RedHat5.X、6.X、7.X的网络yum源
  7. 荣耀赵明评苹果发布会掉队5G:意料之中 情理之外
  8. security框架工作笔记001--- Shiro和Spring Security对比_智慧城市项目中选型用Spring Security
  9. C/C++的内存泄漏检测工具Valgrind memcheck的使用经历
  10. python处理数据快吗_python (七、Numpy高效数据处理)
  11. php 地区表设计,php消息表设计
  12. 校园二手交易平台-简要需求分析
  13. gui框架 java_现在选择哪个Java GUI框架
  14. php mpm_winnt,Windows下Apache模块配置 mpm_winnt_module
  15. Pdf.js 解决电子印章问题
  16. The error may exist in /com/bjpowernode/dao/StudentDao.xml ### Cause: org.apache.ibatis.builder.Buil
  17. [NOI2022] 众数 题解
  18. 动圈耳机振膜_小白大讲堂: 耳机振膜材料对音质的影响
  19. Fedora 10 下载地址
  20. 艾默生流量计如何做好防爆工作

热门文章

  1. ASO优化之如何维护关键词群
  2. Windows sever中域、域树、域森林之间的区别与联系
  3. AlexNet详细解读
  4. 使用STM8S003K3 ADC简介以及初始化
  5. Silverlight.XNA(C#)跨平台3D游戏研发手记:(五)SLG动感增效之《幻影粒子》
  6. 华为LiteOS操作系统基础知识入门与内核移植
  7. PostgreSQL还原.bak文件
  8. Oracle数据库表空间变更路径位置
  9. Qemu-spice云桌面创建
  10. html fixed垂直居中,前端垂直居中的几种简单实现