布隆过滤器Bloom Filter

参考原文:http://www.cnblogs.com/allensun/archive/2011/02/16/1956532.html
在线JS演示
以及 《数学之美》

布隆过滤器 (Bloom Filter)是由Burton Howard Bloom于1970年提出,它是一种space efficient的概率型数据结构,用于判断一个元素是否在集合中。在垃圾邮件过滤的黑白名单方法、爬虫(Crawler)的网址判重模块中等等经常被用到。哈希表也能用于判断元素是否在集合中,但是布隆过滤器只需要哈希表的1/8或1/4的空间复杂度就能完成同样的问题。布隆过滤器可以插入元素,但不可以删除已有元素。其中的元素越多,false positive rate(误报率)越大,但是false negative (漏报)是不可能的。

理论很明了,但要知道所谓的误报率这个概念,即俗称的 “假阳性”,把不应该识别的个体识别为了黑名单。以及了解误报率如何估算,如何解决。

一、误报率的计算

假设有m个bit作为bit array,每个元素会用k个随机函数进行随机,当已有n个元素时,下一个元素的误报率计算

  • 1.对于bit array的某一个位置来说,当第一个元素来时,第一个随机函数后置位1的概率为1/m
    因此,置为0的概率为 1-1/m
    所以,当k个随机函数结束时,为0的概率为
image.png
  • 2.插入n个元素后
    该位置仍然为0的概率为


    image.png

为1的概率为


image.png
  • 3.此时来了第n+1个元素,这个元素通过k个随机函数分布后,全为1的概率为


    image.png

通过数学变化,化简为


image.png

二、如何设计布隆过滤器

需要考虑的m,n,k3个参数,一般n是固定的,是和你业务实际相关的数据
如果你很懒,可以参考误报率的表格,可以满足大部分需要

计算解析

2.1、我们首先先考虑当n,m确定的时候,K应该如何取值

布隆过滤器Bloom Filter_第1张图片
image.png

懒得打公式,就找了个计算过程,重点是,对每个步骤进行注释

  • 1、为什么最值的时候,直接求右边为0,这是典型的倒推,正确的方式是,因为f(x)是不为0的,先去求f(x)的求导单数有几个点为0,是最后求出来导数为0的点只有1个,才能得出最值的结果,一开始不过得到一个局部的最值罢了
  • 2.xlnx=(1-x)ln(1-x)是怎么一下子得到 x=1-x的?
    因为x属于(0,1)先画图


    布隆过滤器Bloom Filter_第2张图片
    f(x)=xlnx-(1-x)ln(1-x).png

    可以看到为0的点只有1个,为x=1/2,这算是用数值法
    xlnx并不是个单调函数,并不能很容易得出相等只有1/2一个点的,当然同过求导,计算2个局部最值,然后分段单调性等证明也是可以的,数值法只是因为比较方便

2.2、知道k后,计算p,m,n的关系

将K带入,很容易得到


image.png

此时可以看到,当false positive的概率P确定时,m和n其实是线性关系,而当n业务确定时,m和p是对数关系

2.3、举例子,简单计算下bloom filter的效率

假设有1亿个人邮箱地址,一条记录8个byte,负载因子为0.75
10^8 * 8/0.75=0.8 GB/0.75=1.06G
而Bloom Filter为当我们接受万分之一的误判率时,
-(10^8)*ln(1/10000) / ((ln2)^2) /8 大概需要 0.23G

如何解决误报

布隆过滤器,本质上是一个概率匹配的模型,他的特性就是肯定不会漏报,但有几率误报,通俗的将"有杀错,没放过"
一般用于邮箱等黑名单时,一般情况下都是黑名单远远小于正常邮箱,但黑名单对也有上亿的量,因此是对黑名单进行布隆。对于误杀的,再通过白名单解决。
结合自身的业务特点,你有上亿的商品,但你为了防止有人用虚假的商品号对你进行攻击,即可以反过来使用布隆过滤器,将有效的放在布隆过滤器,只要正常的都可以过来,但是不正常的攻击,只有很小的概率能过来,一般我们控制在万分之五以下是很容易的。当然,当数量少时,直接用哈希表即可。毕竟布隆过滤器只需要哈希表的1/8或1/4的空间复杂度,仍然是同一量级的

你可能感兴趣的:(布隆过滤器Bloom Filter)