二进制样本/不样本可能不是正确的答案..假设您要采样 1000 个字符串,并且通过抛硬币来进行..这意味着大约在访问 2000 个字符串之后..您将完成.. 那怎么样其余的字符串?
我读了这篇文章 - http://gregable.com/2007/10/reservoir-sampling.html
这很清楚地回答了这个问题..
让我把摘要放在这里-
简单的解决方案
为您在流中看到的每个元素分配一个随机数,然后始终保留前 1,000 个编号的元素。
油藏取样
创建一个包含 1,000 个元素的容器(数组),并用流中的前 1,000 个元素填充它。从 i = 1,001 开始。在第 1001 步之后,元素 1,001(或与此相关的任何元素)应该在 1,000 个元素的集合中的概率是多少?答案很简单:1,000/1,001。因此,生成一个介于 0 和 1 之间的随机数,如果它小于 1,000/1,001,则应取元素 1,001。如果您选择添加它,则替换随机选择的水库中的任何元素(例如元素 #2)。元素#2 在第 1,000 步时肯定在水库中,它被移除的概率是元素 1,001 被选中的概率乘以 #2 被随机选为替换候选者的概率。该概率为 1,000/1,001 * 1/1,000 = 1/1,001。所以,
这可以扩展到第 i 轮 - 以 1,000/i 的概率保留第 i 个元素,如果您选择保留它,请从水库中替换一个随机元素。此步骤之前的任何元素在储层中的概率为 1,000/(i-1)。它们被移除的概率是 1,000/i * 1/1,000 = 1/i。考虑到它们已经在水库中,每个元素保留的概率是 (i-1)/i,因此在 i 轮后元素在水库中的总体概率是 1,000/(i-1) * (i- 1)/i = 1,000/i。