【发布时间】:2014-08-02 02:05:42
【问题描述】:
我非常熟悉使用 Reservoir Sampling 在单次遍历数据中从一组未确定的长度中进行采样。在我看来,这种方法的一个限制是,在返回任何结果之前,它仍然需要遍历整个数据集。从概念上讲,这是有道理的,因为必须允许整个序列中的项目有机会替换以前遇到的项目以实现统一的样本。
有没有办法在整个序列被评估之前产生一些随机结果?我正在考虑一种适合 python 的伟大 itertools 库的惰性方法。也许这可以在某些给定的容错范围内完成?如有任何关于此想法的反馈,我将不胜感激!
为了稍微澄清一下这个问题,这张图总结了我对不同采样技术的内存与流式权衡的理解。我想要的是属于 Stream Sampling 类别的东西,我们事先不知道人口的长度。
显然,不知道先验长度并仍然获得统一样本似乎是矛盾的,因为我们很可能会将样本偏向于总体的开始。有没有办法量化这种偏见?是否需要权衡取舍?有人有聪明的算法来解决这个问题吗?
【问题讨论】:
-
您可以这样做,但这样做会失去生成某些序列的能力。例如,如果您想从列表中随机选择 10 件商品,但您对一件或多件商品进行了某种类型的提前退货,那么您的样本将永远不会包含列表中的最后 10 件商品。如果您可以对输出进行偏置,那么您可以提前返回。否则,您必须等到检查完整个列表。
-
实现水库采样会更有意义,以便它始终迭代其整个可迭代对象。如果调用者想要一个更快的结果而不迭代其整个可迭代对象,它可以传入截断的可迭代对象本身。产生可迭代的储层没有多大意义,因为连续的储层高度相关(它们在 0 或 1 个位置上不同)。
-
@TimothyShields 我同意 API 设计方面的看法,人们会并且应该期望储层样本具有这种行为方式。我在这里寻找的是某种类似的统计上的聪明才智,它可以让我们提前归还物品,或者一些很好的论据,说明为什么这根本不可能。
-
@Stankalank 出于什么目的提前退货?请参阅我之前评论中的最后一句话。
-
@TimothyShields 假设我们有一个大小为 100 的群体,我们想要一个大小为 15 的样本。人们可以很容易地设计一种算法,将群体保存在内存中并从样本中流式传输(迭代地产生)项目.或者,如果我们要使用水库采样,我们会将样本保存在内存中并流式传输总体。我想要一种同时传输人口和样本的方法。 ALA 此图:littleml.files.wordpress.com/2013/01/memory.png
标签: python algorithm random reservoir-sampling