python抽样方法详解及实现

2023-05-16

抽样方法概览

在这里插入图片描述
在这里插入图片描述

随机抽样—总体个数较少

每个抽样单元被抽中的概率相同,并且可以重现。随机抽样常常用于总体个数较少时,它的主要特征是从总体中逐个抽取。
在这里插入图片描述
1、抽签法
2、随机数法:随机数表、随机数骰子或计算机产生的随机数。

分层抽样——总体存在差异且对结果有影响

分层抽样是指在抽样时,将总体分成互不相交的层,然后按照一定的比例,从各层独立地抽取一定数量的个体,将各层取出的个体合在一起作为样本的方法。层内变异越小越好,层间变异越大越好。
分层以后,在每一层进行简单随机抽样,不同群体所抽取的个体个数,一般有三种方法:
(1)等数分配法,即对每一层都分配同样的个体数;
(2)等比分配法,即让每一层抽得的个体数与该类总体的个体数之比都相同;
(3)最优分配法,即各层抽得的样本数与所抽得的总样本数之比等于该层方差与各类方差之和的比。

import  pandas as pd
import random as rd
import numpy as np
import math as ma

def typeicalSampling(group, typeicalFracDict):
    name = group.name
    frac = typeicalFracDict[name]
    return group.sample(frac=frac)

def group_sample(data_set,lable,typeicalFracDict):
    #分层抽样
    #data_set数据集
    #lable分层变量名
    #typeicalFracDict:分类抽样比例
    gbr=data_set.groupby(by=[lable])
    result=data_set.groupby(lable,group_keys=False).apply(typeicalSampling,typeicalFracDict)
    return result

data = pd.DataFrame({'id': [3566841, 6541227, 3512441, 3512441, 3512441,3512441, 3512441, 3512441, 3512441, 3512441],
                   'sex': ['male', 'Female', 'Female','male', 'Female', 'Female','male', 'Female','male', 'Female'],
                   'level': ['high', 'low', 'middle','high', 'low', 'middle','high', 'low', 'middle','middle']})

data_set=data
label='sex'
typicalFracDict = {
    'male': 0.8,
    'Female': 0.2
}
result=group_sample(data_set,label,typicalFracDict)
print(result)

整体抽样

整群抽样又称聚类抽样,是将总体中各单位归并成若干个互不交叉、互不重复的集合,称之为群;然后以群为抽样单位抽取样本的一种抽样方式。应用整群抽样时,要求各群有较好的代表性,即群内各单位的差异要大,群间差异要小。
实施步骤
先将总体分为i个群,然后从i个群中随即抽取若干个群,对这些群内所有个体或单元均进行调查。抽样过程可分为以下几个步骤:
(1)确定分群的标注
(2)总体(N)分成若干个互不重叠的部分,每个部分为一群。
(3)据各样本量,确定应该抽取的群数。
(4)采用简单随机抽样或系统抽样方法,从i群中抽取确定的群数。

系统抽样——总体多

系统抽样亦称为机械抽样、等距抽样。 [4] 当总体中的个体数较多时,采用简单随机抽样显得较为费事。这时,可将总体分成均衡的几个部分,然后按照预先定出的规则,从每一部分抽取一个个体,得到所需要的样本,这种抽样叫做系统抽样。 [1]
在这里插入图片描述

def SystematicSampling(dataMat,number):    
       length=len(dataMat)
       k=int(length/number)
       sample=[]     
       i=0
       if k>0 :       
         while len(sample)!=number:
            sample.append(dataMat[0+i*k])
            i+=1            
         return sample
       else :
         return RandomSampling(dataMat,number) 

过采样

参考文献:https://www.cnblogs.com/massquantity/p/9382710.html
1、RandomOverSampler
原理:从样本少的类别中随机抽样,再将抽样得来的样本添加到数据集中。
缺点:重复采样往往会导致严重的过拟合
主流过采样方法是通过某种方式人工合成一些少数类样本,从而达到类别平衡的目的,而这其中的鼻祖就是SMOTE。

from imblearn.over_sampling import RandomOverSampler
ros = RandomOverSampler(sampling_strategy={0: 700,1:200,2:150 },random_state=0)
X_resampled, y_resampled = ros.fit_sample(X, y)
print(Counter(y_resampled))

2、SMOTE
原理:在少数类样本之间进行插值来产生额外的样本。对于少数类样本a, 随机选择一个最近邻的样本b, 从a与b的连线上随机选取一个点c作为新的少数类样本;
具体地,对于一个少数类样本xi使用K近邻法(k值需要提前指定),求出离xi距离最近的k个少数类样本,其中距离定义为样本之间n维特征空间的欧氏距离。然后从k个近邻点中随机选取一个,使用下列公式生成新样本:
在这里插入图片描述在这里插入图片描述

from imblearn.over_sampling import SMOTE
smo = SMOTE(sampling_strategy={0: 700,1:200,2:150 },random_state=42)
X_smo, y_smo = smo.fit_sample(X, y)
print(Counter(y_smo))

SMOTE会随机选取少数类样本用以合成新样本,而不考虑周边样本的情况,这样容易带来两个问题

1)如果选取的少数类样本周围也都是少数类样本,则新合成的样本不会提供太多有用信息。
2)如果选取的少数类样本周围都是多数类样本,这类的样本可能是噪音,则新合成的样本会与周围的多数类样本产生大部分重叠,致使分类困难。
总的来说我们希望新合成的少数类样本能处于两个类别的边界附近,这样往往能提供足够的信息用以分类。而这就是下面的 Border-line SMOTE 算法要做的事情。
3、BorderlineSMOTE
这个算法会先将所有的少数类样本分成三类,如下图所示:
“noise” : 所有的k近邻个样本都属于多数类
“danger” : 超过一半的k近邻样本属于多数类
“safe”: 超过一半的k近邻样本属于少数类
在这里插入图片描述
Border-line SMOTE算法只会从处于”danger“状态的样本中随机选择,然后用SMOTE算法产生新的样本。处于”danger“状态的样本代表靠近”边界“附近的少数类样本,而处于边界附近的样本往往更容易被误分类。因而 Border-line SMOTE 只对那些靠近”边界“的少数类样本进行人工合成样本,而 SMOTE 则对所有少数类样本一视同仁。

Border-line SMOTE 分为两种: Borderline-1 SMOTE 和 Borderline-2 SMOTE。 Borderline-1 SMOTE 在合成样本时式中的x^
是一个少数类样本,而 Borderline-2 SMOTE 中的x^则是k近邻中的任意一个样本。

from imblearn.over_sampling import BorderlineSMOTE
smo = BorderlineSMOTE(kind='borderline-1',sampling_strategy={0: 700,1:200,2:150 },random_state=42) #kind='borderline-2'
X_smo, y_smo = smo.fit_sample(X, y)
print(Counter(y_smo))

4、ADASYN
原理:采用某种机制自动决定每个少数类样本需要产生多少合成样本,而不是像SMOTE那样对每个少数类样本合成同数量的样本。先确定少数样本需要合成的样本数量(与少数样本周围的多数类样本数呈正相关),然后利用SMOTE合成样本。
缺点:ADASYN的缺点是易受离群点的影响,如果一个少数类样本的K近邻都是多数类样本,则其权重会变得相当大,进而会在其周围生成较多的样本。

from imblearn.over_sampling import ADASYN
ana = ADASYN(sampling_strategy={0: 800,2:300,1:400 },random_state=0)
X_ana, y_ana = ana.fit_sample(X, y)

用 SMOTE 合成的样本分布比较平均,而Border-line SMOTE合成的样本则集中在类别边界处。ADASYN的特性是一个少数类样本周围多数类样本越多,则算法会为其生成越多的样本,从图中也可以看到生成的样本大都来自于原来与多数类比较靠近的那些少数类样本。

5、KMeansSMOTE
原理:在使用SMOTE进行过采样之前应用KMeans聚类。
KMeansSMOTE包括三个步骤:聚类、过滤和过采样。在聚类步骤中,使用k均值聚类为k个组。过滤选择用于过采样的簇,保留具有高比例的少数类样本的簇。然后,它分配合成样本的数量,将更多样本分配给少数样本稀疏分布的群集。最后,过采样步骤,在每个选定的簇中应用SMOTE以实现少数和多数实例的目标比率。

from imblearn.over_sampling import KMeansSMOTE
kms = KMeansSMOTE(sampling_strategy={0: 800,2:300,1:400 },random_state=42)
X_kms, y_kms = kms.fit_sample(X, y)
print(Counter(y_kms))

6、SMOTENC
可处理分类特征的SMOTE

from imblearn.over_sampling import SMOTENC
sm = SMOTENC(random_state=42, categorical_features=[18, 19])

7、SVMSMOTE
使用支持向量机分类器产生支持向量然后再生成新的少数类样本,然后使用SMOTE合成样本

from imblearn.over_sampling import SVMSMOTE
svmm = SVMSMOTE(sampling_strategy={0: 800,2:300,1:400 },random_state=42)
X_svmm, y_svmm = svmm.fit_sample(X, y)
print(Counter(y_kms))

下采样

1、RandomUnderSampler(可控制欠采样数量)
原理:从多数类样本中随机选取一些剔除掉。
缺点:被剔除的样本可能包含着一些重要信息,致使学习出来的模型效果不好。

from imblearn.under_sampling import RandomUnderSampler
cc = RandomUnderSampler(sampling_strategy={0: 50,2:100,1:100 },random_state=0)
X_resampled, y_resampled = cc.fit_sample(X, y)
print(sorted(Counter(y_resampled).items()))

2、NearMiss(可控制欠采样数量)
原理:从多数类样本中选取最具代表性的样本用于训练,主要是为了缓解随机欠采样中的信息丢失问题。
NearMiss采用一些启发式的规则来选择样本,根据规则的不同可分为3类,通过设定version参数来确定:
NearMiss-1:选择到最近的K个少数类样本平均距离最近的多数类样本
NearMiss-2:选择到最远的K个少数类样本平均距离最近的多数类样本
NearMiss-3:对于每个少数类样本选择K个最近的多数类样本,目的是保证每个少数类样本都被多数类样本包围
NearMiss-1和NearMiss-2的计算开销很大,因为需要计算每个多类别样本的K近邻点。另外,NearMiss-1易受离群点的影响,

from imblearn.under_sampling import NearMiss
nm1 = NearMiss(sampling_strategy={0: 50,2:100,1:100 },random_state=0, version=1)
X_resampled_nm1, y_resampled = nm1.fit_sample(X, y)
print(sorted(Counter(y_resampled).items()))

3、ClusterCentroids(可控制欠采样数量)
原理:利用kmeans将对各类样本分别聚类,利用质心替换整个簇的样本。

from imblearn.under_sampling import ClusterCentroids
cc = ClusterCentroids(sampling_strategy={0: 700,1:100,2:90 },random_state=0)
X_resampled, y_resampled = cc.fit_sample(X, y)
print(sorted(Counter(y_resampled).items()))

4、TomekLinks(数据清洗方法,无法控制欠采样数量)
原理:Tomek Link表示不同类别之间距离最近的一对样本,即这两个样本互为最近邻且分属不同类别。这样如果两个样本形成了一个Tomek Link,则要么其中一个是噪音,要么两个样本都在边界附近。这样通过移除Tomek Link就能“清洗掉”类间重叠样本,使得互为最近邻的样本皆属于同一类别,从而能更好地进行分类。

from imblearn.under_sampling import TomekLinks
nm1 = TomekLinks(sampling_strategy='all',random_state=0)
X_resampled_nm1, y_resampled = nm1.fit_sample(X, y)
print(sorted(Counter(y_resampled).items()))

TomekLinks函数中的auto参数控制Tomek’s links中的哪些样本被剔除. 默认的ratio=‘auto’ 移除多数类的样本, 当ratio='all’时, 两个样本均被移除.

5、EditedNearestNeighbours(数据清洗方法,无法控制欠采样数量)
原理:对于属于多数类的一个样本,如果其K个近邻点有超过一半(kind_sel=‘mode’)或全部(kind_sel=‘all’)都不属于多数类,则这个样本会被剔除。

from imblearn.under_sampling import EditedNearestNeighbours
renn = EditedNearestNeighbours(kind_sel='all')
X_res, y_res = renn.fit_resample(X, y)
print(sorted(Counter(y_res).items()))

6、RepeatedEditedNearestNeighbours (数据清洗方法,无法控制欠采样数量)
原理:重复EditedNearestNeighbours多次(参数max_iter控制迭代次数)

#下采样RepeatedEditedNearestNeighbours接口
from imblearn.under_sampling import RepeatedEditedNearestNeighbours
renn = RepeatedEditedNearestNeighbours(kind_sel='all',max_iter=101)
X_res, y_res = renn.fit_resample(X, y)
print(sorted(Counter(y_res).items()))

7、ALLKNN(数据清洗方法,无法控制欠采样数量)

from imblearn.under_sampling import AllKNN
renn = AllKNN(kind_sel='all')
X_res, y_res = renn.fit_resample(X, y)
print(sorted(Counter(y_res).items()))

8、CondensedNearestNeighbour (数据清洗方法,无法控制欠采样数量)
使用近邻的方法来进行迭代, 来判断一个样本是应该保留还是剔除, 具体的实现步骤如下:

1)集合C: 所有的少数类样本;
2)选择一个多数类样本(需要下采样)加入集合C, 其他的这类样本放入集合S;
3)使用集合S训练一个1-NN的分类器, 对集合S中的样本进行分类;
4)将集合S中错分的样本加入集合C;
5)重复上述过程, 直到没有样本再加入到集合C.

from imblearn.under_sampling import CondensedNearestNeighbour
renn = CondensedNearestNeighbour(random_state=0)
X_res, y_res = renn.fit_resample(X, y)
print(sorted(Counter(y_res).items()))

在这里插入图片描述
CondensedNearestNeighbour方法对噪音数据是很敏感的, 也容易加入噪音数据到集合C中.

9、OneSidedSelection (数据清洗方法,无法控制欠采样数量)
原理:在CondensedNearestNeighbour的基础上使用 TomekLinks 方法来剔除噪声数据(多数类样本).

from imblearn.under_sampling import OneSidedSelection
oss = OneSidedSelection(random_state=0)
X_resampled, y_resampled = oss.fit_sample(X, y)
print(sorted(Counter(y_resampled).items()))

10、NeighbourhoodCleaningRule (数据清洗方法,无法控制欠采样数量)
在这里插入图片描述

from sklearn.linear_model import LogisticRegression
from imblearn.under_sampling import InstanceHardnessThreshold
iht = InstanceHardnessThreshold(random_state=0,
                                estimator=LogisticRegression())
X_resampled, y_resampled = iht.fit_sample(X, y)
print(sorted(Counter(y_resampled).items()))

11、InstanceHardnessThreshold(数据清洗方法,无法控制欠采样数量)
在数据上运用一种分类器, 然后将概率低于阈值的样本剔除掉.

from sklearn.linear_model import LogisticRegression
from imblearn.under_sampling import InstanceHardnessThreshold
iht = InstanceHardnessThreshold(random_state=0,
                                estimator=LogisticRegression())
X_resampled, y_resampled = iht.fit_sample(X, y)
print(sorted(Counter(y_resampled).items()))

在这里插入图片描述
12、EasyEnsemble(可控制数量)
从多数类样本中随机抽样成子集,该子集的数量等于少数类样本的数量。接着将该子集与少数类样本结合起来训练一个模型,迭代n次。这样虽然每个子集的样本少于总体样本,但集成后总信息量并不减少。

from imblearn.ensemble import EasyEnsemble
ee = EasyEnsemble(sampling_strategy={0: 500,1:199,2:89 },random_state=0, n_subsets=10)
X_resampled, y_resampled = ee.fit_sample(X, y)
print(X_resampled.shape)
print(y_resampled.shape)
print(sorted(Counter(y_resampled[0]).items()))

有两个很重要的参数:
(i) n_subsets 控制的是子集的个数
(ii) replacement 决定是有放回还是无放回的随机采样.

13、BalanceCascade(可控制数量)
在第n轮训练中,将从多数类样本中抽样得来的子集与少数类样本结合起来训练一个基学习器H,训练完后多数类中能被H正确分类的样本会被剔除。在接下来的第n+1轮中,从被剔除后的多数类样本中产生子集用于与少数类样本结合起来训练。
同样, n_max_subset 参数控制子集的个数, 以及可以通过设置bootstrap=True来使用bootstraping(自助法).

from imblearn.ensemble import BalanceCascade
from sklearn.linear_model import LogisticRegression
bc = BalanceCascade(random_state=0,
                    estimator=LogisticRegression(random_state=0),
                    n_max_subset=4)
X_resampled, y_resampled = bc.fit_sample(X, y)
print(X_resampled.shape)
print(sorted(Counter(y_resampled[0]).items()))

过采样与下采样结合

SMOTE算法的缺点是生成的少数类样本容易与周围的多数类样本产生重叠难以分类,而数据清洗技术恰好可以处理掉重叠样本,所以可以将二者结合起来形成一个pipeline,先过采样再进行数据清洗。主要的方法是 SMOTE + ENN 和 SMOTE + Tomek ,其中 SMOTE + ENN 通常能清除更多的重叠样本.

1、SMOTEENN

from imblearn.combine import SMOTEENN
smote_enn = SMOTEENN(random_state=0)
X_resampled, y_resampled = smote_enn.fit_sample(X, y)

print(sorted(Counter(y_resampled).items()))

2、 SMOTETomek

from imblearn.combine import SMOTETomek
smote_tomek = SMOTETomek(sampling_strategy={0: 700,1:300,2:200 },random_state=0)
X_resampled, y_resampled = smote_tomek.fit_sample(X, y)
print(sorted(Counter(y_resampled).items()))
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

python抽样方法详解及实现 的相关文章

随机推荐

  • 【Python】Python中 在函数内部对函数外的变量进行操作

    在Python中 xff0c 如果想函数内部对函数外的变量进行操作 xff0c 有一些问题 xff08 一些在Java xff0c C中再正常不过的操作这里就不行 xff09 正常情况下 xff0c 在函数外定义的变量是可以直接在函数体内部
  • 关于proteus中串口发送数据与实际不符的问题(如发00h,收80h)

    工程实训要用到串口 xff0c 51单片机 xff0c 串口工作方式一 xff0c 只发不接受 在proteus中用VIRTUAL TERMINAL xff08 虚拟终端 xff09 监视串口发送数据 现象 xff1a 不论是用虚拟终端还是
  • Jetson TX2的各种坑.md

    最近在使用Jetson TX2 在跑实验 xff0c 然后遇到下面问题 xff0c 做笔记 xff0c 记录一下 内存出错无法 xff0c 中断 出现下面那种错误 2019 01 11 19 41 46 959970 E tensorflo
  • 基于STM32的FreeRTOS开发(1)----FreeRTOS简介

    为什么使用freertos FreeRTOS 是一个免费和开源的实时操作系统 xff0c 它主要用于嵌入式系统 它非常轻量级 xff0c 可以在很小的硬件资源上运行 xff0c 因此非常适合在限制硬件资源的嵌入式系统中使用 FreeRTOS
  • 获奖公布 | 征文——从高考到程序员

    每年的这几天 xff0c 空气中总会弥漫着紧张的味道 xff0c 2017 全国统一高考如期而至 朋友圈里的各种高考热文如流水般 xff0c 不停歇地出现在眼前 xff0c 难免会勾起自己曾经的青涩时光 还记得 xff0c 考试前 xff0
  • STM32驱动ESP8266连接阿里云(2)----接入阿里IoT Studio实现Web可视化

    烧录MQTT固件 概述 阿里IoT Studio是一个物联网开发平台 xff0c 可用于快速构建基于云端的物联网应用 它提供了丰富的物联网组件和工具 xff0c 使得开发者可以轻松地进行设备接入 数据存储 数据分析等操作 要实现Web可视化
  • ‘gbk‘ codec can‘t encode character解决方法

    一 问题 xff1a 在将网络数据流导入文件时 xff0c 有可能遇到 39 gbk 39 codec can 39 t encode characte 错误 二 分析 xff1a 1 在windows下面 xff0c 新文件 xff08
  • ROS中的tf(transform)的理解 ,你追我小乌龟的深入剖析

    对于ros中的tf其实一直理解不是很深 xff0c 最近工作上一直在用 xff0c 就很懵逼 xff0c 出来混果然是要还的 xff5e 于是这两天把ros官方提供的小乌龟版的你追我 xff0c 如果你追到我 xff0c 我就让你xxx x
  • 线程同步之信号量(sem_init,sem_post,sem_wait)

    信号量和互斥锁 mutex 的区别 xff1a 互斥锁只允许一个线程进入临界区 xff0c 而信号量允许多个线程同时进入临界区 不多做解释 xff0c 要使用信号量同步 xff0c 需要包含头文件semaphore h 主要用到的函数 xf
  • 老程序员给的10条建议,句句经典

    1 想清楚 xff0c 再动手写代码 刚入行的新手 xff0c 为了展示自己的能力 xff0c 拿到需求迫不及待地就开始上手写代码 xff0c 大忌 xff01 2 不交流 xff0c 就会头破血流 不爱说话和沟通 xff0c 需求都理解错
  • Clickhouse快速上手 原理篇

    1 背景 公司目前使用Greenplum作为报表实时聚合查询的OLAP数据库 xff0c 当时主要是其使用门槛相对较低 xff0c 同时支持事务 xff0c 能在用户访问时候事务更新数据 xff0c 使用云厂商的产品 xff0c 技术支持也
  • Clickhouse快速上手 使用篇

    接着clickhouse原理篇 xff0c 下面来介绍他的具体使用场景 xff0c 包括数据导入 xff0c 更新等 文章目录 1 数据导入调研计划实施1 cos文件系统集成2 编码获取 2 数据更新和使用 1 数据导入 根据官方介绍 Cl
  • linux基本服务之sshd

    这段时间在学习linux常用服务 xff0c 这里将学习内容以及自己的实验心得记录下来 在自己忘记的时候也好复习 实验环境 xff1a centos 6 7 64bit 1 简介 SSHD服务 介绍 xff1a SSH协议 xff1a 安全
  • Git+VSCode基本使用

    前言 由于工作需要 xff0c 最近简单学习了git xff0c 巧合发现了VSCODE编辑器正好集成了git命令 xff0c 使得本地代码管理变得更加容易 因为最后是在linux下交叉编译 xff0c 但是我更习惯windows下写代码
  • 掌握音频开发基础知识

    文章目录 基本概念几种CODEC介绍实时调度相关缓冲区两种类型编写要点遇到的问题 解码能力的自适应混音模块回声消除的延时控制能量统计双声道支持ALSA设备 代码相关 基本概念 采样率 Hz 每秒去取样本的个数 xff0c eg 48000H
  • CSDN日报20170616 ——《从裁缝到码农》

    程序人生 从裁缝到码农 作者 xff1a 修电脑的裁缝酱 我伸出颤抖的手去抓 xff0c 发现曾经遥不可及的梦想 xff0c 经过坚持和努力之后 xff0c 真的可以抓住 我把它抓在手心 xff0c 紧紧地 点击阅读全文 机器学习 一文了解
  • Java中char类型详解

    1 基本定义 char类型的值可以表示为十六进制值 xff0c 其范围从 u0000 到 uffff xff0c 由两个字节构成 char类型原本用于表示单个字符 xff0c 但是现在情况有所变化 xff0c 有些Unicode字符需要一个
  • Git命令行简单使用小结

    最近复习了一下git 总结了一下命令行的基本使用 0 基本理论 a 基本概念 Working Directory 就是平时存放项目代码的地方 Stage Index 用于临时存放改动 事实上他只是一个文件 保存即将提交的文件列表信息 Rep
  • 无外接环境下,单笔记本直连浪潮服务器BMC灌装系统

    1 环境因素 xff1a 单服务器无网络无显示器等外接 xff0c 需要对浪潮防火墙灌装系统 xff1b 2 所需材料 xff1a 1 浪潮服务器 2 可接网线笔记本电脑 xff08 Windows平台 xff09 3 网线一根 3 连接拓
  • python抽样方法详解及实现

    抽样方法概览 随机抽样 总体个数较少 每个抽样单元被抽中的概率相同 xff0c 并且可以重现 随机抽样常常用于总体个数较少时 xff0c 它的主要特征是从总体中逐个抽取 1 抽签法 2 随机数法 xff1a 随机数表 随机数骰子或计算机产生