***
現在有一組數,不知道這組數的總量有多少,請描述一種演算法能夠在這組資料中隨機抽取k個數,使得每個數被取出來的概率相等。如果這組數有n個,那麼每個數字取到的概率就是k/n,但是這個問題的難點在於不知道這組數的總數,也就是不知道n,那麼該怎麼計算每個數取到的概率呢
用python實現一下蓄水池演算法,由於蓄水池演算法是在事先不知道總量的情況下抽樣的,所以定義乙個方法來接收單個元素,並且把這個方法放在類中,以持有取樣後的資料。
import random
class
reservoirsample
(object):
def__init__
(self, size)
: self._size = size
self._counter =
0 self._sample =
deffeed
(self, item)
: self._counter +=
1# 第i個元素(i <= k),直接進入池中
iflen
(self._sample)
< self._size:
# 引用傳遞
return self._sample
# 第i個元素(i > k),以k / i的概率進入池中
rand_int = random.randint(
1, self._counter)
if rand_int <= self._size:
self._sample[rand_int -1]
= item
return self._sample
測試**
接下來實現乙個測試用例驗證實現的演算法是否正確,既然是隨機抽樣,無法通過單詞測試來驗證是否正確,所以通過多次執行的方式來驗證,比如從1-10裡隨機取樣3個數,然後執行10000次取樣,如果演算法正確,最後結果中1-10被取樣的次數應該是相同的,都是3000上下。
import unittest
from collections import counter
from reservoir_sample import reservoirsample
class
testmain
(unittest.testcase)
:def
test_reservoir_sample
(self)
: samples =
for i in
range
(10000):
sample =
rs = reservoirsample(3)
for item in
range(1
,11):
sample = rs.feed(item)
samples.extend(sample)
r = counter(samples)
print
(r)if __name__ ==
'__main__'
: unittest.main(
)
蓄水池取樣
問題描述 現實生活中有很多流式資料,在流式資料上取樣可以抽象為 設幾個中元素個數為n,並且n在不斷的增大,如何在集合中採集k個樣本,使得每個樣本被採集到的概率相等 k n 蓄水池抽樣法 演算法思路是,先構造乙個可以放k個元素的池子,池子中一開始放元素1 k。對於k 1 n 以k n的概率決定是否被替...
隨機取樣 蓄水池問題
看了多篇講解蓄水池問題的文章,感覺下面 的這一篇是證明最為嚴謹的。如何在事先不知道文字檔案行數n的情況下讀取該檔案,從中隨機選擇並輸出一行?事先不知道n的大小,但是一次可以看到這n個物件 即蓄水池抽樣 reservoir sampling 問題 證明如下 問題 證明當前任意一行為取出行的概率為1 i...
蓄水池問題
蓄水池問題描述 假設有n個數,從中隨機抽取k個數字,如果保證抽取的過程是等概率的?其中n是不固定的 類似問題 1.從100個數字抽取20個,如果向100個數字中再增加20個呢?2.給你乙個長度為n的鍊錶,n很大,但你不知道n有多大,你的任務是從這n個元素中取出k個元素,你只能遍歷一次這個鍊錶,演算法...