算法是数据科学的核心,而采样是决定项目成败的关键技术。了解有关使用的最常见采样技术的更多信息,因此您可以在处理数据时选择最佳方法。
数据科学是对算法的研究。
简单随机抽样
假设您要选择总体中的一个子集,其中子集的每个成员都有被选择的相同概率。
下面我们从数据集中选择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_split
X_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))] = elementprint(reservoir)
------------------------------------
[1369, 4108, 9986, 828, 5589]
从数学上可以证明,在样本中,每个元素都具有从流中选择的相同概率。
怎么样?
在数学方面,总是想起一个较小的问题。
因此,让我们考虑只有3个项目的流,我们必须保留其中2个项目。
我们看到第一项,并且由于水库有空间,因此将其保留在列表中。我们看到第二项,并且由于水库有空间,因此将其保留在列表中。
我们看到第三项。这是事情变得有趣的地方。我们选择第二项以2/3的概率出现在列表中。
现在让我们看看选择第一项的可能性:
删除第一项的概率是元素3被选择的概率乘以元素1从储层中的2个元素中随机选择作为替换候选者的概率。该概率为:
2/3 * 1/2 = 1/3
因此,选择1的概率为:
1–1 / 3 = 2/3
对于第二元素,我们可以有完全相同的参数,并且可以将其扩展为许多元素。
因此,每个项目都具有相同的被选择概率:2/3或通常为 k / n。
随机欠采样和过采样
我们经常遇到不平衡的数据集。
处理高度不平衡的数据集的一种广泛采用的技术称为重采样。它包括从多数类中删除样本(欠采样)和/或从少数类中添加更多示例(过采样)。
让我们首先创建一些不平衡数据示例。
from sklearn.datasets import make_classificationX, 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 undersampleundersampled_data = pd.concat([ X[X['target']==0].sample(num_1) , X[X['target']==1] ])
print(len(undersampled_data))# random oversampleoversampled_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
使用不平衡学习的欠采样和过采样
Python软件包不平衡学习(imblearn)解决了不平衡数据集的问题。
它提供了多种方法来进行欠采样和过采样。
a.使用Tomek链接进行欠采样:
它提供的一种这样的方法称为Tomek Links。Tomek链接是成对的相近类别的对示例。
在该算法中,我们最终从Tomek链接中删除了多数元素,这为分类器提供了更好的决策边界。
from imblearn.under_sampling import TomekLinks
tl = TomekLinks(return_indices=True, ratio='majority')
X_tl, y_tl, id_tl = tl.fit_sample(X, y)
b.使用SMOTE进行过采样:
在SMOTE(综合少数族裔过采样技术)中,我们在已经存在的元素附近合成少数族裔的元素。
from imblearn.over_sampling import SMOTE
smote = SMOTE(ratio='minority')
X_sm, y_sm = smote.fit_sample(X, y)
imblearn 程序包中还有许多其他方法可 用于欠采样(集群质心,NearMiss等)和过采样(ADASYN和bSMOTE)。(https://github.com/scikit-learn-contrib/imbalanced-learn#id3)
结论
算法 是数据科学的命脉。
采样是数据科学中的一个重要主题,我们实际上并没有如我们所愿地谈论它。
好的抽样策略有时可以使整个项目向前发展。错误的采样策略可能会给我们错误的结果。因此,在选择抽样策略时应格外小心。