在《什么是布隆过滤器(Bloom Filter)?》一文中,多次提到了误识别率(FPP,false positive probabilistic)。
那么误识别率到底是多大,应该如何计算呢?
假设布隆过滤器大小为m比特,存储了n个元素,使用k次散列函数来计算元素的存储位置。
- 添加1个元素,则任一比特为1的概率为:
1/m
,任一比特为0的概率:1-1/m
; - 添加1个元素,执行k次散列之后,则任一比特为0的概率:
(1-1/m)^k
,任一比特为1的概率:1-(1-1/m)^k
; - 如果添加n个元素,那么任一比特为0的概率:
(1-1/m)^kn
,任一比特为1的概率:1-(1-1/m)^kn
; - 如果将1个新的元素,添加到已存在n个元素的布隆过滤器中,则任一比特已经为1的概率与上面相同,概率为:
1-(1-1/m)^kn
。因此,k个比特都为1的概率为:(1-(1-1/m)^kn)^k
,此即为新插入元素的误识别率。
当n值比较大时,(1-(1-1/m)kn)k约等于:(1-e-kn/m)k
其中,e是一个数学常数,是自然对数函数的底数。有时被称为欧拉数(Euler’s number),以瑞士数学家欧拉命名。它是一个无限不循环小数,数值约为2.71828182846。
假定布隆过滤器大小m为16比特,k为8,存储元素n为1,那么误识别(假阳性)的概率是万分之五(5/10000)。
此时,m/n=16,事实上这表示1个元素使用16个比特的空间来存储。
因此,当k相同时,m/n为16/1、32/2、64/4等值时具有相同的误识别率。
将数值代入公式,计算一下万分之五的概率是怎么来的:
kn=8*1=8
kn/m=8/16=1/2
e的-1次方转换为倒数:1/e=0.36787944117
再计算1/e的1/2次方,即对0.36787944117进行开方,得到:0.60653065971144443045693327628786
计算括号内的值:1-0.60653065971144443045693327628786=0.39346934028855556954306672371214
最后再计算k次方:0.39346934028855556954306672371214的8次方=5.7449622219356465294987619912758e-4
计算得到的误识别率为 5.7449622219356465294987619912758e-4
,即万分之五。
下面是来自http://pages.cs.wisc.edu/~cao/papers/summary-cache/node8.html的一个误识别率表,可以很方便的查询出在m、n和k分别取不同值时的误识别率。
m/n | k | k=1 | k=2 | k=3 | k=4 | k=5 | k=6 |