全文共1854字,预计学习时长4分钟
数据科学是研究算法的学科。本文介绍了一些常见的用于处理数据的抽样技术。
图片来源:
unsplash.com/@gndclouds
简单随机抽样
假设要从一个群体中选出一个集合,该集合中的每个成员选中的概率相等。
下列代码演示了如何从数据集中选择100个采样点。
sample_df = df.sample(100)
分层抽样
假设需要估计选举中每个候选人的平均票数。并且假设该国有3个城镇:
A镇有100万名工人,B镇有200万名工人,C镇有300万名退休人员。
在所有选民中抽取60个随机样本,但随机样本有可能不能很好地与这些城镇的特征相适应,因此会产生数据偏差,从而导致估算结果出现重大错误。
相反,如果分别从A,B和C镇抽取10,20和30个随机样本,那么,在相同的样本数的情况下,用该种方法估算的结果误差较小。
使用python可以很容易地做到这一点:
from sklearn.model_selection import train_test_splitX_train, X_test, y_train, y_test = train_test_split(X, y, stratify=y, test_size=0.25)
水塘抽样
假设有未知数量的大项目流,并且只供迭代一次。
数据科学家可以创建一个算法,从项目流中随机选择一个项目以使每个项目抽中的概率相等。
如何实现这一步骤?
假设必须从无限大的项目流中抽取5个对象,这样每个对象被抽中的概率都相等。
import randomdef generator(max):
number = 1
while number < max:
number += 1
yield number
# Create as stream generator
stream = generator(10000)
# Doing Reservoir Sampling from the stream
k=5
reservoir = []
for i, element in enumerate(stream):
if i+1<= k:
reservoir.append(element)
else:
probability = k/(i+1)
if random.random() < probability:
# Select item in stream and remove one of the k items already selected
reservoir[random.choice(range(0,k))] = element
print(reservoir)
------------------------------------
[1369, 4108, 9986, 828, 5589]
从数学上可以证明,在样本中,每个元素从项目流中被抽中的概率相等。
怎么做呢?
涉及到数学时,从小的问题着手总是有用的。
所以,假设要从一个只有3个项目的数据流中抽出其中2个。
由于水塘空间充足,可将项目1放入列表,同理,由于水塘空间仍然充足,可将项目2也放入列表。
再看项目3。事情就变得有趣了,项目3被抽中的概率为2/3.
现在来看看项目1被抽中的概率:
项目1被抽中的概率等于项目3被抽中的概率乘以项目1被随机选为数据流中其他两个项目的候补的概率,即:
2/3*1/2 = 1/3
因此,抽中项目1的概率为:
1–1/3 = 2/3
数据科学家可以对项目2使用完全相同的参数,并且将该参数运用于数据流中的其他更多项目。
因此,每个项目被抽中的概率相同:2/3或一般式k/n
随机欠采样和过采样
事实上,不均衡数据集十分常见。
重抽样是一种广泛用于处理极度不均衡数据集的技术。它指从多数类样本中排除部分样本(欠采样)和/或从少数类样本中添加更多样本(过采样)。
首先,创建一些不均衡数据的示例。
from sklearn.datasets import make_classification
X, y = make_classification(
n_classes=2, class_sep=1.5, weights=[0.9, 0.1],
n_informative=3, n_redundant=1, flip_y=0,
n_features=20, n_clusters_per_class=1,
n_samples=100, random_state=10
)
X = pd.DataFrame(X)
X['target'] = y
现可以使用以下方法进行随机过采样和欠采样:
num_0 = len(X[X['target']==0])num_1 = len(X[X['target']==1])print(num_0,num_1)
# random undersample
undersampled_data = pd.concat([ X[X['target']==0].sample(num_1) , X[X['target']==1] ])
print(len(undersampled_data))
# random oversample
oversampled_data = pd.concat([ X[X['target']==0] , X[X['target']==1].sample(num_0, replace=True) ])
print(len(oversampled_data))
------------------------------------------------------------
OUTPUT:
90 10
20
180
使用Imbalanced-learn进行欠采样和过采样
Imbalanced-learn(imblearn)是一个解决不均衡数据集的Python语言包。
可提供多种方法进行欠采样和过采样。
1. 使用Tomek Links进行欠采样:
Imbalanced-learn提供的方法之一是Tomek Links,指的是在两个不同类的样本中最近邻的对方。
在这个算法中,最终要将多数类样本从Tomek Links中移除,这为分类器提供了一个更好的决策边界。
from imblearn.under_sampling import TomekLinks
tl = TomekLinks(return_indices=True, ratio='majority')
X_tl, y_tl, id_tl = tl.fit_sample(X, y)
2. 使用SMOTE算法进行过采样
SMOTE算法(合成少数类过采样技术),即在已有的样本最近邻中,为少数类样本人工合成新样本。
from imblearn.over_sampling import SMOTE
smote = SMOTE(ratio='minority')
X_sm, y_sm = smote.fit_sample(X, y)
Imblearn包中还有许多其他方法可用于欠采样(Cluster Centroids,NearMiss等)和过采样(ADASYN和bSMOTE)。
结语
算法是数据科学的生命线。
抽样是数据科学中的一个重要课题。一个好的抽样策略有时可以推动整个项目发展。而错误的抽样策略可能会带来错误的结果。因此,应当谨慎选择抽样策略。
留言 点赞 发个朋友圈
我们一起分享AI学习与发展的干货
编译组:张璐瑶、廖琴
相关链接:
https://towardsdatascience.com/the-5-sampling-algorithms-every-data-scientist-need-to-know-43c7bc11d17c
如需转载,请后台留言,遵守转载规范
推荐文章阅读
长按识别二维码可添加关注
读芯君爱你
转载自原文链接, 如需删除请联系管理员。
原文链接:海量样本无从下手?这五种抽样算法分分钟搞定,转载请注明来源!