海量样本无从下手?五种抽样算法分分钟搞定

大数据 数据分析 算法
数据科学是研究算法的学科。本文介绍了一些常见的用于处理数据的抽样技术。

数据科学是研究算法的学科。本文介绍了一些常见的用于处理数据的抽样技术。

[[274956]]

1. 简单随机抽样

假设要从一个群体中选出一个集合,该集合中的每个成员选中的概率相等。

下列代码演示了如何从数据集中选择100个采样点。

  1. sample_df = df.sample(100) 

2. 分层抽样

[[274957]]

假设需要估计选举中每个候选人的平均票数。并且假设该国有3个城镇:

A镇有100万名工人,B镇有200万名工人,C镇有300万名退休人员。

在所有选民中抽取60个随机样本,但随机样本有可能不能很好地与这些城镇的特征相适应,因此会产生数据偏差,从而导致估算结果出现重大错误。

相反,如果分别从A,B和C镇抽取10,20和30个随机样本,那么,在相同的样本数的情况下,用该种方法估算的结果误差较小。

使用python可以很容易地做到这一点:

  1. from sklearn.model_selection import train_test_split 
  2. X_train, X_test, y_train, y_test = train_test_split(X, y, 
  3.                                                     stratify=y,  
  4.                                                     test_size=0.25) 

3. 水塘抽样

[[274958]]

假设有未知数量的大项目流,并且只供迭代一次。数据科学家可以创建一个算法,从项目流中随机选择一个项目以使每个项目抽中的概率相等。如何实现这一步骤?

假设必须从无限大的项目流中抽取5个对象,这样每个对象被抽中的概率都相等。

  1. import randomdef generator(max): 
  2.  
  3.     number = 1 
  4.     while number < max: 
  5.         number += 1 
  6.         yield number 
  7.  
  8. # Create as stream generator 
  9. stream = generator(10000) 
  10.  
  11. # Doing Reservoir Sampling from the stream 
  12. k=5 
  13. reservoir = [] 
  14. for i, element in enumerate(stream): 
  15.     if i+1<= k: 
  16.         reservoir.append(element) 
  17.     else: 
  18.         probability = k/(i+1) 
  19.         if random.random() < probability: 
  20.             # Select item in stream and remove one of the k items already selected 
  21.              reservoir[random.choice(range(0,k))] = element 
  22.  
  23. print(reservoir) 
  24. ------------------------------------ 
  25. [1369, 4108, 9986, 828, 5589] 

从数学上可以证明,在样本中,每个元素从项目流中被抽中的概率相等。

怎么做呢?

涉及到数学时,从小的问题着手总是有用的。

所以,假设要从一个只有3个项目的数据流中抽出其中2个。

由于水塘空间充足,可将项目1放入列表,同理,由于水塘空间仍然充足,可将项目2也放入列表。

再看项目3。事情就变得有趣了,项目3被抽中的概率为2/3.

现在来看看项目1被抽中的概率:

项目1被抽中的概率等于项目3被抽中的概率乘以项目1被随机选为数据流中其他两个项目的候补的概率,即:

  1. 2/3*1/2 = 1/3 

因此,抽中项目1的概率为:

  1. 1–1/3 = 2/3 

数据科学家可以对项目2使用完全相同的参数,并且将该参数运用于数据流中的其他更多项目。

因此,每个项目被抽中的概率相同:2/3或一般式k/n

4. 随机欠采样和过采样

事实上,不均衡数据集十分常见。

重抽样是一种广泛用于处理极度不均衡数据集的技术。它指从多数类样本中排除部分样本(欠采样)和/或从少数类样本中添加更多样本(过采样)。

首先,创建一些不均衡数据的示例。

  1. from sklearn.datasets import make_classification 
  2.  
  3. X, y = make_classification
  4.     n_classes=2class_sep=1.5, weights=[0.9, 0.1], 
  5.     n_informative=3n_redundant=1flip_y=0
  6.     n_features=20n_clusters_per_class=1
  7.     n_samples=100random_state=10 
  8.  
  9. X = pd.DataFrame(X) 
  10. X['target'] = y 

现可以使用以下方法进行随机过采样和欠采样:

  1. num_0 = len(X[X['target']==0]) 
  2. num_1 = len(X[X['target']==1]) 
  3. print(num_0,num_1) 
  4.  
  5. # random undersample 
  6.  
  7. undersampled_data = pd.concat([ X[X['target']==0].sample(num_1) , X[X['target']==1] ]) 
  8. print(len(undersampled_data)) 
  9.  
  10. # random oversample 
  11.  
  12. oversampled_data = pd.concat([ X[X['target']==0] , X[X['target']==1].sample(num_0, replace=True) ]) 
  13. print(len(oversampled_data)) 
  14.  
  15. ------------------------------------------------------------ 
  16. OUTPUT: 
  17. 90 10 
  18. 20 
  19. 180 

5. 使用Imbalanced-learn进行欠采样和过采样

Imbalanced-learn(imblearn)是一个解决不均衡数据集的Python语言包。

可提供多种方法进行欠采样和过采样。

(1) 使用Tomek Links进行欠采样:

Imbalanced-learn提供的方法之一是Tomek Links,指的是在两个不同类的样本中最近邻的对方。

在这个算法中,最终要将多数类样本从Tomek Links中移除,这为分类器提供了一个更好的决策边界。

  1. from imblearn.under_sampling import TomekLinks 
  2.  
  3. tl = TomekLinks(return_indices=Trueratio='majority'
  4. X_tl, y_tl, id_tl = tl.fit_sample(X, y) 

(2) 使用SMOTE算法进行过采样

SMOTE算法(合成少数类过采样技术),即在已有的样本最近邻中,为少数类样本人工合成新样本。

  1. from imblearn.over_sampling import SMOTE 
  2.  
  3. smote = SMOTE(ratio='minority'
  4. X_sm, y_sm = smote.fit_sample(X, y) 

Imblearn包中还有许多其他方法可用于欠采样(Cluster Centroids,NearMiss等)和过采样(ADASYN和bSMOTE)。

结语

算法是数据科学的生命线。

抽样是数据科学中的一个重要课题。一个好的抽样策略有时可以推动整个项目发展。而错误的抽样策略可能会带来错误的结果。因此,应当谨慎选择抽样策略。

 

责任编辑:赵宁宁 来源: 读芯术
相关推荐

2018-06-14 09:53:07

移动端优化苏宁

2016-01-22 11:40:07

2024-07-15 09:08:51

源码debug根节点

2010-09-06 11:32:48

无线上网设置

2012-03-16 17:19:28

2022-12-13 10:05:27

定时任务任务调度操作系统

2015-03-05 10:43:24

阿里云Azure迁移

2022-08-12 10:41:57

接口性能优化

2010-08-25 09:46:05

无线网络访问故障

2010-09-09 10:11:11

无线网络故障

2021-03-23 09:06:34

下载神器文件下载插件

2011-08-22 12:24:58

nagios

2021-07-08 06:30:03

Linux CPULinux 系统

2017-04-13 12:59:43

数据分析

2010-08-31 10:22:20

无线网络访问故障

2020-06-08 09:11:47

Linux 内核Linux内核

2021-10-20 20:24:53

办公

2020-02-15 16:48:28

机器学习算法人工智能

2011-08-16 09:55:37

Juniper Ex系

2010-04-15 15:32:59

Oracle操作日志
点赞
收藏

51CTO技术栈公众号