8

我非常熟悉使用 Reservoir Sampling 在单次遍历数据中从一组未确定的长度中进行采样。在我看来,这种方法的一个限制是,在返回任何结果之前,它仍然需要遍历整个数据集。从概念上讲,这是有道理的,因为必须允许整个序列中的项目有机会替换以前遇到的项目以实现统一的样本。

有没有办法在评估整个序列之前产生一些随机结果?我正在考虑一种适合 python 的伟大 itertools 库的惰性方法。也许这可以在某些给定的容错范围内完成?我将不胜感激有关此想法的任何反馈!

只是为了稍微澄清一下这个问题,这张图总结了我对不同采样技术的内存与流式权衡的理解。我想要的是属于Stream Sampling类别的东西,我们事先不知道人口的长度。

在此处输入图像描述

显然,不知道先验长度并仍然获得统一样本似乎是矛盾的,因为我们很可能会将样本偏向于总体的开始。有没有办法量化这种偏见?是否需要权衡取舍?有没有人有一个聪明的算法来解决这个问题?

4

2 回答 2

7

如果您事先知道 iterable 将产生的项目总数population,则可以在您找到它们时产生一个样本的项目population(不仅在到达末尾之后)。如果您不提前知道总体规模,这是不可能的(因为无法计算样本中任何项目的概率)。

这是一个执行此操作的快速生成器:

def sample_given_size(population, population_size, sample_size):
    for item in population:
        if random.random() < sample_size / population_size:
            yield item
            sample_size -= 1
        population_size -= 1

请注意,生成器按照它们在总体中出现的顺序生成项目(不是随机顺序,就像random.sample或大多数水库采样代码一样),因此样本的一部分不会是随机子样本!

于 2014-06-11T23:26:40.840 回答
0

如果事先知道人口规模,你不能只生成 sample_size 随机“索引”(在流中)并用它来做一个惰性产量吗?您不必阅读整个流。

例如,如果 population_size 为 100,sample_size 为 3,则生成一个从 1 到 100 的随机整数集,例如得到 10、67 和 72。

现在您生成流的第 10、62 和 72 个元素并忽略其余元素。

我想我不明白这个问题。

于 2014-06-12T04:32:44.527 回答