[算法系列之十]大資料量處理利器:布隆過濾器
【引言】
在日常生活中,包括在設計計算機軟體時,我們經常要判斷一個元素是否在一個集合中。比如在字處理軟體中,需要檢查一個英語單詞是否拼寫正確(也就是要判斷 它是否在已知的字典中);在 FBI,一個嫌疑人的名字是否已經在嫌疑名單上;在網路爬蟲裡,一個網址是否被訪問過等等。最直接的方法就是將集合中全部的元素存在計算機中,遇到一個新 元素時,將它和集合中的元素直接比較即可。一般來講,計算機中的集合是用雜湊表(hash table)來儲存的。它的好處是快速準確,缺點是費儲存空間。當集合比較小時,這個問題不顯著,但是當集合巨大時,雜湊表儲存效率低的問題就顯現出來 了。比如說,一個象 Yahoo,Hotmail 和 Gmai 那樣的公眾電子郵件(email)提供商,總是需要過濾來自發送垃圾郵件的人(spamer)的垃圾郵件。一個辦法就是記錄下那些發垃圾郵件的 email 地址。由於那些傳送者不停地在註冊新的地址,全世界少說也有幾十億個發垃圾郵件的地址,將他們都存起來則需要大量的網路伺服器。如果用雜湊表,每儲存一億 個 email 地址, 就需要 1.6GB 的記憶體(用雜湊表實現的具體辦法是將每一個 email 地址對應成一個八位元組的資訊指紋(詳見:數學之美之資訊指紋), 然後將這些資訊指紋存入雜湊表,由於雜湊表的儲存效率一般只有 50%,因此一個 email 地址需要佔用十六個位元組。一億個地址大約要 1.6GB, 即十六億位元組的記憶體)。因此存貯幾十億個郵件地址可能需要上百 GB 的記憶體。除非是超級計算機,一般伺服器是無法儲存的。今天我們就介紹一個一種稱作布隆過濾器的數學工具,它只需要雜湊表 1/8 到 1/4 的大小就能解決同樣的問題。
【簡介】
布隆過濾器(Bloom Filter)是1970年由布隆提出的。它實際上是一個很長的二進位制向量和一系列隨機對映函式。
布隆過濾器可以用於檢索一個元素是否在一個集合中。
它的優點是空間效率和查詢時間都遠遠超過一般的演算法,缺點是有一定的誤識別率和刪除困難。
【工作原理】
我們通過上面的電子郵件的例子來說明工作原理。
假定儲存以一億個電子郵件地址,先建立一個16億二進位制(位元),即兩億位元組的向量,然後將這16億個二進位制位全部清零。
對於每一個電子郵件的地址X,用8個不同的隨機數產生器(F1,F2.........F8)產生8個資訊指紋(f1,f2,......f8)。
在用一個隨機數產生器G把這8個資訊指紋對映到1-16億中的8個自然數g1,g2.....g8。現在把這9個位置全部設定為1。對這一億個電子郵件都這樣處理之後,一個針對這些
電子郵件地址布隆過濾器就建成了。
現在,讓我們看看如何用布隆過濾器來檢測一個可疑的電子郵件地址Y是否是在黑名單中。用相同的8個隨機數(F1,F2,....F8)產生器對這個地址產生
8個資訊指紋(s1,s2,.....s8),然後將這8個資訊指紋對應到布隆過濾器的8個二進位制位,分別是t1,t2,....t8。
如果Y在黑名單中,顯然,t1,t2,...t8對應8個二進位制位一定為1。這樣如果再遇到黑名單中的電子郵件地址都能準確的發現。
說白了就是原理很簡單,用位陣列和k個不同的HASH函式。將HASH函式對應的值的位陣列置1,查詢時如果發現所有HASH函式對應位都是1說明存在。
【集合表示和元素查詢】
下面我們具體來看布隆過濾器是如何用位陣列表示集合的。初始狀態時,布隆過濾器是一個包含m位的位陣列,每一位都置為0。
為了表達S={x1, x2,…,xn}這樣一個n個元素的集合,布隆過濾器使用k個相互獨立的雜湊函式(Hash ),它們分別將集合中的每個元素對映到{1,…,m}的範圍中。
對任意一個元素x,第i個雜湊函式對映的位置h(i,x)就會被置為1(1≤i≤k,代表第i個雜湊函式)。
注意,如果一個位置多次被置為1,那麼只有第一次會起作用,後面幾次將沒有任何效果。
在下圖中,k=3,且有兩個雜湊函式選中同一個位置(從左邊數第五位)。
在判斷y是否屬於這個集合時,我們對y應用k次雜湊函式,如果所有h(i,y)的位置都是1(1≤i≤k),那麼我們就認為y是集合中的元素,否則就認為y不是集合中的元素。
下圖中y1就不是集合中的元素。y2或者屬於這個集合,或者剛好是一個false positive。
【誤識別問題】
(引用於數學之美)
從這個公式可以看出:
k = ln2 * m / n時 p 最小
何根據輸入元素個數n,確定位陣列m的大小及hash函式個數。
當hash函式個數k = ln2 * m / n 時錯誤率最小。
在錯誤率p不大於E的情況 下:
推出:
在錯誤率不大於E的情況 下,m至少要等於才能表示任意n個元素的集合。
但m還應該更大些,因為還要保證bit數組裡至少一半為0,則m應 該大於等於 大概就是nlg(1/E)1.44倍。
布隆過濾器背後的數學原理在於兩個完全隨機的數學衝突峰概率很小,因此,可以在很小的無識別率的條件下,用很小的空間儲存大量的資訊。
【適用範圍】
可以用來實現資料字典,進行資料的判重,或者集合求交集