布隆過濾器的推導

bloom filter

intro

布隆過濾器是一種很有意思的數據結構,它的用途是檢測某個元素是否在一個集合中。

首先,有一個數組,它的元素全部是0,然後共有m個坑:

我現在有一個集合S={x,y,z}S=\left\{ x,y,z \right\},對於每一個元素,通過3個hash函數,將其打到數組上,打中的位置設置爲1。

比如xx,三次hash後,數組上就會有3個位置變爲1(藍色線條)。

至於hash函數,你可以認爲它對xx做了處理,最後模上數組的長度得到一個下標。

注意,元素hash後可能打中同一個坑,這點不必驚奇。當m的值(也就是數組的長度)越來越大,這種情況的概率就會越來越小。

現在我來了一個ww,我要問:ww在不在SS中?

ww也三次hash一下:

  • 如果有打中0的情形,那麼,它肯定不在SS中。
  • 如果打中的全部是1,那麼它很有可能在SS中,也就是說,可以判定它在SS中,並帶有一定的錯誤概率。

more general

我們的根本目的是減少錯誤概率。

現在考慮一般情況。

  • 數組的長度爲mm
  • 集合爲S={x1,x2,,xn}S=\left\{ x_1,x_2,\dots,x_n \right\},有nn個元素
  • hash函數有kk個:h1,h2,,hkh_1,h_2,\dots,h_k0hi(xj)<m(1ik,1jn)0 \le h_i(x_j)\lt m(1 \le i \le k, 1 \le j \le n),換句話說,每個元素xix_i的每次hash的下標都落在數組內
  • hash函數產生的下標是等概率均勻分佈的,不是說全部擠在前面或者某一個地方

好,現在我們考慮一個元素(比如x1x_1)的插入(佔坑)。

經過一次hash後,某個坑爲1的概率爲:

1m\frac{1}{m}

某個坑爲0的概率是:

11m1-\frac{1}{m}

kk個hash函數過後,某個坑依舊爲0的概率是:

(11m)k(1-\frac{1}{m})^k

因爲limm+(11m)m=e\lim\limits_{m\to+\infty}(1-\frac{1}{m})^{-m}=e,所以

limm(11m)k=limm[(11m)m]km=ekm\lim\limits_{m\to\infty}(1-\frac{1}{m})^k=\lim\limits_{m\to\infty}[(1-\frac{1}{m})^{-m}]^{-\frac{k}m{}}=e^{-\frac{k}{m}}

我們會假設數組的長度mm無窮大,所以上面的式子是成立的。

完成了一個元素的插入後,現在我插入 nn個元素

nn個元素插入後,某個坑依舊爲0的概率是:

enkme^{-\frac{nk}{m}}

於是某個坑爲1的概率是:

1enkm1-e^{-\frac{nk}{m}}

現在我來了一個元素yyyy並不在SS

yy經過 kk個hash函數 後,全部打到了標記爲1的坑,這個概率是:

(1enkm)k(1-e^{-\frac{nk}{m}})^k

好了,我們找到了最終的函數。

目標:使f=(1enkm)kf=(1-e^{-\frac{nk}{m}})^k

最小。


f=eln(1enkm)k=ekln(1enkm)f=e^{\ln(1-e^{-\frac{nk}{m}})^k}=e^{k\ln(1-e^{-\frac{nk}{m}})}


g=kln(1enkm)g=k\ln(1-e^{-\frac{nk}{m}})

問題轉化爲求gg的最小值。

gk=ln(1enkm)+(11enkm)(enkm)(nm)(k)\frac{\partial g}{\partial k}=\ln(1-e^{-\frac{nk}{m}})+(\frac{1}{1-e^{-\frac{nk}{m}}})(-e^{-\frac{nk}{m}})(-\frac{n}{m})(k)

gk=0\frac{\partial g}{\partial k}=0

同時,令

enkm=pe^{-\frac{nk}{m}}=p

於是

nm=lnpk\frac{n}{m}=\frac{\ln p}{-k}

那麼

ln(1p)+(11p)(p)(lnpk)(k)=ln(1p)p1plnp=0\ln(1-p)+(\frac{1}{1-p})(p)(\frac{\ln p}{-k})(k)=\ln(1-p)-\frac{p}{1-p} \ln p=0

整理一下:

(1p)ln(1p)=plnp(1-p)\ln (1-p)=p \ln p

得到

p=12p=\frac{1}{2}

於是

k=mnln2k=\frac{m}{n} \ln 2

k,m,nk,m,n滿足k=mnln2k=\frac{m}{n} \ln 2能夠使得ff最小。

也就是說,如果數組長度比上元素個數爲8的話(mn=8\frac{m}{n}=8),那麼hash函數的個數最好有8ln25.458\ln 2 \approx5.45個(你可以取個整)。

這是一個令人愉快的結果。

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