布隆过滤器

一、简介

        布隆过滤器(bloom filter)是空间效率很高的一种概率数据结构,用于判断一个元素是否在一个集合中。Bloom filter 判断一个元素不存在集合中,则肯定不存在,如果判断一个元素存在于集合中,有一定的概率判断错误。元素可以加到集合中,但是删除困难,有一定的判断误差,因此适合容忍低错误率的场景。

二、为什么需要布隆过滤器?

        在软件设计时,我们经常要判断一个元素是否在一个集合中。一个直接的方法是,将集合中的所有元素都存储在计算机中(如保存在链表哈希表等数据结构)。当要判断一个新元素的时候,直接跟集合中的已存储元素对比即可判断元素是否在集合中。但是,当随着加入的数据量增加,我们需要存储元素的空间就越来越大,而且检索速度也会开始变慢。

三、原理

        布隆过滤器是一个基于m位的比特向量B(b1,b2…,bm),这些比特向量的初始值为0。同时还有一系列的哈希函数(h1,h2…,hk),这些哈希函数运算后的哈希值范围在[1, m]内。

        如下图,就是x、y、z三个元素插入到布隆过滤器中,并判断w值是否在集合中的示意图。

 

上图中,布隆过滤器由m=18位向量,k=3个哈希函数组成。h1、h2和h3是三个哈希函数将输入值分别映射成比特向量上的某个位置上。

假设输入的数据集合X={x, y, z},插入x值(对应红线),则将经过h1、h2和h3三个哈希函数映射到的比特向量上的值改为1。同理,y(对应绿线)z(对应蓝线)值也一样操作。

X集合中元素分别经过三个哈希函数运算后映射为h1(x)=2,h2(x)=6,h3(x)=14,即H(x)=(2,6,14)。同理得,H(y)=(5,17,12),H(z)=(4,6,12)。

如果要查找x、y、z,通过布隆过滤器可以找到对应的比特向量都为1,我们只能确定x、y、z可能在集合中。在上图中,可以发现,x和z在h2哈希函数映射后映射到的是同一个比特向量位置(第6个),同时y和z在经过h3映射后也是同一个比特向量位置(第12个)。也就是说,当我们通过布隆过滤器判断一个元素是否在集合中时,即使对应的比特向量位置全为1,也可能是其他元素映射后导致的。如果要查找w值,经过哈希映射后,可以发现有一个比特向量上的值不为1,那就可以判断,w值一定不在集合中。

比如,查询数据 H(y0)=(1,6,14)和 H(y1)=(2,6,17),可以发现 H(y0)对应的第一个位置为0,因此y0肯定不在集合X中;而 y1 对应的第2,6,17位置均为1,因此y1可能在(而实际不在)集合X中。这种情况称为假阳性五保(False Positive)。

显然,随着输入集合X的增大,各位置上为1的概率增大,布隆过滤器将因为逐渐被“填满”而提高假阳性误报率。可从理论上证明,当比特向量B的半数空间被填满时,布隆过滤器的假阳性误报率将达到最低值。

四、python实现

在实际应用中,我们要设计一个布隆过滤器,只需要确定数据集的容量大小n和误报率P这两个参数。

# -*- coding: utf-8 -*-
from pybloom import BloomFilter
# capacity是数据集容量大小(n), error_rate是能容忍的误报率(P)
f = BloomFilter(capacity=1000, error_rate=0.001)
print f.add(‘dog’) 
# 当不存在该元素,返回False
print f.add(‘cat’) # 当不存在该元素,返回False
print f.add(‘fish’) # 当不存在该元素,返回False
print f.add(‘pig’) # 当不存在该元素,返回False
print f.add(‘cat’) # 若存在,返回 True

print len(f) # 当前存在的元素个数

输出:

False

False

False

False

True

4

五、优点

相比于哈希表、链表等数据结构,其空间和时间的优势明显。而且布隆过滤器的插入、查询时间都是常数O(k),也就是说每次想要插入或查询一个元素是否在集合中时,只需要使用k个哈希函数对元素求值,并将对应的比特位标记或检查对应的比特位即可

六、缺点

        一般情况下,无法从布隆过滤器中删除元素。因为在删除元素之前,我们需要确认一个元素是否在集合中,而我们知道布隆过滤器只能给出可能在集合中或者一定不在集合中的回复,而无法给出是否一定在集合中的回复。

七、应用场景

比较典型的应用场景就是检查垃圾邮箱的地址,比如我建立了一个垃圾邮件的布隆过滤器,当新邮件到来的时候我要快速的判断这封邮件是不是垃圾邮件。 还可以用来判断一个 URL 是不是恶意链接等等。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值