布隆过滤器(Bloom Filter)

目录

1. 什么是布隆过滤器

2. 基本原理

3. 误判率及相关计算

4. 改进:计数 Bloom Fliter


1. 什么是布隆过滤器

布隆过滤器(Bloom Filter后文简称BF)是由Howard Bloom 在1970年提出的二进制向量数据结构,它具有很好的空间和时间效率,尤其是空间效率极高,BF通常被用来检测某个元素是否是巨量数据集合中的成员(如果BF判断某个元素存在于集合S,那么该元素也可能不存在 ,如果判断不存在,那么就一定不存在)。

2. 基本原理

BF可以高效的表征数据集合,其使用长度为m的位数组来存储集合信息,同时使用k个相互独立的哈希函数将数据映射到位数组空间。其基本思想如下:首先,将长度为m的位数组元素全部置为0,。对于集合S中的某个成员a,分别使用k个哈希函数对其计算,如果h _i(a) = x(1\leqslant i \leqslant k,1\leqslant x \leqslant m)),则将位数组的第x个位置置为1,对于成员a来说,经过k个哈希函数计算后,可能会将位数组中的w位(w\leqslant k)设置为1。对于集合中的其他成员也如此处理,这样即可完成位数组空间的集合表示。

当查询某个成员a是否在集合S中时,使用相同的k个哈希函数计算,如果其对应位数组中的w位(w\leqslant k)都为1,则判断成员a属于集合S,只要w位中有任意一位位0,则判断成员a不属于集合S。

3. 误判率及相关计算

因为BF使用位数组和哈希函数来表征集合,并不需要实际存储集合数据本身,所以其空间利用率非常高,但是有个潜在问题,及在查询某个成员是否属于集合时,会发生误判。也就是说,如果某个成员不在集合中,有可能BF会得出其在集合中的结论。所以BF只能使用在允许发生一定误判的场景,而在要求百分之百精确判断集合成员的场景下不能使用。

下面我们使用一个位数为12的位数组和3个不相同的数字x1,x2,x3,以及3个哈希函数来举例说明:

x1,x2分别使用三个哈希函数映射位数组的三个位置(对应位置的数值标为1)。如果此时查询不属于该集合的x3是否在集合中,而正好3个哈希函数对x3计算后对应的位置分别是2,7,11,那么根据判断规则,BF会认为x3属于集合,因为其对应的位置都为1,此时就发生了误判现象。

尽管BF会发生误判,但不会发生漏判。也就开篇就提到的,如果某个成员确实属于集合,那么BF一定能够给出正确判断。这也很好理解,因为在将该成员映射到位数组空间过程中,对应位置都已经被设置为1,而整个过程中不存在将1改为0的行为,所以一定不会发生漏判。

在实际应用中,一般希望可以在一定范围内控制误判率的大小,比如低于1%。那么哪些因素会影响误判率呢?很显然集合的大小n,哈希函数的个数k,位数组的长度m都会影响误判率。n和m对误判率的影响直观上很好理解,因为集合大小n越大,其他条件固定的情况下,位数组中就会有更多比例的位置被设置为1,误判率就会增大。而位数组大小m越大,那么在n,k固定的情况下,位数组中剩余未0的比例就会越高,误判率就会越小。哈稀函数个数对误判率的影响情况比较复杂,一方面在将集合成员映射到位数组过程中,如果其他条件固定,使用的哈希函数数越多,则位数组中会有更多比例位置被设置为1,即增大误判率,但是在查询时,哈希函数越多,误判的机率就越小。经过数学分析,3个因素于误判率的关系如下:

p_{fp}\approx (1-e^{-kn/m})^k

根据以上公式,如果已知k,m和n,即可计算出对应的误判率。从上面的分析可以看出,3个影响因子中,哈希函数个数k情况比较复杂。那么假设m和n已知,设定多少个哈希函数误判率能达到最低呢? 经过分析,最优的哈希函数个数为:

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

在实际应用中,更常见的需求是假设已知集合大小n,并设定好误判率p,需要计算给BF分配多大内存合适,也就是需要确定m的大小。如下公式可以解决这个问题:

m=-\frac{nlnp}{(ln2)^2}

有了以上公式,就可以在实际应用中灵活地设置各种参数以达到充分利用BF工具的目的。

4. 改进:计数 Bloom Fliter

基本的BF在使用时有个缺点:无法删除集合成员,只能增加成员并对其查询。一个容易想到但是不正确的做法是:如果要删除集合成员a,那么先用k个哈希函数对其计算,因为a已经是集合成员,那么其对应的位数组的位置一定已经被设定为1,所以只要将对应位置的1重新设置为0即可。这看上去很简洁,但却是错误的。

无法删除集合成员限制了BF的使用场景,因为很多场景下集合成员是动态变化的,有增有减,此时BF就无法使用,因为它只能处理集合成员递增的情形。

计数BF(Counting Bloom Fliter)对此做出了改进,使得BF可以删除集合成员,这样就大大拓展了BF的使用范围。

基本BF不能实现删除操作是因为其基本信息单元是1个比特位,只能表达两种状态,表达能力有限。所以针对这个缺陷,扩展其基本信息单元的位数,可以承载更多的信息。

计数BF一般采取3或4个比特位位单元。这样,将集合成员加入位数组时,根据k个哈希函数计算,此时对应位置的信息单元由多个比特位构成,将其原先的数值加1即可。查询集合时,只要相应位置的信息单元都不为0即可认为该成员属于集合,而删除成员,只要将对应位置的计数减1即可。

计数BF扩展了BF的应用场景,对应的代价是增加了位数组大小,如果采取3比特位作为基本单元的话,则位数组大小增加3倍。另外存在计数溢出的可能,因为比特位表达能力仍然有限,这样当计数很大的时候存在计数溢出问题。

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