海量資料中隨機抽查K個樣本 演算法

2021-05-26 07:48:15 字數 1523 閱讀 2021

現在做爬蟲階段的資料分析,需要針對每乙個站點隨機抽檢k個url,那麼,如何從巨大數量的url中做到隨機抽檢呢?url的總數是不知道的,當然你可以掃瞄兩次,第一次得到url總是,但是,有更好的做法。

(哈哈,我要無恥的說 原創 **標籤不好看 :))

以下引用來自:

要求從n個元素中隨機的抽取k個元素,其中n無法確定。

是在 《計算機程式設計與藝術》 中看到的這個題目,書中只給出了解法,沒給出證明。

解決方法是叫reservoir sampling (蓄水池抽樣)

init: a reservoir with the size: k

fori= k+1ton

m=random(1, i);

if( m < k)

swapthe mth valueandith value

end for

證明:每次都是以 k/i 的概率來選擇

例: k=1000的話, 從1001開始作選擇,1001被選中的概率是1000/1001,1002被選中的概率是1000/1002,與我們直覺是相符的。

接下來證明:

假設當前是i+1, 按照我們的規定,i+1這個元素被選中的概率是k/i+1,也即第 i+1 這個元素在蓄水池中出現的概率是k/i+1

此時考慮前i個元素,如果前i個元素出現在蓄水池中的概率都是k/i+1的話,說明我們的演算法是沒有問題的。

對這個問題可以用歸納法來證明:k < i <=n

1.當i=k+1的時候,蓄水池的容量為k,第k+1個元素被選擇的概率明顯為k/(k+1), 此時前k個元素出現在蓄水池的概率為 k/(k+1), 很明顯結論成立。

2.假設當 j=i 的時候結論成立,此時以 k/i 的概率來選擇第i個元素,前i-1個元素出現在蓄水池的概率都為k/i。  

證明當j=i+1的情況:

即需要證明當以 k/i+1 的概率來選擇第i+1個元素的時候,此時任一前i個元素出現在蓄水池的概率都為k/(i+1).

前i個元素出現在蓄水池的概率有2部分組成, ①在第i+1次選擇前得出現在蓄水池中,②得保證第i+1次選擇的時候不被替換掉

①.由2知道在第i+1次選擇前,任一前i個元素出現在蓄水池的概率都為k/i

②.考慮被替換的概率:  

首先要被替換得第 i+1 個元素被選中(不然不用替換了)概率為 k/i+1,其次是因為隨機替換的池子中k個元素中任意乙個,所以不幸被替換的概率是 1/k,故

前i個元素中任一被替換的概率 = k/(i+1) * 1/k = 1/i+1

則沒有被替換的概率為:   1 - 1/(i+1) = i/i+1

綜合① ②,通過乘法規則

得到前i個元素出現在蓄水池的概率為 k/i * i/(i+1) = k/i+1

故證明成立

看著以前如此遙遠的演算法應用到專案中,感覺不一樣呀,公司面試狂面演算法還是有道理的:)

海量資料中隨機抽查K個樣本 演算法

現在做爬蟲階段的資料分析,需要針對每乙個站點隨機抽檢k個url,那麼,如何從巨大數量的url中做到隨機抽檢呢?url的總數是不知道的,當然你可以掃瞄兩次,第一次得到url總是,但是,有更好的做法。哈哈,我要無恥的說 原創 標籤不好看 以下引用來自 要求從n個元素中隨機的抽取k個元素,其中n無法確定。...

如何在海量資料中查詢最相似的topk樣本

大概總結3中方法,不一定對,歡迎 1 還記得knn演算法吧,選擇最近的k個樣本作為 輸出 其中減少計算量的地方在於使用了kd樹,使得查詢非常高效 先計算每個特徵的方差,降序排序構建二叉樹 對當前特徵排序,取中位數作為 節點,把資料劃分成2部分 對左右部分遞迴處理 搜尋最近鄰點 沿著路徑搜尋即可 當維...

堆 heap 從海量資料中尋找最大的k個值

1 目的 獲取大量元素 topk 大個元素,固定記憶體 2 思路 1 先放入元素前 k 個建立乙個最小堆 2 迭代剩餘元素 a 如果當前元素小於堆頂元素,跳過該元素 肯定不是前 k 大 b 否則替換堆頂元素為當前元素,並重新調整。3 示例 import heapq class topk 獲取大量元素...