問題描述:
現實生活中有很多流式資料,在流式資料上取樣可以抽象為:
設幾個中元素個數為n,並且n在不斷的增大,如何在集合中採集k個樣本,使得每個樣本被採集到的概率相等(k/n)?
蓄水池抽樣法:
演算法思路是,先構造乙個可以放k個元素的池子,池子中一開始放元素1~k。
對於k+1~n 以k/n的概率決定是否被替換到池子中,遍歷完所有元素後就可以得到乙個等概率取樣的k個元素,時間複雜度是o(n);
偽**:
init : a reservoir with the size: k
for i= k+1 to n
m=random(1, i);
if( m <= k)
swap the mth value and ith value
end for
證明:
對小於等於k的元素,第一次被選中的概率是1,最後留在池子中的概率=它第一次被選中的概率 * 以後面它不被替換的概率:
第一次隨機的時候它被替換走的概率是 1/k+1 ,所以不被替換走的概率是 k/k+1 ,
第二次隨機的時候它不被替換走的概率是 k+1/k+2 .....
所以最後留在池子中的概率是 : 1* (k/(k+1))*((k+1)/(k+2)).....(n-1)/n = k/n
對於大於k的元素j,被選中的概率是 k/j,後面不被替換的概率是 j/j+1 j+1/j+2 ......n-1/n
所以最後留在池子中的概率是: k/j*(j/j+1).......(n-1)/n = k/n
全部都是等概率的
蓄水池取樣
現在有一組數,不知道這組數的總量有多少,請描述一種演算法能夠在這組資料中隨機抽取k個數,使得每個數被取出來的概率相等。如果這組數有n個,那麼每個數字取到的概率就是k n,但是這個問題的難點在於不知道這組數的總數,也就是不知道n,那麼該怎麼計算每個數取到的概率呢 用python實現一下蓄水池演算法,由...
隨機取樣 蓄水池問題
看了多篇講解蓄水池問題的文章,感覺下面 的這一篇是證明最為嚴謹的。如何在事先不知道文字檔案行數n的情況下讀取該檔案,從中隨機選擇並輸出一行?事先不知道n的大小,但是一次可以看到這n個物件 即蓄水池抽樣 reservoir sampling 問題 證明如下 問題 證明當前任意一行為取出行的概率為1 i...
蓄水池問題
蓄水池問題描述 假設有n個數,從中隨機抽取k個數字,如果保證抽取的過程是等概率的?其中n是不固定的 類似問題 1.從100個數字抽取20個,如果向100個數字中再增加20個呢?2.給你乙個長度為n的鍊錶,n很大,但你不知道n有多大,你的任務是從這n個元素中取出k個元素,你只能遍歷一次這個鍊錶,演算法...