Bloom Filter:海量数据的HashSet

news/2024/9/17 16:43:48

Bloom Filter一般用于数据的去重计算,近似于HashSet的功能;但是不同于Bitmap(用于精确计算),其为一种估算的数据结构,存在误判(false positive)的情况。

1. 基本原理

Bloom Filter能高效地表征数据集合\(S = \lbrace x_1 ,x_2 ,...,x_n \rbrace\),判断某个数据是否属于这个集合。其基本思想如下:用长度为\(m\)的位数组\(A\)来存储集合信息,同时是有\(k\)个独立的hash函数\(h_i(1\le i \le k)\)将数据映射到位数组空间。具体流程如下:

  1. 将长度为\(m\)的位数组全置为0;
  2. 对于数据\(x \in S\),依次计算其\(k\)个hash函数值\(h_i(x)=w,且1\le i \le k, 1 \le w \le m\),将位数组中的第\(a\)位bit置为1,即A[w]=1.

399159-20160918161221153-629571601.png

当查询数据\(y\)是否属于集合\(S\)时,计算其\(k\)个hash函数值,如果\(h_i(y)\)对应的位数组均为1,则数据\(y\)属于集合\(S\);反之,则不属于。

399159-20160918161227794-1758339683.png

2. 相关计算

在上述判断中,可能存在误判(false positive, FP),比如某数的\(k\)个hash函数值可能属于集合\(S\)中某几个数\(k\)个hash函数值组成的集合。显然,误判率跟集合大小\(n\)、位数组大小\(m\)、hash函数的个数\(k\)有关;在其他条件不变的情况下,若\(n\)越大(\(m\)越小,或\(k\)越多),则误判率越高。误判率估算公式如下:

\[ P_{fp} \approx (1-e^{-kn/m})^k \]

在实际的场景中,常常是已知集合大小\(n\),预设误判率\(P_{fp}\),需要计算位数组大小\(m\)、hash函数的个数\(k\)。通过一系列的数学推导,可得到如下公式:

\[ m= - \frac{n\ln P_{fp}}{(\ln 2)^2} \]

\[ k=\frac{m}{n}\ln 2 \]

详细的数学推导可参看相关文档。

3. 实战

Bloom Filter的Java实现有Guava、stream-lib,Scala实现有breeze、bloom-filter-scala。采用breeze库的Distinct Count实现如下:

import breeze.util.BloomFilterval bf = BloomFilter.optimallySized[Int](5, 0.01)
val arr = Array(1, 3, 4, 5, 1, 2, 6, 3, 1)
var cnt = 0
arr.foreach { t =>bf.contains(t) match {case false => cnt += 1; bf.+=(t)case _ =>}
}
println(arr.distinct.length) // 6
println(cnt) // 6

从上面的Scala代码中,不难发现:在Distinct Count计算过程中,需要定义一个global变量,逐一用于对每个不属于集合元素进行计算。显然,在分布式计算中,这种方法不太适用;因为global变量没法做到实时的传递更新。因此,另一种估算算法HyperLogLog,拥有优秀的可加性、易于并行化,在大数据的场景下应用广泛——Spark、Kylin中的近似Distinct Count便是基于此。

4. 参考资料

[1] Broder, Andrei, and Michael Mitzenmacher. "Network Applications of Bloom Filters: A Survey." Internet Mathematics 1.4 (2011): 485-509.
[2] 张俊林, 《大数据日知录》.


http://lihuaxi.xjx100.cn/news/243777.html

相关文章

你不怕他离职吗?

图片来自“wikiart” 这是我同事在晚上11点多跟我聊微信时问起的一个问题,我觉得这个问题还是挺有代表性的,所以我还是决定就这个问题展开聊聊我对这句话的看法。 我同事之所以这么说,是因为他的组员,也就是问题中的那个他&#x…

Nmap (网络映射器)好东西啊

2019独角兽企业重金招聘Python工程师标准>>> Nmap (网络映射器)是由 Gordon Lyon设计,用来探测计算机网络上的主机和服务的一种安全扫描器。为了绘制网络拓扑图,Nmap的发送特制的数据包到目标主机,然后对返…

【转载】有软件开发,就要有软件测试!

移动app市场很大且还在不断发展。有多大呢?两个最流行的移动平台,iOS和Android,为我们提供了一些数据:▪▪ 1,250,000个可供下载的 app(去年增长了85%)▪▪ 63,000个新提…

零基础怎么学UI设计

互联网的快速发展,给很多企业和求职人员有了更多的创业和工作机会,近几年,UI设计行业招聘需求人数就在不断上涨,越来越多的人想转行做UI设计。那么零基础怎么学UI设计?有哪些简单有效的学习方法?我们来看看下面的详细介绍。 零基…

Golang微服务开发实践

github: github.com/yun-mu/Micr… 微服务概念学习:可参考 Nginx 的微服务文章 微服务最佳实践:可参考 微服务最佳实践 demo 简介 服务: consignment-service(货运服务)user-service(用户服务)l…

导航属性(外键)

第一种方法:(不灵活)1.一个学生类型只能保存一个年级对象//一个年级对象能保存多个学生对象//实际开发时单向比较多5.在年级对象类中根据年级编号来查询年级对象//写在if前面代表察回来值即使是空也没问题 因为null6.创建学生编号的时候new 一个 年级对象并且调用年级对象的id将…

Web前端学习6个有效果软件,你值得拥有!

想要让程序猿可以快速有效的工作,辅助工具是非常有必要的,不管是刚学习web前端技术的同学还是已经进入工作的学员,都需要学习和掌握一些Web前端开发工具和软件,Web前端学习6个有效果软件,你值得拥有! Web前端学习6个有…

Linux:检查当前运行级别的五种方法

2019独角兽企业重金招聘Python工程师标准>>> 运行级就是Linux操作系统当前正在运行的功能级别。存在七个运行级别,编号从0到6。系统可以引导到任何给定的运行级别。运行级别由数字标识。每个运行级别指定不同的系统配置,并允许访问不同的进程…