1. Bloom Filter简介
布隆过滤器 (Bloom Filter
)是由Burton Howard Bloom于1970年提出,它是一种space efficient
的概率型数据结构,用于判断一个元素是否在集合中。在垃圾邮件过滤的黑白名单方法、爬虫(Crawler)的网址判重模块中等等经常被用到。哈希表也能用于判断元素是否在集合中,但是布隆过滤器只需要哈希表的1/8或1/4的空间复杂度就能完成同样的问题。
1.1 Bloom Filter特点
- 布隆过滤器可以插入元素,但不可以删除已有元素。
- Bloom Filter的这种高效是有一定代价的:在判断一个元素是否属于某个集合时,有可能会把不属于这个集合的元素误认为属于这个集合(
false positive
)。 - 其中的元素越多,
false positive rate
(误报率)越大,但是false negative
(漏报)是不可能的。 - 因此,
Bloom Filter
不适合那些“零错误”的应用场合。而在能容忍低错误率的应用场合下,Bloom Filter
通过极少的错误换取了存储空间的极大节省。
2. 集合表示和元素查询
2.1 集合表示
下面我们具体来看Bloom Filter
是如何用位数组表示集合的。初始状态时,Bloom Filter
是一个包含m
位的位数组,每一位都置为
0
。
为了表达 Bloom Filter
使用
2.2 元素查询
在判断
y
是否属于这个集合时,我们对
3. 错误率估计
前面我们已经提到了,Bloom Filter
在判断一个元素是否属于它表示的集合时会有一定的错误率(false positive rate),下面就来估计错误率的大小。在估计之前为了简化模型,我们假设
kn<m
。且各个哈希函数是完全随机的。当集合
S=x1,x2,…,xn
的所有元素都被
k
个哈希函数映射到
其中
1/m
表示任意一个哈希函数选中这一位的概率(前提是哈希函数是完全随机的),
(1−1/m)
表示哈希一次没有选中这一位的概率。要把
S
完全映射到位数组中,需要做
令
ρ
为位数组中
(1−ρ)
为位数组中
1
的比例,
相比
p′
和
f′
,使用
p
和
4. 最优的哈希函数个数
既然Bloom Filter
要靠多个哈希函数将集合映射到位数组中,那么应该选择几个哈希函数才能使元素查询时的错误率降到最低呢?
这里有两个互斥的理由:如果哈希函数的个数多,那么在对一个不属于集合的元素进行查询时得到
0
的概率就大;但另一方面,如果哈希函数的个数少,那么位数组中的
先用
p
和
根据对称性法则可以很容易看出当 p=12 ,也就是 k=ln2⋅mn 时, g 取得最小值。
在这种情况下,由公式
需要强调的一点是,
p=12
时错误率最小这个结果并不依赖于近似值
p
和
同样根据对称性法则可以得到当 p′=12 时, g′ 取得最小值。
5. 位数组的大小
下面我们来看看,在不超过一定错误率的情况下,Bloom Filter
至少需要多少位才能表示全集中任意
n
个元素的集合。假设全集中共有
假设 Bloom Filter
引入了错误,
个集合。
m
位的位数组共有
个集合。全集中
n
个元素的集合总共有
个,因此要让
m
位的位数组能够表示所有
即:
上式中的近似前提是
n
和
将公式 (14) 的结果带入公式 (13) ,即:
根据上式,我们得出结论:在错误率不大于
ε
的情况下,
m
至少要等于
上一小节中我们曾算出当
这个结果比前面我们算得的下界
nlog21ε
大了
log2e≈1.44
倍。这说明在哈希函数的个数取到最优时,要让错误率不超过
ε
,
m
至少需要取到最小值的
6. 总结
在计算机科学中,我们常常会碰到时间换空间或者空间换时间的情况,即为了达到某一个方面的最优而牺牲另一个方面。Bloom Filter在时间空间这两个因素之外又引入了另一个因素:错误率。在使用Bloom Filter判断一个元素是否属于某个集合时,会有一定的错误率。也就是说,有可能把不属于这个集合的元素误认为属于这个集合(False Positive),但不会把属于这个集合的元素误认为不属于这个集合(False Negative)。在增加了错误率这个因素之后,Bloom Filter通过允许少量的错误来节省大量的存储空间。
自从Burton Bloom在70年代提出Bloom Filter之后,Bloom Filter就被广泛用于拼写检查和数据库系统中。近一二十年,伴随着网络的普及和发展,Bloom Filter在网络领域获得了新生,各种Bloom Filter变种和新的应用不断出现。可以预见,随着网络应用的不断深入,新的变种和应用将会继续出现,Bloom Filter必将获得更大的发展。
【完】