Bloom Filter理解

本文介绍了Bloom Filter,一种用于大数据量时判断元素是否存在集合中的数据结构,以及它的优化形式——计数布隆过滤器。Bloom Filter通过多个哈希函数避免BitSet的Hash碰撞问题,提高空间效率。尽管可能会产生假阳性,但在特定场景如URL去重、邮件黑名单、FTRL算法等有广泛应用。计数布隆过滤器则能进行元素计数,进一步增强其功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

解决的问题

1、BitSet/布隆过滤器: 大数据量的时候, 判断一个元素是否在一个集合中
2、计数布隆过滤器:大数据量的时候,针对元素进行计数

Bitset

原理

int => 4个字节 = 32位
long => 8个字节 = 64位

  • 一个很长的二进制向量,每一个bit为初始为0
  • 添加元素时,将这个元素index对应的位置为1
  • 查询元素时,如果这个元素作为index对应位为1,则说明这个元素存在

缺点

Hash碰撞

  • 当样本分布极度不均匀的时候,bitset会造成很大空间上的浪费。举个例子,比如你有10个数,分别是1、2、3、4、5、6、7、8、99999999999;那么你不得不用99999999999个bit位去实现你的BitSet,而这个BitSet的中间绝大多数位置都是0,并且永远不会用到,这显然是极度不划算的

  • 当元素不是整型的时候,bitset就不适用了。比如爬虫程序的url,如果想用bitset做去重的话,得先把url转换成int型,在转换的过程中难免某些url会计算相同的int值,于是bitset的准确性就会降低

布隆过滤器

思想

目的是为了解决bitset的缺点,使hash值尽可能的均匀分布,减少hash冲突的概率

  • 多个Hash,增大随机性,减少hash碰撞的概率
  • 扩大数组范围,使hash值均匀分布,进一步减少hash碰撞的概率

实现步骤

  • 初始化:开一个足够大的 boolean 数组,初始值都是 false。
  • 插入一个元素:通过k个哈希函数,计算出元素的k个哈希值,对 boolean 数组的长度取模之后,标记对应的k个位置上的值为 true。
  • 查询一个元素:通过同样的k个哈希函数,在 boolean 数组中取出对应的k个位置上的值。如果都是 true,则表示该元素可能存在,如果有一个 false,则表示一定不存在。

比如你有10个Url,你完全可以创建一长度是100bit的数组,然后对url分别用5个不同的hash函数进行hash,得到5个hash后的值,这5个值尽可能的保证均匀分布在100个bit的范围内。然后把5个hash值对应的bit位都置为1,判断一个url是否已经存在时,一次看5个bit位是否为1就可以了,如果有任何一个不为1,那么说明这个url不存在.

这里需要注意的是,如果对应的bit位值都为1,那么也不能肯定这个url一定存在,这个是BloomFilter的特点之一

准确性

参考:https://en.wikipedia.org/wiki/Bloom_filter#Probability_of_false_positives

应用

1、FTRL算法判断特征是否值得加入训练(通过计数布隆过滤器)
2、黑名单。
比如邮件黑名单过滤器,判断邮件地址是否在黑名单中
3、排序(仅限于bitSet)。
4、网络爬虫,判断某个URL是否已经被爬取过

计数布隆过滤器

因为在学习FTRL算法的时候,FTRL工程部署时使用计数型布隆过滤器来做memory saving,所以这里加深一下对计数布隆过滤器的理解。

思想

基于标准的 BloomFilter 稍加改动,把存储所用的 boolean 数组改为 int 数组,就成为了可以计数的 BloomFilter

实现步骤

  • 初始化:开一个足够大的 int 数组,初始值都是 0。
  • 插入一个元素:通过k个哈希函数,计算出元素的k个哈希值,对 int 数组的长度取模之后,将对应的k个位置上的值都加一
  • 查询一个元素的出现次数:通过同样的k哈希函数,在 int 数组中取出对应的k个位置上的值。并取其中的最小值来作为该元素的出现次数预估

参考资料

https://www.veaxen.com/%E7%AE%97%E6%B3%95-%E5%B8%83%E9%9A%86%E8%BF%87%E6%BB%A4%E5%99%A8%EF%BC%88bloom-filter%EF%BC%89.html
https://aaronice.gitbooks.io/lintcode/bloom-filter.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值