建設(shè)單位企業(yè)鎖登陸網(wǎng)站seo沈陽
文章目錄
- BloomFilter簡單介紹
- BloomFilter中的數(shù)學(xué)知識
- fpp(誤判率/假陽性)的計算
- k的最小值
- 公式總結(jié)
- 編程語言實現(xiàn)
- golang的實現(xiàn)
- [已知n, p求m和k](https://github.com/bits-and-blooms/bloom/blob/master/bloom.go#L133)
- 參考
BloomFilter簡單介紹
BloomFilter我們可能經(jīng)常聽到也在使用, 它的特點是如果判斷結(jié)果為"不存在", 則一定不存在; 如果判斷為存在, 則可能存在. 如下圖示例說明當(dāng)我們判斷z元素存在時, 其實是不存在的, 即存在有概率性.
如上圖, 長為m=16的二進制向量, 初始全為0; k=3(即添加一個元素需要將3個bit設(shè)置為1), 對n=3個元素進行添加操作.
BloomFilter幾個關(guān)鍵量定義:
m
: 二進制向量大小(多少個二進制位)
n
: 要存放的元素個數(shù)
k
: 哈希函數(shù)的個數(shù), 或者說每添加一個元素都要進行k次計算
fpp
或者簡寫為p
: 誤判率(false positive rate), 即 使用bloomfilter判斷為存在時, 但實際不存在的概率
BloomFilter中的數(shù)學(xué)知識
fpp(誤判率/假陽性)的計算
BloomFilter主要的數(shù)學(xué)原理是: 在某一范圍內(nèi)(1<=x<=m)1<=x<=m)1<=x<=m)(x為整數(shù), m通常是很大的, 如106級別10^6級別106級別), 任意選取兩個整數(shù)i,j,i和j可重復(fù)選取i, j, i和j可重復(fù)選取i,j,i和j可重復(fù)選取, 則其相等的概率是非常小的: mm2=1m\dfrac{m}{m^2}=\dfrac{1}{m}m2m?=m1?
我們假定hash計算是均勻的, 即每次hash會隨機地將m
位中的一位設(shè)置為1
. 那么:
- 一次hash計算(如h1(x)h1(x)h1(x))后, 任一位被 置為1 的概率為: 1m\dfrac{1}{m}m1?
- 一次hash計算(如h1(x)h1(x)h1(x))后, 任一位 還是0(即未被置為1) 的概率為: 1?1m1 - \dfrac{1}{m}1?m1?
- 添加一個元素(如
bloomFilter.Add(x)
, 即執(zhí)行k次hash)后, 任一位還是0的概率為: (1?1m)k(1 - \dfrac{1}{m})^k(1?m1?)k - 添加n個元素后(如上圖中的n=3個元素:x,y,z), 任一位還是0的概率為: (1?1m)kn(1 - \dfrac{1}{m})^{kn}(1?m1?)kn , 任一位為1的概率為 1?(1?1m)kn1- (1 - \dfrac{1}{m})^{kn}1?(1?m1?)kn
- 如果將1個新的元素,添加到已存在n個元素的BloomFilter中,則任一位已經(jīng)為1的概率與上面相同,為:1?(1?1m)kn1- (1 - \dfrac{1}{m})^{kn}1?(1?m1?)kn .
那么添加這個新元素時, k個比特都為1(相當(dāng)于新元素和已有元素已經(jīng)分不清了)的概率(此即為新插入元素的誤識別率)為:
p=[1?(1?1m)kn]kp = [1- (1 - \dfrac{1}{m})^{kn}]^{k} p=[1?(1?m1?)kn]k
通常來說, m是一個非常大的數(shù)(1MiB內(nèi)存就有220×8≈800萬2^{20}\times{8}\approx 800萬220×8≈800萬個bit), 并且我們有: lim?x→∞(1+x)1x=e{ \lim\limits_{x \to \infin} (1+x)^{\frac{1}{x}} = e}x→∞lim?(1+x)x1?=e
那么在工程實踐中, 可以認為p的近似值為:
p=[1?(1?1m)kn]k=[1?(1?1m)?m×?knm]k≈(1?e?knm)k(當(dāng)m很大時,將?1m看作x)\begin{aligned} p &= [1- (1 - \dfrac{1}{m})^{kn}]^{k} \\ &= [1- (1 - \dfrac{1}{m})^{-m\times\frac{-kn}{m}}]^{k} \\ &\approx (1-e^{-\frac{kn}{m}})^{k} \enspace (當(dāng)m很大時, 將 -\dfrac{1}{m}看 作x) \end{aligned} p?=[1?(1?m1?)kn]k=[1?(1?m1?)?m×m?kn?]k≈(1?e?mkn?)k(當(dāng)m很大時,將?m1?看作x)?
k的最小值
計算過程參考: https://cs.stackexchange.com/questions/132088/how-is-the-optimal-number-of-hashes-is-derived-in-bloom-filter
已經(jīng)遺忘的知識:
- 求導(dǎo)公式: (ln?x)′=1x(\ln{x})^{'} = \dfrac{1}{x}(lnx)′=x1?
- 求導(dǎo)公式: (enx)′=nenx(\bold{e}^{nx})^{'} = n\bold{e}^{nx}(enx)′=nenx
在某些情況下, 我們對n
, m
, 的值可以給一個估算值, 以此來獲得最小的p
(即盡可能準確判斷), 那么k
就是一個變量了, 問題就變?yōu)榍?(1?e?knm)k(1-e^{-\frac{kn}{m}})^{k}(1?e?mkn?)k的最小值.
令f(k)=(1?e?knm)kf(k)=(1-e^{-\frac{kn}{m}})^{k}f(k)=(1?e?mkn?)k, 那么
兩邊取對數(shù)有:ln?f(k)=ln?(1?e?knm)k=kln?(1?e?knm)設(shè)g(k)=kln?(1?e?knm),那么:g′(k)=ln?(1?e?knm)+knme?knm1?e?knm令x=e?knm,x∈(0,1),那么有h(x)=ln?(1?x)?x1?xln?x(注意k用?mnlnx替換)=(1?x)ln?(1?x)?xln?x1?x(x∈0,1)\begin{aligned} & 兩邊取對數(shù)有: \\ & \ln f(k)=\ln (1-e^{-\frac{kn}{m}})^{k} = k \ln(1-e^{-\frac{kn}{m}}) \\ & 設(shè) g(k) = k\ln{(1-e^{-\frac{kn}{m}})}, 那么:\\ & g{'}(k) = \ln{(1-e^{-\frac{kn}{m}})} + k\dfrac{\frac{n}{m}e^{-\frac{kn}{m}}}{1-e^{-\frac{kn}{m}}} \enspace \\ & 令 x = e^{-\frac{kn}{m}}, x \in(0, 1), 那么有 \\ & h(x) = \ln(1-x) - \dfrac{x}{1-x} \ln x \enspace (注意k用-\dfrac{m}{n}lnx替換) \\ & \enspace \enspace \enspace \enspace = \dfrac{(1-x) \ln(1-x)-x \ln x}{1-x} \enspace (x\in{0, 1}) \end{aligned} ?兩邊取對數(shù)有:lnf(k)=ln(1?e?mkn?)k=kln(1?e?mkn?)設(shè)g(k)=kln(1?e?mkn?),那么:g′(k)=ln(1?e?mkn?)+k1?e?mkn?mn?e?mkn??令x=e?mkn?,x∈(0,1),那么有h(x)=ln(1?x)?1?xx?lnx(注意k用?nm?lnx替換)=1?x(1?x)ln(1?x)?xlnx?(x∈0,1)?
對 h(x)=(1?x)ln?(1?x)?xln?x1?x(x∈0,1)h(x) = \dfrac{(1-x)\ln(1-x)-x \ln x}{1-x} \enspace (x\in{0, 1})h(x)=1?x(1?x)ln(1?x)?xlnx?(x∈0,1), 不難看出:
- 當(dāng)x=12時,h(x)=0x=\dfrac{1}{2}時, h(x)=0x=21?時,h(x)=0
- 當(dāng)x>12時,h(x)<0x>\dfrac{1}{2}時,h(x)<0x>21?時,h(x)<0
- 當(dāng)x<12時,h(x)>0x<\dfrac{1}{2}時,h(x)>0x<21?時,h(x)>0
站在巨人的肩膀上, 我們可以直接在這里看:
顯然在x∈(0,1)范圍內(nèi),當(dāng)x=0.5時,h(x)最小x\in(0, 1)范圍內(nèi), 當(dāng)x=0.5時, h(x)最小x∈(0,1)范圍內(nèi),當(dāng)x=0.5時,h(x)最小, 此時k=mnln2k=\dfrac{m}{n}ln2k=nm?ln2
也就是說:
當(dāng)k<mnln2k <\dfrac{m}{n}ln2k<nm?ln2時(想象k非常接近0), x=e?knmx = e^{-\frac{kn}{m}}x=e?mkn?會非常接近1, 此時x>12x>\dfrac{1}{2}x>21?,
h(x)<0h(x)<0h(x)<0 ? f(k)在變小;
當(dāng)k>mnln2k >\dfrac{m}{n}ln2k>nm?ln2時(想象k非常接近0), x=e?knmx = e^{-\frac{kn}{m}}x=e?mkn?會非常接近0, 此時x<12x<\dfrac{1}{2}x<21?,
h(x)>0h(x)>0h(x)>0 ? f(k)在變大;
所以k=mnln2k=\dfrac{m}{n}ln2k=nm?ln2時會使得f(k)f(k)f(k)最小, 即此時p最小.
公式總結(jié)
- 誤判率公式: p=[1?(1?1m)kn]kp = [1- (1 - \dfrac{1}{m})^{kn}]^{k}p=[1?(1?m1?)kn]k
- 誤判率近似公式(當(dāng)
m
很大時): p≈(1?e?knm)kp \approx (1-e^{-\frac{kn}{m}})^{k}p≈(1?e?mkn?)k - 已知
m
,n
, k的最小值(近似)為: k=mnln?2≈0.7mnk=\dfrac{m}{n}\ln{2} \approx 0.7\dfrac{m}{n}k=nm?ln2≈0.7nm? - 已知
n
,p
, 且k取最小時, m=?nln?p(ln2)2m=-\dfrac{n\ln{p}}{(ln2)^{2}}m=?(ln2)2nlnp?
編程語言實現(xiàn)
golang的實現(xiàn)
https://github.com/bits-and-blooms/bloom
已知n, p求m和k
func EstimateParameters(n uint, p float64) (m uint, k uint) {m = uint(math.Ceil(-1 * float64(n) * math.Log(p) / math.Pow(math.Log(2), 2)))k = uint(math.Ceil(math.Log(2) * float64(m) / float64(n)))return
}
參考
- https://en.wikipedia.org/wiki/Bloom_filter
- https://cs.stackexchange.com/questions/132088/how-is-the-optimal-number-of-hashes-is-derived-in-bloom-filter
(完)