集交集基数的快速近似算法

Fast approximate algorithm for cardinality of sets intersection

我有一个池集(大小为池 n),所有集都不适合 RAM。我只能适应一小部分,比如所有集合的 1-5% 到 RAM 中。

问题是给定查询集 Q 我需要 return 与 Q 相交的最大基数的前 k 个集。

  1. 假设 Q 来自同一个集合池。
  2. 一般Q

k很小,以百为单位,而n以亿为单位。所有集合中的区域元素总数也以数亿计。

我做了一些将集合表示为布隆过滤器的实验。因为集合大小变化很大,所以我必须使用非常大的 bloomfilters,这是低效的(bloomfiltes 占用原始数据集的 5x space)。来自 https://github.com/jaybaird/python-bloomfilter 的自适应 bloomfiter 仅产生 3-5 倍的数据集压缩,因此这仍然几乎不可行。

K-Minimum Values 数据结构的内存效率极高。与布隆过滤器不同,它不提供成员资格测试,仅提供集合论运算和基数估计。

可能对你有用,这取决于你的集合的基数和你的容错能力。

如果将查询集 Q 作为散列保存在内存中 table,则无需同时将所有其他集合保存在内存中。您可以一个接一个地计算每个集合的交集基数。只需将一个集合加载到内存中,计算其与 Q 的交集的基数,最后再次将其从内存中删除。

将所有集合一起保存在一个布隆过滤器中,其中包含 (setId, value) 形式的键。这将必须能够处理所有集合的并集大小的集合,这可以防止您将小集合存储在适合非常大集合的布隆过滤器中。

其次,出于您的目的,您可能会接受非常大的错误率,这再次让布隆过滤器收缩。错误率为 1% 的布隆过滤器需要每个元素 9.58505837736744... 位。错误率为 10% 的布隆过滤器每个元素需要 4.79252918868372 位。但是如果你有 10% 的错误率,在 400 个元素的集合上,在纠正预期的误报后,你可以得到一个 95% 的答案在正确答案的 3% 以内。将过滤器尺寸缩小 2 倍可能是可以接受的。 (Q越大,相对误差越小。)

如果在这两种技术之间,布隆过滤器仍然太大,那么也许您应该考虑将数据分布在多台机器上...

其实,我已经找到了解决办法。通过将 hyperloglog 和 minhash 相乘给出交集,并且可以使用 LSH 有效地存储 minhashes。此处有更多详细信息:http://infolab.stanford.edu/%7Eullman/mmds/ch3.pdf