Bloom Filter解析
布隆过滤器简介:https://www.cnblogs.com/Jack47/p/bloom_filter_intro.html
布隆过滤器详解:原文链接:http://www.cnblogs.com/allensun/archive/2011/02/16/1956532.html
布隆过滤器解析:https://www.cnblogs.com/liyulong1982/p/6013002.html
布隆过滤器 (Bloom Filter)是由Burton Howard Bloom于1970年提出,它是一种space efficient的概率型数据结构,用于判断一个元素是否在集合中。在垃圾邮件过滤的黑白名单方法、爬虫(Crawler)的网址判重模块中等等经常被用到。哈希表也能用于判断元素是否在集合中,但是布隆过滤器只需要哈希表的1/8或1/4的空间复杂度就能完成同样的问题。布隆过滤器可以插入元素,但不可以删除已有元素。其中的元素越多,false positive rate(误报率)越大,但是false negative (漏报)是不可能的。
本文将详解布隆过滤器的相关算法和参数设计,在此之前希望大家可以先通过谷歌黑板报的数学之美系列二十一 - 布隆过滤器(Bloom Filter)来得到些基础知识。
简单的布隆过滤器不支持删除一个元素,因为“漏报”是不允许的。一个元素映射到k位,尽管设置这k位中任意一位为0就能够删除这个元素,但也会导致删除其他可能映射到这个位置的元素。因为没办法决定是否有其他元素也映射到了需要删除的这一位上。
通过好几个哈希函数来共同判断这个元素是否在集合里,比只用一次哈希带来冲突的可能性要低很多。暴雪的MPQ归档文件中使用的哈希算法跟布隆过滤器也有异曲同工之妙。
一个空的布隆过滤器是一个m位的位数组,所有位的值都为0。定义了k个不同的符合均匀随机分布的哈希函数,每个函数把集合元素映射到位数组的m位中的某一位。
添加一个元素:
先把这个元素作为k个哈希函数的输入,拿到k个数组位置,然后把所有的这些位置置为1。
查询一个元素(测试这个元素是否在集合里):
把这个元素作为k个哈希函数的输入,得到k个数组位置。这些位置中只要有任意一个是0,元素肯定不在这个集合里。如果元素在集合里,那么这些位置在插入这个元素时都被置为1了。如果这些位置都是1,那么要么元素在集合里,要么所有这些位置是在其他元素插入过程中被偶然置为1了,导致了一次“误报”。
一个布隆过滤器的例子见下图,代表了集合{x,y,z}。带颜色的箭头表示了集合中每个元素映射到位数组中的位置。元素w不在集合里,因为它哈希后的比特位置中有一个值为0的位置。在这个图里,m=18,k=3。
一个布隆过滤器的例子
简单的布隆过滤器不支持删除一个元素,因为“漏报”是不允许的。一个元素映射到k位,尽管设置这k位中任意一位为0就能够删除这个元素,但也会导致删除其他可能映射到这个位置的元素。因为没办法决定是否有其他元素也映射到了需要删除的这一位上。
通过好几个哈希函数来共同判断这个元素是否在集合里,比只用一次哈希带来冲突的可能性要低很多。暴雪的MPQ归档文件中使用的哈希算法跟布隆过滤器也有异曲同工之妙。
误判率
误判率就是在插入n个元素后,某元素被判断为“可能在集合里”,但实际不在集合里的概率,此时这个元素哈希之后的k个比特位置都被置为1。
假设哈希函数等概率地选择每个数组位置,即哈希后的值符合均匀分布,那么每个元素等概率地哈希到位数组的m个比特位上,与其他元素被哈希到哪些位置无关(独立事件)。设定数组总共有m个比特位,有k个哈希函数。在插入一个元素时,一个特定比特没有被某个哈希函数置为1的概率是:
插入一个元素后,这个比特没有被任意哈希函数置为1的概率是:
在插入了n个元素后,这个特定比特仍然为0的概率是:
所以这个比特被置为1的概率是:
现在检测一个不在集合里的元素。经过哈希之后的这k个数组位置任意一个位置都是1的概率如上。这k个位置都为1的概率是:
哈希函数个数的最优解
对于给定的m和n,让“误报率”最小的k值为:
此时“误报率”为:
可以简化为:
在leveldb中,设定的误判率<=1%,所以m/n是9.6,即10个比特,此时k=6.72,即7bit,即需要7次hash,每个元素占7bit,总共需要m=n*9.6个比特作为布隆过滤器的位数组数据。
优点
- 存储空间和插入/查询时间都是常数,远远超过一般的算法
- Hash函数相互之间没有关系,方便由硬件并行实现
- 不需要存储元素本身,在某些对保密要求非常严格的场合有优势
缺点
- 有一定的误识别率
- 删除困难
应用
- 搜索引擎中的海量网页去重
- leveldb等数据库中快速判断元素是否存在,可以显著减少磁盘访问
下一篇文章会介绍布隆过滤器在leveldb中的实现和应用
回到本系列目录:leveldb源码学习系列
参考资料:
- Bloom Filter
- Whay Bloom filters work the way they do
- BloomFilter–大规模数据处理利器
- Bloom Filter概念和原理
- 海量数据处理之Bloom Filter详解
Bloom Filter解析的更多相关文章
- Leveldb源码解析之Bloom Filter
Bloom Filter,即布隆过滤器,是一种空间效率很高的随机数据结构. 原理:开辟m个bit位数组的空间,并全部置零,使用k个哈希函数将元素映射到数组中,相应位置1.如下图,元素K通过哈希函数h1 ...
- 爬虫技术之——bloom filter(含java代码)
在爬虫系统中,在内存中维护着两个关于URL的队列,ToDo队列和Visited队列,ToDo队列存放的是爬虫从已经爬取的网页中解析出来的即将爬取的URL,但是网页是互联的,很可能解析出来的URL是已经 ...
- scrapy-redis + Bloom Filter分布式爬取tencent社招信息
scrapy-redis + Bloom Filter分布式爬取tencent社招信息 什么是scrapy-redis 什么是 Bloom Filter 为什么需要使用scrapy-redis + B ...
- Bloom Filter:海量数据的HashSet
Bloom Filter一般用于数据的去重计算,近似于HashSet的功能:但是不同于Bitmap(用于精确计算),其为一种估算的数据结构,存在误判(false positive)的情况. 1. 基本 ...
- 探索C#之布隆过滤器(Bloom filter)
阅读目录: 背景介绍 算法原理 误判率 BF改进 总结 背景介绍 Bloom filter(后面简称BF)是Bloom在1970年提出的二进制向量数据结构.通俗来说就是在大数据集合下高效判断某个成员是 ...
- Bloom Filter 布隆过滤器
Bloom Filter 是由伯顿.布隆(Burton Bloom)在1970年提出的一种多hash函数映射的快速查找算法.它实际上是一个很长的二进制向量和一些列随机映射函数.应用在数据量很大的情况下 ...
- Bloom Filter学习
参考文献: Bloom Filters - the math http://pages.cs.wisc.edu/~cao/papers/summary-cache/node8.html B ...
- 【转】探索C#之布隆过滤器(Bloom filter)
原文:蘑菇先生,http://www.cnblogs.com/mushroom/p/4556801.html 背景介绍 Bloom filter(后面简称BF)是Bloom在1970年提出的二进制向量 ...
- bloom filter
Bloom filter 是由 Howard Bloom 在 1970 年提出的二进制向量数据结构,它具有很好的空间和时间效率,被用来检测一个元素是不是集合中的一个成员. 结 构 二进制 召回率 ...
随机推荐
- python基础学习5----字典
字典由大括号和键值对组成,特点为无序,键唯一 1.字典的创建 #直接创建字典 dic1={'name':'a','age':20} #通过dict创建字典,输出都为{'name': 'a', 'age ...
- android下载 sdk 的两个代理 ,解决下载sdk慢的问题
mirrors.opencas.cn mirrors.neusoft.edu.cn 设置教程:http://blog.csdn.net/mociml/article/details/1633125 ...
- ansible 碎记录
https://www.zhukun.net/archives/8167 ansible -i new/hosts new -m authorized_key -a "user=root k ...
- Servlet 核心接口
在Servlet体系结构中,除了用于实现Servlet的Servlet接口.GenericServlet类和HttpServlet类外,还有一些辅助Servlet获取相关资源信息的重要接口,了解这些接 ...
- 《面向对象程序设计》六 GUI
git传送门 我这无药可救的拖延症和懒癌orz 主界面 文件读取界面 提示界面 最初选择vs+mfc,发现许多自动生成的代码读不懂(不须懂),尝试qt后感觉人生迎来了希望,看了推荐的视频与教程稍微了解 ...
- 【Ansible 文档】【译文】Windows 支持
see also:List of Windows Modules Windows Support Windows 支持 Windows: How Does It Work Windows:如何工作 正 ...
- OpenCV——反向投影(定位模板图像在输入图像中的位置)
反向投影: #include <opencv2/opencv.hpp> #include <iostream> using namespace cv; using namesp ...
- Fiddler-http检测调试工具
Fiddler是最强大最好用的Web调试工具之一,它能记录所有客户端和服务器的http和https请求,允许你监视,设置断点,甚至修改输入输出数据. 使用Fiddler无论对开发还是测试来说,都有很大 ...
- A Theoretical Analysis of Feature Pooling in Visual Recognition
这篇是10年ICML的论文,但是它是从原理上来分析池化的原因,因为池化的好坏的确会影响到结果,比如有除了最大池化和均值池化,还有随机池化等等,在eccv14中海油在顶层加个空间金字塔池化的方法.可谓多 ...
- 设置ssh key后push为什么还要输入用户名和密码
$ git push Username for 'https://github.com': Password for 'https://Username@github.com': Counting o ...