日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

布隆過濾器 (Bloom Filter) 詳解

系統(tǒng) 2231 0

布隆過濾器 (Bloom Filter)是由Burton Howard Bloom于1970年提出,它是一種space efficient的概率型數(shù)據(jù)結(jié)構(gòu),用于判斷一個(gè)元素是否在集合中。在垃圾郵件過濾的黑白名單方法、爬蟲(Crawler)的網(wǎng)址判重模塊中等等經(jīng)常被用到。哈希表也能用于判斷元素是否在集合中,但是布隆過濾器只需要哈希表的1/8或1/4的空間復(fù)雜度就能完成同樣的問題。布隆過濾器可以插入元素,但不可以刪除已有元素。其中的元素越多,false positive rate(誤報(bào)率)越大,但是false negative (漏報(bào))是不可能的。

本文將詳解布隆過濾器的相關(guān)算法和參數(shù)設(shè)計(jì),在此之前希望大家可以先通過谷歌黑板報(bào)的 數(shù)學(xué)之美系列二十一 - 布隆過濾器(Bloom Filter) 來得到些基礎(chǔ)知識(shí)。

一. 算法描述

一個(gè)empty bloom filter是一個(gè)有m bits的bit array,每一個(gè)bit位都初始化為0。并且定義有k個(gè)不同的hash function,每個(gè)都以u(píng)niform random distribution將元素hash到m個(gè)不同位置中的一個(gè)。在下面的介紹中n為元素?cái)?shù),m為布隆過濾器或哈希表的slot數(shù),k為布隆過濾器重hash function數(shù)。

為了add一個(gè)元素,用k個(gè)hash function將它hash得到bloom filter中k個(gè)bit位,將這k個(gè)bit位置1。

為了query一個(gè)元素,即判斷它是否在集合中,用k個(gè)hash function將它hash得到k個(gè)bit位。若這k bits全為1,則此元素在集合中;若其中任一位不為1,則此元素比不在集合中(因?yàn)槿绻冢瑒t在add時(shí)已經(jīng)把對應(yīng)的k個(gè)bits位置為1)。

不允許remove元素,因?yàn)槟菢拥脑挄?huì)把相應(yīng)的k個(gè)bits位置為0,而其中很有可能有其他元素對應(yīng)的位。因此remove會(huì)引入false negative,這是絕對不被允許的。

當(dāng)k很大時(shí),設(shè)計(jì)k個(gè)獨(dú)立的hash function是不現(xiàn)實(shí)并且困難的。對于一個(gè)輸出范圍很大的hash function(例如MD5產(chǎn)生的128 bits數(shù)),如果不同bit位的相關(guān)性很小,則可把此輸出分割為k份。或者可將k個(gè)不同的初始值(例如0,1,2, … ,k-1)結(jié)合元素,feed給一個(gè)hash function從而產(chǎn)生k個(gè)不同的數(shù)。

當(dāng)add的元素過多時(shí),即n/m過大時(shí)(n是元素?cái)?shù),m是bloom filter的bits數(shù)),會(huì)導(dǎo)致false positive過高,此時(shí)就需要重新組建filter,但這種情況相對少見。

二. 時(shí)間和空間上的優(yōu)勢

當(dāng)可以承受一些誤報(bào)時(shí),布隆過濾器比其它表示集合的數(shù)據(jù)結(jié)構(gòu)有著很大的空間優(yōu)勢。例如self-balance BST, tries, hash table或者array, chain,它們中大多數(shù)至少都要存儲(chǔ)元素本身,對于小整數(shù)需要少量的bits,對于字符串則需要任意多的bits(tries是個(gè)例外,因?yàn)閷τ谟邢嗤琾refixes的元素可以共享存儲(chǔ)空間);而chain結(jié)構(gòu)還需要為存儲(chǔ)指針付出額外的代價(jià)。對于一個(gè)有1%誤報(bào)率和一個(gè)最優(yōu)k值的布隆過濾器來說,無論元素的類型及大小,每個(gè)元素只需要9.6 bits來存儲(chǔ)。這個(gè)優(yōu)點(diǎn)一部分繼承自array的緊湊性,一部分來源于它的概率性。如果你認(rèn)為1%的誤報(bào)率太高,那么對每個(gè)元素每增加4.8 bits,我們就可將誤報(bào)率降低為原來的1/10。add和query的時(shí)間復(fù)雜度都為O(k),與集合中元素的多少無關(guān),這是其他數(shù)據(jù)結(jié)構(gòu)都不能完成的。

如果可能元素范圍不是很大,并且大多數(shù)都在集合中,則使用確定性的bit array遠(yuǎn)遠(yuǎn)勝過使用布隆過濾器。因?yàn)閎it array對于每個(gè)可能的元素空間上只需要1 bit,add和query的時(shí)間復(fù)雜度只有O(1)。注意到這樣一個(gè)哈希表(bit array)只有在忽略collision并且只存儲(chǔ)元素是否在其中的二進(jìn)制信息時(shí),才會(huì)獲得空間和時(shí)間上的優(yōu)勢,而在此情況下,它就有效地稱為了k=1的布隆過濾器。

而當(dāng)考慮到collision時(shí),對于有m個(gè)slot的bit array或者其他哈希表(即k=1的布隆過濾器),如果想要保證1%的誤判率,則這個(gè)bit array只能存儲(chǔ)m/100個(gè)元素,因而有大量的空間被浪費(fèi),同時(shí)也會(huì)使得空間復(fù)雜度急劇上升,這顯然不是space efficient的。解決的方法很簡單,使用k>1的布隆過濾器,即k個(gè)hash function將每個(gè)元素改為對應(yīng)于k個(gè)bits,因?yàn)檎`判度會(huì)降低很多,并且如果參數(shù)k和m選取得好,一半的m可被置為為1,這充分說明了布隆過濾器的space efficient性。

三. 舉例說明

以垃圾郵件過濾中黑白名單為例:現(xiàn)有1億個(gè)email的黑名單,每個(gè)都擁有8 bytes的指紋信息,則可能的元素范圍為 clip_image002 ,對于bit array來說是根本不可能的范圍,而且元素的數(shù)量(即email列表)為 clip_image002[6] ,相比于元素范圍過于稀疏,而且還沒有考慮到哈希表中的collision問題。

若采用哈希表,由于大多數(shù)采用open addressing來解決collision,而此時(shí)的search時(shí)間復(fù)雜度為 :

clip_image002[8]

即若哈希表半滿(n/m = 1/2),則每次search需要probe 2次,因此在保證效率的情況下哈希表的存儲(chǔ)效率最好不超過50%。此時(shí)每個(gè)元素占8 bytes,總空間為:

clip_image002[10]

若采用Perfect hashing(這里可以采用Perfect hashing是因?yàn)橹饕僮魇莝earch/query,而并不是add和remove),雖然保證worst-case也只有一次probe,但是空間利用率更低,一般情況下為50%,worst-case時(shí)有不到一半的概率為25%。

若采用布隆過濾器,取k=8。因?yàn)閚為1億,所以總共需要 clip_image002[12] 被置位為1,又因?yàn)樵诒WC誤判率低且k和m選取合適時(shí),空間利用率為50%(后面會(huì)解釋),所以總空間為:

clip_image002[14]

所需空間比上述哈希結(jié)構(gòu)小得多,并且誤判率在萬分之一以下。

四. 誤判概率的證明和計(jì)算

假設(shè)布隆過濾器中的hash function滿足simple uniform hashing假設(shè):每個(gè)元素都等概率地hash到m個(gè)slot中的任何一個(gè),與其它元素被hash到哪個(gè)slot無關(guān)。若m為bit數(shù),則對某一特定bit位在一個(gè)元素由某特定hash function插入時(shí)沒有被置位為1的概率為:

clip_image002[16]

則k個(gè)hash function中沒有一個(gè)對其置位的概率為:

clip_image002[18]

如果插入了n個(gè)元素,但都未將其置位的概率為:

clip_image002[20]

則此位被置位的概率為:

clip_image002[22]

現(xiàn)在考慮query階段,若對應(yīng)某個(gè)待query元素的k bits全部置位為1,則可判定其在集合中。因此將某元素誤判的概率為:

clip_image002[24]

由于 clip_image002[26] ,并且 clip_image002[28] 當(dāng)m很大時(shí)趨近于0,所以

clip_image002[30]

從上式中可以看出,當(dāng)m增大或n減小時(shí),都會(huì)使得誤判率減小,這也符合直覺。

現(xiàn)在計(jì)算對于給定的m和n,k為何值時(shí)可以使得誤判率最低。設(shè)誤判率為k的函數(shù)為:

clip_image002[32]

設(shè) clip_image002[34] , 則簡化為

clip_image002[36] ,兩邊取對數(shù)

clip_image002[38] , 兩邊對k求導(dǎo)

clip_image002[40]

下面求最值

clip_image002[42]

clip_image002[44] clip_image004

clip_image002[44] clip_image006

clip_image002[44] clip_image008

clip_image002[44] clip_image010

clip_image002[44] clip_image012

clip_image002[44] clip_image014

clip_image002[44] clip_image002[52]

因此,即當(dāng) clip_image002[54] 時(shí)誤判率最低,此時(shí)誤判率為:

clip_image002[56]

可以看出若要使得誤判率≤1/2,則:

clip_image002[58]

這說明了若想保持某固定誤判率不變,布隆過濾器的bit數(shù)m與被add的元素?cái)?shù)n應(yīng)該是線性同步增加的。

五. 設(shè)計(jì)和應(yīng)用布隆過濾器的方法

應(yīng)用時(shí)首先要先由用戶決定要add的元素?cái)?shù)n和希望的誤差率P。這也是一個(gè)設(shè)計(jì)完整的布隆過濾器需要用戶輸入的僅有的兩個(gè)參數(shù),之后的所有參數(shù)將由系統(tǒng)計(jì)算,并由此建立布隆過濾器。

系統(tǒng)首先要計(jì)算需要的內(nèi)存大小m bits:

clip_image002[60]

再由m,n得到hash function的個(gè)數(shù):

clip_image002[52]

至此系統(tǒng)所需的參數(shù)已經(jīng)備齊,接下來add n個(gè)元素至布隆過濾器中,再進(jìn)行query。

根據(jù)公式,當(dāng)k最優(yōu)時(shí):

clip_image002[66]

clip_image004[8]

因此可驗(yàn)證當(dāng)P=1%時(shí),存儲(chǔ)每個(gè)元素需要9.6 bits:

clip_image002[70]

而每當(dāng)想將誤判率降低為原來的1/10,則存儲(chǔ)每個(gè)元素需要增加4.8 bits:

clip_image002[72]

這里需要特別注意的是,9.6 bits/element不僅包含了被置為1的k位,還把包含了沒有被置為1的一些位數(shù)。此時(shí)的

clip_image002[74]

才是每個(gè)元素對應(yīng)的為1的bit位數(shù)。

clip_image002[76] 從而使得P(error)最小時(shí),我們注意到:

clip_image002[78] 中的 clip_image002[80] ,即

clip_image002[82]

此概率為某bit位在插入n個(gè)元素后未被置位的概率。因此,想保持錯(cuò)誤率低,布隆過濾器的空間使用率需為50%。

如果您滿意我的博客,請點(diǎn)擊“ 訂閱Allen Sun的技術(shù)博客 ”即可訂閱,謝謝:)

原創(chuàng)文章屬于 Allen Sun
歡迎轉(zhuǎn)載,但請注明文章作者 Allen Sun 和鏈接

布隆過濾器 (Bloom Filter) 詳解


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 张家港市| 嘉鱼县| 义马市| 云龙县| 张北县| 宜黄县| 安国市| 原阳县| 浦江县| 青神县| 南阳市| 宁明县| 且末县| 旌德县| 留坝县| 永春县| 吉木乃县| 江永县| 沙田区| 邵阳县| 黄浦区| 临桂县| 临夏县| 保康县| 曲松县| 平利县| 兴山县| 洞头县| 洛宁县| 霸州市| 北宁市| 株洲市| 屏东县| 本溪市| 宜川县| 紫金县| 泰州市| 南皮县| 胶州市| 龙江县| 潞西市|