BloomFilter原理学习

news2024/10/5 12:37:57

文章目录

  • BloomFilter简单介绍
  • BloomFilter中的数学知识
    • fpp(误判率/假阳性)的计算
    • k的最小值
    • 公式总结
  • 编程语言实现
    • golang的实现
      • [已知n, p求m和k](https://github.com/bits-and-blooms/bloom/blob/master/bloom.go#L133)
  • 参考

BloomFilter简单介绍

BloomFilter我们可能经常听到也在使用, 它的特点是如果判断结果为"不存在", 则一定不存在; 如果判断为存在, 则可能存在. 如下图示例说明当我们判断z元素存在时, 其实是不存在的, 即存在有概率性.
BloomFilter原理示意

如上图, 长为m=16的二进制向量, 初始全为0; k=3(即添加一个元素需要将3个bit设置为1), 对n=3个元素进行添加操作.

BloomFilter几个关键量定义:
m: 二进制向量大小(多少个二进制位)
n: 要存放的元素个数
k: 哈希函数的个数, 或者说每添加一个元素都要进行k次计算
fpp或者简写为p: 误判率(false positive rate), 即 使用bloomfilter判断为存在时, 但实际不存在的概率

BloomFilter中的数学知识

fpp(误判率/假阳性)的计算

BloomFilter主要的数学原理是: 在某一范围内( 1 < = x < = m ) 1<=x<=m) 1<=x<=m)(x为整数, m通常是很大的, 如 1 0 6 级别 10^6级别 106级别), 任意选取两个整数 i , j , i 和 j 可重复选取 i, j, i和j可重复选取 i,j,ij可重复选取, 则其相等的概率是非常小的: m m 2 = 1 m \dfrac{m}{m^2}=\dfrac{1}{m} m2m=m1

我们假定hash计算是均匀的, 即每次hash会随机地将m位中的一位设置为1. 那么:

  • 一次hash计算(如 h 1 ( x ) h1(x) h1(x))后, 任一位被 置为1 的概率为: 1 m \dfrac{1}{m} m1
  • 一次hash计算(如 h 1 ( x ) h1(x) h1(x))后, 任一位 还是0(即未被置为1) 的概率为: 1 − 1 m 1 - \dfrac{1}{m} 1m1
  • 添加一个元素(如bloomFilter.Add(x), 即执行k次hash)后, 任一位还是0的概率为: ( 1 − 1 m ) k (1 - \dfrac{1}{m})^k (1m1)k
  • 添加n个元素后(如上图中的n=3个元素:x,y,z), 任一位还是0的概率为: ( 1 − 1 m ) k n (1 - \dfrac{1}{m})^{kn} (1m1)kn , 任一位为1的概率为 1 − ( 1 − 1 m ) k n 1- (1 - \dfrac{1}{m})^{kn} 1(1m1)kn
  • 如果将1个新的元素,添加到已存在n个元素的BloomFilter中,则任一位已经为1的概率与上面相同,为: 1 − ( 1 − 1 m ) k n 1- (1 - \dfrac{1}{m})^{kn} 1(1m1)kn .
    那么添加这个新元素时, k个比特都为1(相当于新元素和已有元素已经分不清了)的概率(此即为新插入元素的误识别率)为:
    p = [ 1 − ( 1 − 1 m ) k n ] k p = [1- (1 - \dfrac{1}{m})^{kn}]^{k} p=[1(1m1)kn]k

通常来说, m是一个非常大的数(1MiB内存就有 2 20 × 8 ≈ 800 万 2^{20}\times{8}\approx 800万 220×8800个bit), 并且我们有: lim ⁡ x → ∞ ( 1 + x ) 1 x = e { \lim\limits_{x \to \infin} (1+x)^{\frac{1}{x}} = e} xlim(1+x)x1=e
那么在工程实践中, 可以认为p的近似值为:
p = [ 1 − ( 1 − 1 m ) k n ] k = [ 1 − ( 1 − 1 m ) − m × − k n m ] k ≈ ( 1 − e − k n m ) k ( 当 m 很大时 , 将 − 1 m 看作 x ) \begin{aligned} p &= [1- (1 - \dfrac{1}{m})^{kn}]^{k} \\ &= [1- (1 - \dfrac{1}{m})^{-m\times\frac{-kn}{m}}]^{k} \\ &\approx (1-e^{-\frac{kn}{m}})^{k} \enspace (当m很大时, 将 -\dfrac{1}{m}看 作x) \end{aligned} p=[1(1m1)kn]k=[1(1m1)m×mkn]k(1emkn)k(m很大时,m1看作x)

k的最小值

计算过程参考: https://cs.stackexchange.com/questions/132088/how-is-the-optimal-number-of-hashes-is-derived-in-bloom-filter

已经遗忘的知识:

  1. 求导公式: ( ln ⁡ x ) ′ = 1 x (\ln{x})^{'} = \dfrac{1}{x} (lnx)=x1
  2. 求导公式: ( e n x ) ′ = n e n x (\bold{e}^{nx})^{'} = n\bold{e}^{nx} (enx)=nenx

在某些情况下, 我们对n, m, 的值可以给一个估算值, 以此来获得最小的p(即尽可能准确判断), 那么k就是一个变量了, 问题就变为求 ( 1 − e − k n m ) k (1-e^{-\frac{kn}{m}})^{k} (1emkn)k的最小值.
f ( k ) = ( 1 − e − k n m ) k f(k)=(1-e^{-\frac{kn}{m}})^{k} f(k)=(1emkn)k, 那么
两边取对数有 : ln ⁡ f ( k ) = ln ⁡ ( 1 − e − k n m ) k = k ln ⁡ ( 1 − e − k n m ) 设 g ( k ) = k ln ⁡ ( 1 − e − k n m ) , 那么 : g ′ ( k ) = ln ⁡ ( 1 − e − k n m ) + k n m e − k n m 1 − e − k n m 令 x = e − k n m , x ∈ ( 0 , 1 ) , 那么有 h ( x ) = ln ⁡ ( 1 − x ) − x 1 − x ln ⁡ x ( 注意 k 用 − m n l n x 替换 ) = ( 1 − x ) ln ⁡ ( 1 − x ) − x ln ⁡ x 1 − x ( x ∈ 0 , 1 ) \begin{aligned} & 两边取对数有: \\ & \ln f(k)=\ln (1-e^{-\frac{kn}{m}})^{k} = k \ln(1-e^{-\frac{kn}{m}}) \\ & 设 g(k) = k\ln{(1-e^{-\frac{kn}{m}})}, 那么:\\ & g{'}(k) = \ln{(1-e^{-\frac{kn}{m}})} + k\dfrac{\frac{n}{m}e^{-\frac{kn}{m}}}{1-e^{-\frac{kn}{m}}} \enspace \\ & 令 x = e^{-\frac{kn}{m}}, x \in(0, 1), 那么有 \\ & h(x) = \ln(1-x) - \dfrac{x}{1-x} \ln x \enspace (注意k用-\dfrac{m}{n}lnx替换) \\ & \enspace \enspace \enspace \enspace = \dfrac{(1-x) \ln(1-x)-x \ln x}{1-x} \enspace (x\in{0, 1}) \end{aligned} 两边取对数有:lnf(k)=ln(1emkn)k=kln(1emkn)g(k)=kln(1emkn),那么:g(k)=ln(1emkn)+k1emknmnemknx=emkn,x(0,1),那么有h(x)=ln(1x)1xxlnx(注意knmlnx替换)=1x(1x)ln(1x)xlnx(x0,1)

h ( x ) = ( 1 − x ) ln ⁡ ( 1 − x ) − x ln ⁡ x 1 − x ( x ∈ 0 , 1 ) h(x) = \dfrac{(1-x)\ln(1-x)-x \ln x}{1-x} \enspace (x\in{0, 1}) h(x)=1x(1x)ln(1x)xlnx(x0,1), 不难看出:

  1. x = 1 2 时 , h ( x ) = 0 x=\dfrac{1}{2}时, h(x)=0 x=21,h(x)=0
  2. x > 1 2 时 , h ( x ) < 0 x>\dfrac{1}{2}时,h(x)<0 x>21,h(x)<0
  3. x < 1 2 时 , h ( x ) > 0 x<\dfrac{1}{2}时,h(x)>0 x<21,h(x)>0

站在巨人的肩膀上, 我们可以直接在这里看:
显然在 x ∈ ( 0 , 1 ) 范围内 , 当 x = 0.5 时 , h ( x ) 最小 x\in(0, 1)范围内, 当x=0.5时, h(x)最小 x(0,1)范围内,x=0.5,h(x)最小, 此时 k = m n l n 2 k=\dfrac{m}{n}ln2 k=nmln2

在这里插入图片描述
也就是说:
k < m n l n 2 k <\dfrac{m}{n}ln2 k<nmln2时(想象k非常接近0), x = e − k n m x = e^{-\frac{kn}{m}} x=emkn会非常接近1, 此时 x > 1 2 x>\dfrac{1}{2} x>21,
h ( x ) < 0 h(x)<0 h(x)<0 ⇒ f(k)在变小;
k > m n l n 2 k >\dfrac{m}{n}ln2 k>nmln2时(想象k非常接近0), x = e − k n m x = e^{-\frac{kn}{m}} x=emkn会非常接近0, 此时 x < 1 2 x<\dfrac{1}{2} x<21,
h ( x ) > 0 h(x)>0 h(x)>0 ⇒ f(k)在变大;
所以 k = m n l n 2 k=\dfrac{m}{n}ln2 k=nmln2时会使得 f ( k ) f(k) f(k)最小, 即此时p最小.

公式总结

  1. 误判率公式: p = [ 1 − ( 1 − 1 m ) k n ] k p = [1- (1 - \dfrac{1}{m})^{kn}]^{k} p=[1(1m1)kn]k
  2. 误判率近似公式(当m很大时): p ≈ ( 1 − e − k n m ) k p \approx (1-e^{-\frac{kn}{m}})^{k} p(1emkn)k
  3. 已知m, n, k的最小值(近似)为: k = m n ln ⁡ 2 ≈ 0.7 m n k=\dfrac{m}{n}\ln{2} \approx 0.7\dfrac{m}{n} k=nmln20.7nm
  4. 已知n, p, 且k取最小时, m = − n ln ⁡ p ( l n 2 ) 2 m=-\dfrac{n\ln{p}}{(ln2)^{2}} m=(ln2)2nlnp

编程语言实现

golang的实现

https://github.com/bits-and-blooms/bloom

已知n, p求m和k

func EstimateParameters(n uint, p float64) (m uint, k uint) {
	m = uint(math.Ceil(-1 * float64(n) * math.Log(p) / math.Pow(math.Log(2), 2)))
	k = uint(math.Ceil(math.Log(2) * float64(m) / float64(n)))
	return
}

参考

  1. https://en.wikipedia.org/wiki/Bloom_filter
  2. https://cs.stackexchange.com/questions/132088/how-is-the-optimal-number-of-hashes-is-derived-in-bloom-filter

(完)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/389869.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

瑞吉外卖——day2

目录 一、新增员工 二、查询分页数据 三、启用、禁用员工账户、编辑员工信息 一、新增员工 点击左上角新增员工 页面如下&#xff1a; 我们随便填数据 &#xff0c;点击保存&#xff0c;请求的地址如下 返回前端可以看到请求方式为Post 在employeeController中编写对应的代…

Elasticsearch:图片相似度搜索的 5 个技术组成部分

作者&#xff1a;Radovan Ondas&#xff0c;Bernhard Suhm 在本系列博文的第一部分中&#xff0c;我们介绍了图像相似度搜索&#xff0c;并回顾了一种可以降低复杂性并便于实施的高级架构。 此博客解释了实现图像相似性搜索应用程序所需的每个组件的基本概念和技术注意事项。 学…

Python采集本地二手房,一键知晓上万房源信息

前言 大家早好、午好、晚好吖 ❤ ~欢迎光临本文章 所以今天教大家用Python来采集本地房源数据&#xff0c;帮助大家筛选好房。 话不多说&#xff0c;让我们开始愉快的旅程吧~ 更多精彩内容、资源皆可点击文章下方名片获取此处跳转 本文涉及知识点 采集基本流程 requests 发送…

【Java】Spring Boot整合WebSocket

【Java】Spring Boot整合WebSocket WebSocket简介 WebSocket是一种协议&#xff0c;用于实现客户端和服务器之间的双向通信。它可以在单个TCP连接上提供全双工通信&#xff0c;避免了HTTP协议中的请求-响应模式&#xff0c;从而实现更高效的数据交换。WebSocket协议最初由HTM…

【计算几何】贝塞尔曲线 B样条曲线简介及其离散化 + Python C++ 代码实现

文章目录一、贝塞尔曲线二、B样条曲线三、Python 代码实现B样条曲线离散化四、C 代码实现B样条曲线离散化4.1 主要代码4.2 其余类4.3 离散效果展示&#xff08;在CAD中展示&#xff09;本文只做简介&#xff0c;关于贝塞尔曲线和B样条曲线的详细介绍&#xff0c;请参考&#xf…

unity UGUI系统梳理 - 基本布局

偷懒了&#xff0c;部分节选unity API API 1、矩形工具 为了便于布局&#xff0c;每个 UI 元素都表示为矩形。可使用工具栏中的__矩形工具 (Rect Tool)__ 在 Scene 视图中操纵此矩形。矩形工具既可用于 Unity 的 2D 功能&#xff0c;也可用于 UI&#xff0c;实际上甚至还可用…

C/C++开发,无可避免的多线程(篇三).协程及其支持库

一、c20的协程概念 在c20标准后&#xff0c;在一些函数中看到co_await、co_yield、co_return这些关键词&#xff0c;这是c20为协程实现设计的运算符。 协程是能暂停执行以在之后恢复的函数。原来我们调用一个功能函数时&#xff0c;只要调用了以后&#xff0c;就要完整执行完该…

【Kettle-佛系总结】

Kettle-佛系总结Kettle-佛系总结1.kettle介绍2.kettle安装3.kettle目录介绍4.kettle核心概念1.转换2.步骤3.跳&#xff08;Hop&#xff09;4.元数据5.数据类型6.并行7.作业5.kettle转换1.输入控件1.csv文件输入2.文本文件输入3.Excel输入4.XML输入5.JSON输入6.表输入2.输出控件…

百度Apollo规划算法——轨迹拼接

百度Apollo规划算法——轨迹拼接引言轨迹拼接1、什么是轨迹拼接&#xff1f;2、为什么要进行轨迹拼接&#xff1f;3、结合Apollo代码为例理解轨迹拼接的细节。参考引言 在apollo的规划算法中&#xff0c;在每一帧规划开始时会调用一个轨迹拼接函数&#xff0c;返回一段拼接轨迹…

Kubernetes之服务发布

学了服务发现后&#xff0c;svc的IP只能被集群内部主机及pod才可以访问&#xff0c;要想集群外的主机也可以访问svc&#xff0c;就需要利用到服务发布。 NodePort Nodeport服务是外部访问服务的最基本方式。当我们创建一个服务的时候&#xff0c;把服务的端口映射到kubernete…

【大数据AI人工智能】常见的归一化函数有哪些?分别用数学公式详细介绍

常见的归一化函数有哪些?分别用数学公式详细介绍一下。 常见的归一化函数 常见的归一化函数包括: Min-Max 归一化Z-Score 归一化Log 归一化Sigmoid 归一化下面分别介绍这些归一化函数以及它们的数学公式。 1. Min-Max 归一化 Min-Max 归一化是将原始数据线性映射到 [0,1]…

dp模型——状态机模型C++详解

状态机定义状态机顾名思义跟状态有关系&#xff0c;但到底有什么关系呢。在实际解决的时候&#xff0c;通常把状态想成节点&#xff0c;状态的转换想成有向边的有向图&#xff0c;我们来举个例子。相信大家都玩过类似枪战的游戏&#xff08;没玩过的也听说过吧&#xff09;&…

4.创建和加入通道相关(network.sh脚本createChannel函数分析)[fabric2.2]

fabric的test-network例子有一个orderer组织、两个peer组织、每个组织一个节点&#xff0c;只有系统通道&#xff08;system-channel&#xff09;&#xff0c;没有其他应用通道。我们可以使用./network.sh createChannel命令来创建一个名为mychannel的应用通道。 一、主要概念 …

【Java开发】JUC进阶 04:线程池详解

1 线程池介绍由于频繁创建销毁线程要调用native方法比较消耗资源&#xff0c;为了保证内核的充分利用&#xff0c;所以引入了线程池的概念。&#x1f4cc; 线程池优点降低资源消耗提高响应速度方便管理&#x1f4cc; 创建线程池使用Executors创建使用ThreadPoolExecutor创建&am…

Git图解-为啥是Git?怎么装?

目录 零、学习目标 一、版本控制 1.1 团队开发问题 1.2 版本控制思想 1.2.1 版本工具 二、Git简介 2.1 简介 2.2 Git环境的搭建 三、转视频版 零、学习目标 掌握git的工作流程 熟悉git安装使用 掌握git的基本使用 掌握分支管理 掌握IDEA操作git 掌握使用git远程仓…

【教程】记录Typecho Joe主题升级与Joe魔改版

目录 升级Joe 其他魔改版 Joe主题挺好看的&#xff0c;很早之前我就装了。后来官方升级了主题&#xff0c;但没有给升级教程。这里记录一下我的升级过程&#xff0c;供大家参考。 Joe Github&#xff1a;GitHub - HaoOuBa/Joe: A Theme of Typecho 升级站点&#xff1a;小锋学…

WSL2使用Nvidia-Docker实现CUDA版本自由切换

众所周知&#xff0c;深度学习的环境往往非常麻烦&#xff0c;经常不同的项目所依赖的 torch、tensorflow 包对 CUDA 的版本也有不同的要求&#xff0c;Linux 下进行 CUDA 的管理比较麻烦&#xff0c;是一个比较头疼的问题。 随着 WSL2 对物理机显卡的支持&#xff0c;Nvidia-…

用二极管和电容过滤电源波动,实现简单的稳压 - 小水泵升压改装方案

简而言之&#xff0c;就是类似采样保持电路&#xff0c;当电源电压因为电机启动而骤降时&#xff0c;用二极管避免电容电压跟着降低&#xff0c;从而让电容上连接的低功耗芯片有一个比较稳定的供电电压。没什么特别的用处&#xff0c;省个LDO 吧&#xff0c;电压跌幅太大的时候…

最详细Sql语句优化大汇总 面试必问 含解释

欢迎补充和纠正&#xff01;&#xff01;&#xff01; 目录 欢迎补充和纠正&#xff01;&#xff01;&#xff01; 基础知识 相关索引的创建 一条sql语句的执行过程 sql语句关键字的执行顺序 SQL优化 使用explain来分析Sql语句 尽量用varchar代替char 使用数值代替字符…

Vector - CAPL - 定时器函数和使用

定时器在C语言中的使用我想学习过C编程的都不会陌生&#xff0c;它能够提供延时&#xff0c;完成等待一定的时间&#xff1b;它也可以实现多线程的操作&#xff0c;并行实行某些软件功能。那在CAPL中&#xff0c;定时器又能做哪些工作呢&#xff1f;又是怎么使用的呢&#xff1…