隨機取樣 蓄水池問題

2022-08-05 02:27:25 字數 1544 閱讀 5939

看了多篇講解蓄水池問題的文章,感覺下面**的這一篇是證明最為嚴謹的。

如何在事先不知道文字檔案行數n的情況下讀取該檔案,從中隨機選擇並輸出一行?

(事先不知道n的大小,但是一次可以看到這n個物件)

即蓄水池抽樣(reservoir sampling)問題

證明如下:

問題: 證明當前任意一行為取出行的概率為1/i,i為當前掃瞄到的行號,也即每一行取出的概率相等

我們用數學歸納法來證明,

當i=1時,當前只瀏覽了第一行,因此第一行為取出行的概率為1/1=1,符合直接取出的條件

當i=k時,有前k行為取出行的概率為1/k,我們要證明的是,當i=k+1時,前k+1行每一行被取出的概率均相等,且為1/(k+1)。當掃瞄到第k+1行時,我們以1/(k+1)概率替換choice,易知,第k+1行為choice的概率即為1/(k+1),對於第k行,其為choice的概率是 第k行為取出行的概率 * 第k+1行沒有被取出的概率即,

對於第k行的證明同樣可應用到前k-1行,對於其中第m行其為choice的概率是 第m行為取出行的概率 * 第m+1行沒有被取出的概率 * … *第k+1行沒有被取出的概率,即

由此證得當i=k+1時,所有行的取出概率為1/(k+1)。證畢。

可以對其進行擴充套件,即如何從未知或者很大樣本空間隨機地取k個數?模擬下即可得到答案,即先把前k個數放入蓄水池,對第k+1,我們以k/(k+1)概率決定是否要把它換入蓄水池,換入時隨機的選取乙個作為替換項,這樣一直做下去,對於任意的樣本空間n,對每個數的選取概率都為k/n。也就是說對每個數選取概率相等。

證明我們仍然使用數學歸納法:

問題,證明對於任意樣本號n,n>=k,每個樣本作為取出樣本的概率相等,即k/n。

證明:

當n=k時,由我們把前k個數放入蓄水池可知,每個樣本的取出概率均相等,即k/k=1。   設當前樣本號為n,其每個取出樣本概率均相等,即為k/n,我們要證明的是這種情況對於n+1也成立。

由於我們以k/(n+1)決定是否把n+1放入蓄水池,那麼對於n+1其出現在蓄水池中的概率就是k/(n+1),對於前n個元素中的任意元素m(k+1<=m<=n),其出現在蓄水池中的概率為 m出現在蓄水池中的概率 * [(m+1被選中的概率*m沒被m+1替換的概率 + m+1沒被選中的概率)*(m+2被選中的概率*m沒被m+2替換的概率 + m+2沒被選中的概率)*…*(n+1被選中的概率*m沒被n+1替換的概率 + n+1沒被選中的概率)],即

可見,對於n+1每個樣本取出概率也相等,即為k/(n+1)。證畢。

其偽**如下:

init : a reservoir with the size: k  

fori= k+1 to n  

m=random(1, i);  

if( m 

swap the mth value and ith value  

end 

for

個人總結:如果在知道n的大小情況下,我們可以從[1、n]中隨機選擇乙個數作為選擇物件。但是現在不知道n的大小,要使每乙個元素被取的概率相等(隨機)。

蓄水池取樣

問題描述 現實生活中有很多流式資料,在流式資料上取樣可以抽象為 設幾個中元素個數為n,並且n在不斷的增大,如何在集合中採集k個樣本,使得每個樣本被採集到的概率相等 k n 蓄水池抽樣法 演算法思路是,先構造乙個可以放k個元素的池子,池子中一開始放元素1 k。對於k 1 n 以k n的概率決定是否被替...

蓄水池取樣

現在有一組數,不知道這組數的總量有多少,請描述一種演算法能夠在這組資料中隨機抽取k個數,使得每個數被取出來的概率相等。如果這組數有n個,那麼每個數字取到的概率就是k n,但是這個問題的難點在於不知道這組數的總數,也就是不知道n,那麼該怎麼計算每個數取到的概率呢 用python實現一下蓄水池演算法,由...

蓄水池問題

蓄水池問題描述 假設有n個數,從中隨機抽取k個數字,如果保證抽取的過程是等概率的?其中n是不固定的 類似問題 1.從100個數字抽取20個,如果向100個數字中再增加20個呢?2.給你乙個長度為n的鍊錶,n很大,但你不知道n有多大,你的任務是從這n個元素中取出k個元素,你只能遍歷一次這個鍊錶,演算法...