我对水库采样算法非常熟悉,我在考虑如果给出总大小N
会怎么样。在这种情况下我们可以获得什么好处?结果,这是算法:
Let n be the total size of data
Let k be the total size of sample
for each element from data
if random(0,1) <= k/n
put this element into sample
-- k
-- n
done
乍一看看起来不对,但我发现很难证明。任何人都可以帮我以正式的方式证明这个算法吗?
答案 0 :(得分:1)
这是Dave's fix的正确性证明。假设该流是1..n
而不失一般性。我们归纳证明,在循环m in {0..n}
次迭代之后,样本被分布为与1..m
的{{1}}的交集,k
的组合。
基本情况1..n
很简单:样本和交集都是空的。鉴于特定m = 0
的归纳假设,我们现在为m
证明了这一假设。设m+1
为表示S
次迭代后的集合的随机变量,让m
为表示S'
次迭代后的集合的随机变量。让m+1
设置为交集。对于所有&
- 组合k
,我们写
T
因为Pr(S' = T & {1..m+1})
= Pr(S = T & {1..m}) Pr(S' = T & {1..m+1} | S = T & {1..m}),
意味着S' = T & {1..m+1}
。通过归纳假设和一些计数,
S = T & {1..m}
结合这两个方程式,得到
(n choose k) Pr(S = T & {1..m})
= ((n - m) choose (k - |T & {1..m}|)).
通过检查戴夫的计划,
(n choose k) Pr(S' = T & {1..m+1})
= ((n - m) choose (k - |T & {1..m}|)) Pr(S' = T & {1..m+1} | S = T & {1..m}).
现在有两种情况。第一种情况是Pr(m+1 in S' | S) = (k - |S|) / (n - m).
。
m+1 in T
第二种情况是Pr(S' = T & {1..m+1} | S = T & {1..m})
= Pr(m+1 in S' | S = T & {1..m})
= (k - |T & {1..m}|) / (n - m)
(n choose k) Pr(S' = T & {1..m+1})
= ((n - m) choose (k - |T & {1..m}|)) (k - |T & {1..m}|) / (n - m)
= (n - m - 1) choose (k - |T & {1..m}| - 1)
= (n - (m+1)) choose (k - |T & {1..m+1}|).
。
m+1 not in T
在这两种情况下,我们都证明Pr(S' = T & {1..m+1} | S = T & {1..m})
= Pr(m+1 not in S' | S = T & {1..m})
= (n - m - (k - |T & {1..m}|)) / (n - m)
(n choose k) Pr(S' = T & {1..m+1})
= ((n - m) choose (k - |T & {1..m}|)) (n - m - (k - |T & {1..m}|)) / (n - m)
= (n - m - 1) choose (k - |T & {1..m}|)
= (n - (m+1)) choose (k - |T & {1..m+1}|).
具有正确的值。
答案 1 :(得分:0)
如果您想要准确的K个样本:设K是所需的样本,k是到目前为止获得的样本。设N是数据的总大小,n是到目前为止采样的集合。然后检查是否随机(0,1)&lt; =(K-k)/(N-n)。
您还可以获取流的每个(N / K)'元素,或将您的流划分为K个子流,并从每个子流中随机取一个元素。