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 年提出的二进制向量数据结构,它具有很好的空间和时间效率,被用来检测一个元素是不是集合中的一个成员. 结 构 二进制 召回率 ...
随机推荐
- 51nod 贪心算法题集
2070 最小罚款: 题意:初始有n元,每个任务有2个参数:t和w,<=t时刻前完成任务才可避免造成损失w.问:如何安排才能尽可能避免损失?一个任务执行时间是一个单位时间. 分析:任务按时间排个 ...
- 在Linux服务器上运行Jupyter notebook server教程
在Linux服务器上运行Jupyter notebook server教程 很多deep learning教程都推荐在jupyter notebook运行python代码,方便及时交互.但只在本地运行 ...
- [翻译] 提升树算法的介绍(Introduction to Boosted Trees)
[翻译] 提升树算法的介绍(Introduction to Boosted Trees) 1. 有监督学习的要素 XGBoost 适用于有监督学习问题.在此类问题中,我们使用多特征的训练数据集 \(x ...
- Mysql表类型(存储引擎)的比较
面试官问:你知道mysql有哪些存储引擎,区别是啥? 我:一脸闷逼,于是乎下来补一补,以作备查 1.和大多数数据库不同,MySQL 中有一个存储引擎的概念,针对不同的存储需求可以选择最优的存储引擎. ...
- BZOJ 1345 序列问题 单调栈
题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1345 题目大意: 对于一个给定的序列a1,…,an,我们对它进行一个操作reduce( ...
- 使用 rem 作为单位使页面自适应设备宽度
一.新建 rem.js 文件,代码如下: export default function () { document.documentElement.style.fontSize = document ...
- OpenCV——图像金字塔和图片尺寸缩放
- OpenCV——漫水填充
- Python2.7-fractions
fractions 模块,提供分数格式存储数据,没多大用处,除了模块里的最大公约数函数 gcd(a,b) 模块类和方法: fractions.Fraction(numerator=0, denomin ...
- SNAT和DNAT
1.SNAT iptables防火墙 Centos6.6 64位 iptables 内网:eth0 172.16.4.1 外网:eth 112.112.112.112/24 当有用户访问公网时,修改用 ...