布隆过滤器

前言

布隆过滤器(Bloom Filter)是非常经典的,以空间换时间的算法。布隆过滤器由布隆在 1970 年提出。它实际上是一个很长的二进制向量和一系列随机映射函数。布隆过滤器可以用于检索一个元素是否在一个集合中。它的优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误识别率和删除困难。

布隆过滤器的原理

布隆过滤器的实现原理是一个超大的位数组和几个哈希函数。假设位数组的长度为 m,哈希函数的个数为 k请添加图片描述
解析上图,具体的操作流程:

  1. 假设集合里面有 3 个元素 {x, y, z},哈希函数的个数为 3。
  2. 首先将位数组进行初始化,初始化状态的维数组的每个位都设置位 0。
  3. 对于集合里面的每一个元素,将元素依次通过 3 个哈希函数进行映射,每次映射都会产生一个哈希值,这个值对应位数组上面的一个点,然后将位数组对应的位置标记为 1。
  4. 查询某元素是否存在集合中的时,用同样的方法将 W 通过哈希映射到位数组上的 3 个点。如果 3 个点中任意一个点不为 1,则可以判断该元素一定不存在集合中。反之,如果 3 个点都为 1,则该元素可能存在集合中。

注意:此处不能判断该元素是否一定存在集合中,可能存在一定的误判率,这一点从图中就能得知:假设某个元素通过映射对应下标为 4、5、6 这 3 个点。虽然这 3 个点都为 1,但是很明显这 3 个点是不同元素经过哈希得到的位置,因此这种情况说明元素虽然不在集合中,也可能对应的都是 1,这是误判率存在的原因。

假阳性率

所谓假阳性率就是本来在集合中不存在的元素,被判定为存在的概率。

假阳性是BF最大的痛点,因此有必要权衡,比如计算一下假阳性的概率。为了简单一点,就假设我们的哈希函数选择位数组中的比特时,都是等概率的。当然在设计哈希函数时,也应该尽量满足均匀分布。

  • 在位数组长度m的BF中插入一个元素,它的其中一个哈希函数会将某个特定的比特置为1。因此,在插入元素后,该比特仍然为0的概率是: 1 − 1 m 1-{1 \over m} 1m1
  • 现有k个哈希函数,并插入n个元素,自然就可以得到该比特仍然为0的概率是: ( 1 − 1 m ) k n (1-{1 \over m})^{kn} (1m1)kn
  • 反过来讲,它已经被置为1的概率就是 1 − ( 1 − 1 m ) k n 1- (1-{1 \over m})^{kn} 1(1m1)kn
  • 也就是说,如果在插入n个元素后,我们用一个不在集合中的元素来检测,那么被误报为存在于集合中的概率(也就是所有哈希函数对应的比特都为1的概率)为: ( 1 − [ 1 − 1 m ] k n ) k (1- [1-{1 \over m}]^{kn})^k (1[1m1]kn)k
  • 当n比较大时,根据重要极限公式,可以近似得出假阳性率: ( 1 − e − k n / m ) k (1- e^{-kn/m})^k (1ekn/m)k

因此,可以得出如下结论,在哈希函数的个数k一定的情况下:

  • 位数组长度m越大,假阳性率越低
  • 已插入元素的个数n越大,假阳性率越高

如何选择适合业务的 k 和 m 值呢,直接贴一个公式:
请添加图片描述

如何设计m,k呢

下图是网友根据不同的m,k算出的假阳率,我们可以根据需要去选择
请添加图片描述

主要参考

布隆过滤器
Bloom Filters 容错率计算,布隆过滤器大小如何设置

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值