迭代或惰性储层采样

时间:2014-06-11 21:15:03

标签: python algorithm random-sample

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

在整个序列评估之前,有没有办法能够产生一些随机结果?我正在考虑那种适合python的伟大itertools库的懒惰方法。也许这可以在一些给定的容错范围内完成?我很欣赏有关这个想法的任何反馈!

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

enter image description here

显然,由于我们很可能会将样本偏向人口的起点,因此不知道先验的长度并且仍然得到统一的样本,这似乎存在矛盾。有没有办法量化这种偏见?是否需要权衡利弊?有没有人有一个聪明的算法来解决这个问题?

2 个答案:

答案 0 :(得分:6)

如果事先知道可迭代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或大多数储层采样代码),因此样本的一部分将不是随机子样本! / p>

答案 1 :(得分:0)

如果预先知道种群大小,你不能只生成sample_size随机“索引”(在流中)并使用它来做一个懒惰的产量吗?您不必阅读整个流。

例如,如果population_size为100,且sample_size为3,则生成一组从1到100的随机整数,比如说得到10,67和72。

现在你产生流的第10,62和72个元素并忽略其余元素。

我想我不明白这个问题。