1. 程式人生 > >基數估計演算法(一):Flajolet-Martin演算法

基數估計演算法(一):Flajolet-Martin演算法

簡介

說起基數估計演算法的始祖,或許就是由Flajolet和Martin大佬發表的論文《 Probabilistic counting algorithms for data base applications 》開始的吧。他們提出在大資料中基於概率來估計基數的演算法,江湖人稱 FM-sketch演算法。

基礎版

首先定義一個hash函式:
function hash(x): -> [0,1,2,...,2L1],該函式能將元素均勻地對映到該區間內。

再定義bit函式:
bit(y, k) 表示 y的二進位制表示第k個bit數值(0或1).
y

=k0bit(y,k)2k.

定義tail(y)表示y的二進位制表示中末尾出現第一個1的位置(從0開始計數),即連續0的個數:
tail(y)={minbit(y,k)0,L,if y>0if y=0

定義BITMAP[0…L-1]陣列,BITMAP[i] 表示在可重複集合M中有一個數經過hash後呈現...10i,即該hash值的二進位制表示中末尾有連續i個0.
具體BITMAP的計算如下:

for i :=0 to L- 1 do BITMAP[i] :=O;
for all x in M do
    begin
    index := tail(hash(x));
    if
BITMAP[index] = 0 then BITMAP[index] := 1; end;

好了定義了這麼多,重點來了!
如果M中的基數為n,按照概率,BITMAP[0]大約有n2次會被訪問到(想一下一半是奇數一半是偶數),同理BITMAP[1]大約有n22次被訪問到… 因此BITMAP[i]大約有n2i次被訪問到。
可以得出結論,當ilog2n時,BITMAP[i]幾乎沒被訪問過,即BITMAP[i]幾乎確定為0;相反的,如果ilog2n時,BITMAP[i]很大概率上為1。
設BITMAP裡最左邊的0的位置為R,因此我們可以用R來近似log2n
比如一個24bits(L=24)的BITMAP如下:
111111111111001100000000
則左邊的0出現的位置為12,即R=12.

在確保hash值是均勻分佈的條件下,R的數學期望值為:
E(R)log2φn,φ=0.77351...
可以證明R的方差為:σ(R)1.12。估計值偏離準確值。

標準版

很明顯,在上述介紹的方法中,估計值很不精確。
因此實際中,為了減小誤差提高精度,通常會採用多組hash方法。
具體可以利用m組不同的hash方法,生成m個BITMAP,然後對每個BITMAP採用同樣的方法計算出對應的R值,然後求平均。
有: R=R1+R2+...+Rmm
E(R)log2φn;

更進一步,還可以設計A組hash函式,其中每組B個hash函式,這些hash函式各不相同且對映結果均勻分佈。然後利用每組中的B個雜湊函式計算出B個估計值,求出B個估計值的算術平均數作為該組的估計值;最後將所有組的結果進行排序,取中位數作為最終的輸出結果。
顯然這種做法精度會進一步提高。

但是,這種做法卻有些缺點。首先要設計這麼多個不同且hash結果分佈均勻的hash函式是困難的,其次這麼做顯然既耗時也耗空間。

顯然F和M兩位大佬看出了這個問題,所以他們採用的還是用一個hash函式來處理,不同的是BITMAP卻是有m組。具體做法是,當一個數y進行hash之後,首先mod m,即 α=h(x)modm得到組號;組裡的下標為:index=h(x)/m.

所以理想狀態下均勻分佈,則m個組中每個組都有nm個數,因此可以用R¯¯¯來近似 log2(φnm).
得出結論 nmφ2R¯ ,其中φ=0.77351...,R¯¯¯=R1+R2+...+Rmm

虛擬碼,如下:
Probabilistic counting with stochastic averaging (PCSA)

PCSA
PCSA

m取不同值時的結果如下:
結果

TIPs

  • BITMAP長度L的取值
    經證明,L>log2(nm)+4. 結果較理想。
    具體地,當m=64時,若L=16,可以計算的基數達 n ~ 105;若L=24,基數可以超過107.

  • BITMAP數量m的取值(即多少組)
    經證明,該演算法的標準誤差為:0.78m.
    因此其與m成反比。具體的,當m=64時,標準誤差大約為10%;當m=256時,標準誤差將減小到5%。

  • 演算法可應用於分散式計算
    論文中有闡述,這裡就不多作介紹。

參考資料

  • P. Flajolet and G. Nigel Martin. Probabilistic counting algorithms for data base applications. Journal of computer and system sciences, 31(2):182–209, 1985.