基數估計(cardinality estimation)

基數是指一個集合中,不同的數的個數。
基數統計是集合不同的數的個數。比如說一個集合{0, 1, 2, 2, 4, 5},其基數是5,而個數是6。因為1重復出現了兩次。基數是個去重統計。
基數估計是估計一個集合中不同的數的個數,不是數據總量的估計,也不是基數的精確計算。而是用概率算法的思想,來用低空間和時間成本,以一個很低的誤差度來估計數據的基數。

Flajolet–Martin algorithm

這是一個概率算法,把集合的數,通過hash算法,均勻(理論上盡量均勻)hash到一個區間
![](http://www.forkosh.com/mathtex.cgi? \Small [0, 2^L-1])

  1. Initialize a bit-vector BITMAP to be of length L and contain all 0's.
  1. For each element X in M:
    ![](http://www.forkosh.com/mathtex.cgi? \Small index=\rho(y); y =hash(x) )
    ![](http://www.forkosh.com/mathtex.cgi? \Small BITMAP(index)=1 )
  2. Let R denote the smallest index i such that
    ![](http://www.forkosh.com/mathtex.cgi? \Small BITMAP(i)=0 )
  3. Estimate the cardinality of M as
    ![](http://www.forkosh.com/mathtex.cgi? \Small 2^{R}/\phi )
    where ![](http://www.forkosh.com/mathtex.cgi? \Small \phi \approx 0.77351 )

算法思想:

  1. 假設集合M一共有n個數,當集合M的x,均勻hash到新的hash空間[0, 2^L], 則BIT(0)能被訪問n/2次。 因為最低bit位的0,1表示了奇偶數,均勻分布下,奇數大概有一半。所以有n/2的機會,使得BITMAP[0]=1, 同理 BITMAP[1]=1有n/4的機會
  2. 所以, 對于BITMAP[i] = 0的位置i,表示 n < 2^i, 所以算法中的R可以估計,n能使得BITMAP為1的位置的最高點。使得n約為2^R。 其中大約的系數和嚴格的證明,可以參考引用的論文。

[引用]

  1. Flajolet, Philippe; Martin, G. Nigel (1985). "Probabilistic counting algorithms for data base applications" (PDF). Journal of Computer and System Sciences. 31 (2): 182–209. doi:10.1016/0022-0000(85)90041-8.

LogLog algorithm

LogLog也是概率算法,使用m個bit位,使用的bit位m越大算法效果越好,具體算法過程如下:

  1. 與上面算法類似,需要把原始hash到一個數值空間M,即:
    ![](http://www.forkosh.com/mathtex.cgi? \Small M: Multiset \ of \ hashed \ values; \ m = 2^k )
  1. 初始化m個存儲位為0, 即:
    ![](http://www.forkosh.com/mathtex.cgi? \Small s^{(i)}= 0; 1 \le i \le m; \ m=2^k )
  2. 同樣定義:
    ![](http://www.forkosh.com/mathtex.cgi? \Small \rho(y)=\min_{i>=0}bit(y,i)\ne0 \qquad [1])
  3. 對M中的每個x,
    ![](http://www.forkosh.com/mathtex.cgi? \Small for \quad x =b_1b_2\cdots \in M \quad do)
    ![](http://www.forkosh.com/mathtex.cgi? \Small set \quad j :=1 + <b_1 \cdots b_k>2; \quad value \ of \ first \ k \ bits \ in \ x; \ m=2^k )
    ![](http://www.forkosh.com/mathtex.cgi? \Small set \quad s^{(j)} := max \lbrack s^{(j)}, \rho(b
    {k+1}b_{k+2}\cdots) \rbrack ; )
  4. 計算基數估計,
    ![](http://www.forkosh.com/mathtex.cgi? \Small return \quad E := \alpha_mm2{\frac{1}{m}\sum_{j}s{(j)}} )

算法思想:

  1. 在上面Flajolet–Martin算法的基礎上,進行改進。 將集合M的元素分散到m個桶,然后每個桶中的元素采用Flajolet–Martin一致的思路。
  2. 對于有n個不同元素的集合M,大約有n/2^k個不同元素,它們的rho值(LogLog算法中式子[1])等于k。當k=1的時候,也就是n/2個元素會有BITMAP[0]=1(見Flajolet–Martin算法)。所以,
    ![](http://www.forkosh.com/mathtex.cgi? \Small R(M) := \max_{x \in M}\rho(x) )
    可以作為![](http://www.forkosh.com/mathtex.cgi? \Small \log_2n ) 的粗略估計。
  3. 使用元素x的前k個bit位的值,作為m個桶的桶序號,把x落入相應的桶中。這樣每個桶中的元素個數,大約是n/m
  4. 每個桶,采用2中描述的,可以對每個桶i的基數有估計出,有:
    ![](http://www.forkosh.com/mathtex.cgi? \Small \log_2{n_i} = s^{(i)})
  5. 綜合3,4可以知道,每個桶基數的期望是 n/m,等于每個桶基數估計的均值
    ![](http://www.forkosh.com/mathtex.cgi? \Small \log_2{\frac{n}{m}} = \frac{1}{m}\sum_{j=1}{m}s{(j)})
  6. 所以大致上,
    ![](http://www.forkosh.com/mathtex.cgi? \Small E \approx m2{\frac{1}{m}\sum_{j}s{(j)}} )
    根據更深入的分析推導,有
    ![](http://www.forkosh.com/mathtex.cgi? \Small E := \alpha_mm2{\frac{1}{m}\sum_{j}s{(j)}} )
    其中,
    ![](http://www.forkosh.com/mathtex.cgi? \Small \alpha_m := \lbrack \Gamma(-1/m)\frac{1-2^{1/m}}{log2} \rbrack ^{-m}; \Gamma(s)=\frac1s\int_{0}{\infty}e{-t}t^sdt)
    來修正均值帶來的系統偏差
  7. 更詳細的推導和論證參考引用文章

[引用]

  1. Durand, Marianne; Flajolet, Philippe (2003). "Loglog Counting of Large Cardinalities" (PDF). Algorithms - ESA 2003. Lecture Notes in Computer Science. 2832. p. 605. doi:10.1007/978-3-540-39658-1_55. ISBN 978-3-540-20064-2.

HyperLogLog algorithm

HyperLogLog算法,在LogLog算法上做了改進,就是把m個桶的平均值,從LogLog的幾何平均數,改成了調和平均數.

在HyperLogLog的最終實現上,另外做了修正。對小、中、大范圍的值,分別做了修正。具體算法描述如下:(描述了[0,10^9]內的基數估計)

![](http://www.forkosh.com/mathtex.cgi? \Small Let \quad h: D \to {0,1}^32 \quad hash \ data \ from \ D \ to \ binary \ 32-bit \ words.)
![](http://www.forkosh.com/mathtex.cgi? \Small \rho(y)=\min_{i>=0}bit(y,i)\ne0 )
![](http://www.forkosh.com/mathtex.cgi? \Small define \quad \alpha_{16}=0.673; \alpha_{32}=0.697; \alpha_{64}=0.709; \alpha_{m}=0.7213/(1+1.079/m) \ for \ m \ge 128; )
Program HyperLogLog(input M: multiset of items from domain D):

  1. ![](http://www.forkosh.com/mathtex.cgi? \Small assume \quad m = 2^k \ with \ k \in [4 \cdots16] )
  2. ![](http://www.forkosh.com/mathtex.cgi? \Small initialize \ a \ collection \ of \ m \ registers, \ s{(1)},s{(2)},\cdots,s^{(m)}, to \ 0;)
  3. ![](http://www.forkosh.com/mathtex.cgi? \Small for \quad v \in M \quad do)
    ![](http://www.forkosh.com/mathtex.cgi? \Small set \quad x =b_1b_2\cdots )
    ![](http://www.forkosh.com/mathtex.cgi? \Small set \quad j :=1 + <b_1 \cdots b_k>2; \quad value \ of \ first \ k \ bits \ in \ x; \ m=2^k )
    ![](http://www.forkosh.com/mathtex.cgi? \Small set \quad s^{(j)} := max \lbrack s^{(j)}, \rho(b
    {k+1}b_{k+2}\cdots) \rbrack ; )
  4. ![](http://www.forkosh.com/mathtex.cgi? \Small compute \quad E := \alpha_mm^2 \lbrack \sum_{j=1}{m}2{-s^{(j)}} \rbrack ^{-1} )
  5. small range correction
    ![](http://www.forkosh.com/mathtex.cgi? \Small if \ E \le \frac52m \ then )
    ![](http://www.forkosh.com/mathtex.cgi? \Small let \ V \ be \ the \ number \ of \ registers \ equals \ to \ 0 )
    ![](http://www.forkosh.com/mathtex.cgi? \Small if \ V \ne 0 \ then \ set \ E^{}:=mlog(m/V) \ else \ set \ E^{}:=E; \ endif)
    ![](http://www.forkosh.com/mathtex.cgi? \Small \ endif)
    intermediate range - no correction
    ![](http://www.forkosh.com/mathtex.cgi? \Small \ if E \le \frac1{30}2^{32} \ then \ set \ E^:=E; \ endif)
    large range correction
    ![](http://www.forkosh.com/mathtex.cgi? \Small \ if \ E > \frac1{30}2^{32} \ then \ set \ E^
    :=-2{32}log(1-E/2{32}); \ endif)
  6. return
    ![](http://www.forkosh.com/mathtex.cgi? \Small cardinality \ estimate \ E^* \ with \ typical \ relative \ error \ \pm1.04/\sqrt{m})

[引用]

  1. Flajolet, P.; Fusy, E.; Gandouet, O.; Meunier, F. (2007). "HyperLogLog: the analysis of a near-optimal cardinality estimation algorithm" (PDF). AOFA ’07: Proceedings of the 2007 International Conference on the Analysis of Algorithms.

基數估計算法的比較

Paste_Image.png

應用

基數估計的應用比較廣泛,對于存儲空間和實時要求比較高,但是精度要求能容忍一定誤差的時候,基數估計是個很好的選擇。
基數估計的應用舉例:

  1. HyperLogLog算法,在redis中也有應用。
  2. 基數估計應用在數據庫優化中,用來估計復雜查詢涉及的映射、連接等操作的數量。
  3. 路由器使用基數估計,在線實時的分析特定類型的事件,為防止Dos、port scan服務。
  4. 復雜的網絡拓撲結構中,用來估計連接結點對的數量
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,983評論 6 537
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,772評論 3 422
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,947評論 0 381
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,201評論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,960評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,350評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,406評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,549評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,104評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,914評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,089評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,647評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,340評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,753評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,007評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,834評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,106評論 2 375

推薦閱讀更多精彩內容