布隆过滤器(Bloom Filter, BF)是由Howrad Bloom在1970年提出的一种具有高效时间和空间效率的二进制向量数据结构,用来检测一个元素是不是属于这个集合。注意,布隆过滤器只判断是否出现在集合中,无法给出元素在集合中的具体位置。
关于如何构造布隆过滤器,下面以集合
S
=
{
S
1
,
S
2
,
S
3
}
S=\{S_{1},S_{2},S_{3}\}
S={S1,S2,S3}为例进行说明。首先要说明一点,虽然布隆过滤器也需要利用哈希查询算法,但与传统的哈希查询算法不同,布隆过滤器并不存储集合中的具体元素,而是通过多次哈希函数将集合中的元素映射到二进制位串中。一旦集合元素被映射到对应的二进制位,则将对应位置改为1。
上述布隆过滤器中,每个位置占1个比特位。如果每个位置改为多个比特位,这样就能表达出的信息。比如如下图所示的计数布隆过滤器。
注意:一般不对布隆过滤器执行删除元素的操作。
在查询过程中,需要计算出相关元素 S i S_{i} Si对应的多个哈希地址,然后检查布隆过滤器中对应的位置上是否全部为1,若全都为1,则 S i S_{i} Si可能在布隆过滤器上(被称为假阳性问题);若不全为1,那么元素 S i S_{i} Si一定不在布隆过滤器上。
布隆过滤器的优点主要有以下几点:
而布隆过滤器的缺点主要为:存在误判率。当两个不同的值却能产生相同的哈希值时,布隆过滤器无法确定查询元素是否真的存在集合中。为了尽量降低误判率,布隆过滤器中一般都设置多个哈希函数。
python中实现布隆过滤器的第三方包很多,这里使用的是pybloom-live (pybloomfiltermmap等包在Windows上安装遇到报错,无法解决)。
pip install pybloom_live
from pybloom_live import BloomFilter
bf=BloomFilter(capacity=100000,error_rate=0.001)
#构建布隆过滤器
for i in range(100000):
bf.add(i)
#查询元素
for i in [1,200,345,100323,3233232,'hello']:
print(i in bf)
其结果如下:
True
True
True
False
False
False