m: 表示 Bloom Filter bit array 的长度;
k: 表示 hash 函数个数;
n: 表示插入元素的个数;
假设 hash 函数以等概率选择 bit array 的下标,那么某次 hash 后,某个特定 bit 位未被设置为 1 的概率为 1−m1。经过 k 个 hash 函数之后,该 bit 位仍未被设置为 1 的概率为:
(1−m1)k在插入 n 个元素之后,某个 bit 位仍然没有被设置为 1 的概率为:
(1−m1)kn因此在插入 n 个元素之后,某个 bit 位被设置为 1 的概率为:
p=1−(1−m1)kn对于一个不存在于集合中的元素,如果要出现误判(false positive),意味着经过 k 个 hash 函数之后,生成的 k 个下标所对应的 bit 位全部为 1,其概率为:
ε=pk=(1−(1−m1)kn)k接下来利用自然常数 e 的极限定义对上式进行简化。已知:
m→∞lim(1+mz)m=ez令 z=−1:
m→∞lim(1−m1)m=e−1当 m 足够大时,有:
(1−m1)kn=((1−m1)m)mkn≈e−mkn代入 ε 可得:
ε≈(1−e−mkn)k当 ε 最小时,k 为最优。因此需要对 ε 关于 k 求导,找到极小值点。
令 f=(1−e−mkn)k,对等式两边取对数:
g=lnf=k⋅ln(1−e−mkn)对 g 关于 k 求导(利用乘积法则):
dkdg=ln(1−e−mkn)+k⋅dkdln(1−e−mkn)对第二项应用链式法则:
dkdln(1−e−mkn)=1−e−mknmn⋅e−mkn因此:
dkdg=ln(1−e−mkn)+mkn⋅1−e−mkne−mkn令 dkdg=0(在不考虑 k 为整数的约束下寻找极值点):
ln(1−e−mkn)+mkn⋅1−e−mkne−mkn=0整理得:
−ln(1−e−mkn)=mkn⋅1−e−mkne−mkn对等式两边取指数:
1−e−mkn1=emkn⋅1−e−mkne−mkn为简化表达,令 x=e−mkn(其中 0<x<1),可得:
1−x1=(x1)1−xx⟺(1−x)−1=x−1−xx⟺(1−x)=x1−xx对等式两边取对数:
ln(1−x)=1−xx⋅lnx⟺(1−x)⋅ln(1−x)=x⋅lnx设 h(t)=t⋅lnt,上式即 h(1−x)=h(x)。由于 h(t) 在 (0,1) 上先递减后递增,且关于 t=21 对称(即 h(t)=h(1−t) 当且仅当 t=21),可得 x=21。
又因为 x=e−mkn,所以:
e−mkn=21⟺−mkn=ln21=−ln2⟺k=nmln2已知 ε≈(1−e−mkn)k,将 k=nmln2 代入。
由前面的推导,当 k 取最优值时 e−mkn=21,因此:
ε≈(1−21)nmln2=(21)nmln2对两边取自然对数:
lnε≈nmln2⋅ln21=−nm(ln2)2解出 m:
m≈−(ln2)2nlnε≈−1.44nlog2ε其中 (ln2)21≈2.08,所以也可以写成 m≈−2.08nlnε。
给定预期插入元素数 n 和可接受的误判率 ε:
- 最优 bit array 长度: m≈−(ln2)2nlnε
- 最优 hash 函数个数: k=nmln2≈−log2ε
例如,若期望误判率为 1%(ε=0.01),则每个元素约需 9.6 bits,最优 hash 函数个数约为 7。