HyperLogLog


數據量一大,連統計基數也成了一個麻煩事。在使用kylin的時候,遇到對度量值進行基數統計,使用的是Hyperloglog算法,占用內存小,誤差小,實乃不錯的方法,但查閱網上的資料與內容,感覺未能理解的太明白。經過一番折騰,自己給整理出一個版本出來。

算法的論文是《HyperLogLog the analysis of a near-optimal cardinality estimation algorithm》,可以在谷歌學術上下載下來看看。具體論文的理論推導不詳細介紹,簡述下其思想核心。

在理想狀態下,將一堆數據hash至[0,1],每兩點距離相等,1/間距 即可得出這堆數據的基數。然而實際情況往往不能如願,只能通過一些修正不斷的逼近這個實際的基數。實際采用的方式一是分桶,二是取kmax。分桶將數據分為m組,每組取第k個位置的值,所有組中得到最大的kmax,(k-1)/kmax得到估計的基數。

HLL算法的另一個主觀上的理解可以用拋硬幣的方式來理解。以當硬幣拋出反面為一次過程,當你拋n次硬幣全為正面的概率為1/2^n。當你經歷過k(k很大時)次這樣的過程,硬幣不出現反面的概率基本為0。假設反面為1,正面為0,每拋一次記錄1或者0,當記錄上顯示為0000000...001時,這種可以歸結為小概率事件,基本不會發生。轉換到基數的想法就是,可以通過第一個1出現前0的個數n來統計基數,基數大致為2^(n+1)時。硬幣當中可以統計為(1/2*1+1/4*2+1/8*3...),大致可以這么去想。

論文當中對於算法的具體實現過程如下:

 


 

1.hash成32位的值

2.初始化m個登記表

3.計算得出每組最大的leadingzeros

4.計算基數並做調整。

國外友人實現的一個頁面demo  http://content.research.neustar.biz/blog/hll.html

java代碼的實現可參考 https://github.com/addthis/stream-lib/blob/master/src/main/java/com/clearspring/analytics/stream/cardinality/HyperLogLog.java

代碼看懂並不難,有需要的話可以跟我來討論。



作者:形彥
鏈接:http://www.jianshu.com/p/0cf5f8bc1079
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM