为什么实际的误报率远低于Guava的BloomFilter中期望的误报率?

时间:2019-09-19 10:47:20

标签: guava bloom-filter false-positive

我使用的布隆过滤器具有较小的期望误报率(fpp),但得到的结果却少得多:

    BloomFilter<Long> bloomFilter = BloomFilter.create(Funnels.longFunnel(), 1_000_000, .001);
    int c = 0;
    for (int i = 0; i < 1_000_000; i ++) {
        // can replace with random.nextLong() because 1M random.nextLong() can hardly make collision
        if (!bloomFilter.put(Long.valueOf(i))) {
            // There is no duplicated elements so put returns false means false-positive
            c ++;
        }
    }
    System.out.println(c);

我希望有1000(1M * 0.001)个误报,但结果是127(如果使用大随机数,结果也将接近120,但不会接近1000)。

===更新===

这是我的考试:

desired actual    a/d 
0.3     0.12      40%
0.1     0.03      30%
0.03    0.006     20%    (guava's default fpp)
0.01    0.0017    17%
0.003   0.0004    13%
0.001   0.00012   12%
0.0003  0.00003   10%
0.0001  0.000009   9%
0.00003 0.000002   7%
0.00001 0.0000005  5%

2 个答案:

答案 0 :(得分:2)

如果过滤器中的条目较少,则误报率会较低。在测试中,您从一个空集开始计算概率,然后再添加条目。这不是正确的方法。

您首先需要将一百万个条目添加到Bloom过滤器中,然后然后计算误报概率,例如,通过检查条目是否在您未添加的集合中来。

>
for (int i = 0; i < 1_000_000; i ++) {
    bloomFilter.put(Long.valueOf(i));
}
for (int i = 0; i < 1_000_000; i ++) {
    // negative entries are not in the set
    if (!bloomFilter.mightContain(Long.valueOf(-(i + 1)))) {
        c++;
    }
}

答案 1 :(得分:0)

BloomFilter唯一的保证是,真正的假阳性概率最多为您设置的值。在某些情况下,Bloom Filter数据结构的性质可能必须向下舍入实际FPP。

在这种情况下,BloomFilter必须比您要求的要准确,否则您会很幸运。