大數據流的在線Heavy Hitters算法(下篇):基於略圖的方法

Continue...

之前有好幾篇分上下篇寫的文章都鴿了,慚愧慚愧。爲了不食言,今天繼續聊Heavy Hitters(頻繁項)算法之基於略圖(Sketch)的方法。時間緊張且限於水平,寫得簡單些,看官勿怪。

什麼是略圖

顧名思義,略圖(Sketch)就是能夠大致準確地描述一份數據集的摘要。當數據量非常大時,往往不能直接放入內存中,普通的查找樹、哈希表等受制於數據規模,自然也就沒有用武之地了。然而,略圖的出現以精準度作爲trade-off換來了時間、空間效率的極大提升,也使得解決大數據上的Heavy Hitters以及其他很多問題成爲可能。

概率性數據結構(probabilistic data structure)有不少都採用了略圖的思想,筆者很久之前講過的布隆過濾器就是最典型的應用,它可以藉助位圖與多個哈希函數來非常高效地判斷集合中元素的存在性。而本文接下來要講的兩種略圖——Count-Min Sketch與Count Sketch——則是解決Heavy Hitters問題的利器,本質上也是布隆過濾器思想的延續。

Count-Min Sketch

Count-Min Sketch的論文發表於2004年,其數據結構由兩部分組成:

  • 一個寬度爲w,深度爲d(即d行w列)的二維整數數組,初始化爲全0;
  • d個互相獨立的哈希函數h1...hd,其哈希空間均爲[1...w]。

接下來觀察數據流,當數據流中元素j出現時(可以出現1次,也可以連續出現c次),將j分別用哈希函數h1...hd映射到二維數組中每一行的對應位置,並將該位置的值加上c。如下圖所示,可以看出,Count-Min Sketch非常類似於擴展到d維並且加上了計數功能的布隆過濾器。

那麼如何估計一個元素j的大致出現頻率f[j]呢?答案是直接取元素j對應的所有哈希桶中,計數值最小的那一個。即:

f[j] = mink CMS[k][hk(j)]

當然,爲了保證一定的精準度,w和d的值也不是隨便取的。定義精度參數爲ε,誤差概率參數爲δ(兩者都是很小的正數),那麼就有:

w = 2/ε, d = log 1/δ

ε、δ兩個參數之間有如下的關係:

P{ f[j] <= f[j] + ε||f||1 } >= 1 - δ

翻譯成人話:在至少爲1 - δ的概率下, Count-Min Sketch對任意一個元素j估計的出現頻率與其真實頻率的誤差小於所有元素真實頻率之和的ε倍。這個結論可以用馬爾可夫不等式來證明,筆者數學不怎麼樣,就不班門弄斧了。

容易得知,由於哈希衝突的存在,Count-Min Sketch給出的頻率估計肯定是偏大的(即f[j] >= f[j])。在輸入數據量足夠多的情況下,選擇最小的頻率計數值就意味着哈希衝突最少,亦即更接近真實的頻率值。反過來,它對於很少出現的元素,表現就會比較差。

話說回來,如何用Count-Min Sketch解決Heavy Hitters問題呢?答案就比較直白了——使用K個元素的最小堆維護Top-K,每更新一個元素的計數,就同時更新到最小堆,並隨時移除頻率過小的元素。具體操作方法參見筆者之前介紹PriorityQueue的文章的結尾。

Count-Min Sketch在現實中的應用也很廣泛。在筆者所知的開源框架裏,Spark在spark-sketch子模塊中實現了包括Count-Min Sketch在內的多種略圖結構,並應用在CountMinSketchAgg聚合函數以及DataFrame的數據統計中。PostgreSQL也有一個Count-Min Sketch插件,專門用於近似計算Top-K。

Count Sketch

Count Sketch的論文發表於2002年,比Count-Min Sketch還要早,本質上是Count-Min Sketch的一般化形式。除了w*d的二維數組和d個哈希函數之外,還有另外一組哈希函數g1...gd,且它們的哈希空間只有{1, -1}兩個值。另外,g1...gd取{1, -1}的分佈必須是隨機且均勻的,也就是說E[g(j)]=0。

當數據流中元素j出現c次時,將j分別用哈希函數h1...hd映射到二維數組中每一行的對應位置,並將該位置的值加上c*g(j),如下圖所示。

g1...gd哈希函數是Count Sketch與Count-Min Sketch的最大不同點,它的存在可以部分抹去Count-Min Sketch中的只加操作帶來的正誤差,因此估算f[j]時不必再取元素j對應的所有哈希桶中計數值最小的那一個了。相對地,我們取中位數,即:

f[j] = medianj CS[k][hk(j)] * gk(j)

Count Sketch的ε、δ兩個參數與估計誤差之間有如下的關係(可以藉助切比雪夫不等式證明):

P{ f[j] - ε||f-j||2 <= f[j] <= f[j] + ε||f-j||2 } >= 1 - δ

由上可知,Count-Sketch給出的頻率估計有可能偏大也有可能偏小,但是它用更多的空間(w ~ O(1/ε2))換來了比Count-Min Sketch更嚴格的誤差界限。

使用Count Sketch解決Heavy Hitters問題的思路與Count-Min Sketch相同,就不再贅述了。

The End

還有一大堆其他的事情要搞,晚安吧各位。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章