Algorithm 使用bloom过滤器的优势是什么?

Algorithm 使用bloom过滤器的优势是什么?,algorithm,data-structures,bloom-filter,Algorithm,Data Structures,Bloom Filter,我在读bloom过滤器,它们看起来很傻。使用bloom过滤器可以完成的任何事情,都可以使用单个哈希函数而不是多个哈希函数在更少的空间内、更高效地完成,或者看起来就是这样。为什么要使用bloom过滤器?它有什么用处?bloom过滤器在生物信息学中非常有用。与使用常规散列相比,它们可以更节省空间,特别是当您正在处理的字符串的大小可以是数亿个字母,而字母表非常小,即{a,G,T,C}。它们通常用于评估基因组中是否存在某个k-mer。有一个例子,一个用于相关的东西 编辑: 多个哈希函数用于最小化误报。希

我在读bloom过滤器,它们看起来很傻。使用bloom过滤器可以完成的任何事情,都可以使用单个哈希函数而不是多个哈希函数在更少的空间内、更高效地完成,或者看起来就是这样。为什么要使用bloom过滤器?它有什么用处?

bloom过滤器在生物信息学中非常有用。与使用常规散列相比,它们可以更节省空间,特别是当您正在处理的字符串的大小可以是数亿个字母,而字母表非常小,即{a,G,T,C}。它们通常用于评估基因组中是否存在某个k-mer。有一个例子,一个用于相关的东西

编辑:

多个哈希函数用于最小化误报。希望是在所有k-hash函数之间,每个值在位数组中与其他所有可能值相比都具有唯一的签名。然而,假阳性确实存在,但可以将其最小化到可管理的水平。使用此技术,可以独立地对元素大小进行散列。搜索它们时,使用每个哈希函数并进行检查,以确保它们的位值均为1

与人类基因组相比,元素大小的增加会显著增加哈希表的大小(表大小为4*4k)。这是假设您使用2位/字母对元素进行编码。

来自:

布卢姆过滤器有一个强大的空间 与其他数据结构相比的优势 用于表示集合,例如 自平衡二叉搜索树, 尝试、哈希表或简单数组 或条目的链接列表。最 其中至少需要存储 数据项本身,它可以 需要从一个小数字到任何地方 对于小整数,将位转换为 任意位数,如 字符串(尝试)是一个例外,因为 它们可以共享存储空间 前缀相等的元素)。联系 结构会产生额外的线性 指针的空间开销。盛开 具有1%错误和最佳 另一方面,k的值, 每分钟只需要大约9.6位 元素-不考虑元素的大小 元素。这个优势来了 部分是因为它的紧凑性,遗传的 来自数组,部分来自它的 概率性质。如果1%的错误 阳性率似乎太高了 每次我们为每个元素添加大约4.8位 我们把它减少了十倍

我很清楚

bloom过滤器本身不存储元素,这是关键点。您不使用bloom过滤器来测试元素是否存在,而是使用它来测试它是否确实存在,因为它保证不会出现假阴性。这使您不必为集合中不存在的元素(例如查找它们的磁盘IO)做额外的工作

所有这些都比哈希表(对于大型数据集,它可能部分位于磁盘上)占用的空间要少得多。尽管可以将bloom过滤器与哈希表等结构结合使用,但一旦确定元素有可能存在,就可以使用bloom过滤器

因此,一个示例使用模式可能是:

磁盘上有大量数据--您可以决定需要的错误范围(例如1%),它规定了m的值。然后确定最佳k(根据文中给出的公式)。您可以从此磁盘绑定数据填充筛选器一次

现在你有了RAM中的过滤器。当您需要处理某些元素时,您可以查询您的过滤器,以查看它是否有可能存在于您的数据集中。如果没有,就不会做额外的工作。无磁盘读取等(如果是散列或树等,则必须执行此操作)


否则,如果过滤器说“是的,它在那里”,则有1%的可能性是错误的,因此您需要做必要的工作来找出错误。99%的时候,它真的会在那里,所以这项工作不是白费力气。

如果Bloom筛选器返回某个项目是集合的成员,则有一定的误报概率。如果只使用一个散列函数来表示集合中的成员身份,则误报概率将高于使用多个散列函数。

Alex对此进行了很好的解释。对于那些还没有完全掌握的人,希望这个例子能帮助你理解:

假设我在Chrome团队中为Google工作,我想在浏览器中添加一个功能,通知用户输入的url是否是恶意url。所以我有一个大约一百万个恶意URL的数据集,这个文件的大小大约是25MB。由于大小相当大(与浏览器本身的大小相比很大),我将这些数据存储在远程服务器上

案例1:我将哈希函数与哈希表一起使用。我决定使用一个高效的哈希函数,并通过哈希函数运行所有100万个URL以获得哈希键。然后,我制作一个哈希表(数组),其中哈希键将为我提供放置该URL的索引。现在,一旦我散列并填充了散列表,我就会检查它的大小。我已将所有100万个URL及其键存储在哈希表中。因此,大小至少为25MB。此哈希表由于其大小将存储在远程服务器上。当用户出现并在地址栏中输入URL时,我需要检查它是否是恶意的。因此,我通过散列函数运行URL(浏览器本身可以做到这一点),并获得该URL的散列键。现在,我必须使用该散列键向远程服务器发出请求,以检查具有该特定键的散列表中的特定URL是否与用户输入的内容相同。如果是,则是恶意的,如果不是,则不是恶意的。因此,每次用户输入URL时,都必须向远程服务器发出请求,以检查它是否是恶意URL。这会花费很多时间,因此会使我的浏览器速度变慢<