我正在阅读绽放过滤器,它们看起来很傻。使用Bloom Bloom过滤器可以完成的任何事情,都可以使用单个哈希函数而不是多个哈希函数在更少的空间内更有效地完成,或者就是这样。为什么要使用布隆过滤器,它有什么用?
我正在阅读绽放过滤器,它们看起来很傻。使用Bloom Bloom过滤器可以完成的任何事情,都可以使用单个哈希函数而不是多个哈希函数在更少的空间内更有效地完成,或者就是这样。为什么要使用布隆过滤器,它有什么用?
Answers:
从维基百科:
与其他表示集的数据结构相比,Bloom筛选器在空间上具有很大的优势,例如用于自平衡二进制搜索树,尝试,哈希表或简单数组或条目的链接列表的集合。其中大多数要求至少存储数据项本身,这可能需要从少量位(对于小整数)到任意位数(例如对于字符串)而言的任何地方(尝试是例外,因为它们可以在具有相同前缀的元素)。链接的结构会为指针带来额外的线性空间开销。另一方面,具有1%误差和k的最佳值的Bloom滤波器每个元素仅需要9.6位-不管元素的大小如何。这种优势部分是由于其紧凑性(继承自数组,部分是由于其概率性质。如果1%的误报率似乎太高,则每次我们为每个元素增加4.8位时,我们将其降低十倍。
我很清楚
Bloom过滤器不存储元素本身,这是关键。您无需使用Bloom筛选器来测试是否存在某个元素,而是使用它来测试它是否肯定不存在,因为它可以确保不会出现假阴性。这样,您就不必为集合中不存在的元素(例如,用于查找它们的磁盘IO)做额外的工作。
而且所有空间都比哈希表之类的要少得多(对于大型数据集,哈希表可能会部分地位于磁盘上)。尽管可以将Bloom过滤器与哈希表之类的结构结合使用,但是一旦确定该元素有出现的机会。
因此,示例使用模式可能是:
您在磁盘上有很多数据-您决定要确定的错误界限(例如1%),该界限规定了m的值。然后确定最佳k(根据文章中给出的公式)。您一次从此磁盘绑定数据填充过滤器。
现在,您已将筛选器放入RAM。当您需要处理某些元素时,可以查询过滤器以查看它是否有可能存在于数据集中。如果没有,则不会进行任何额外的工作。没有磁盘读取,等等。(如果它是哈希或树,则必须这样做)。
否则,如果过滤器显示“是的,则在其中”,则有1%的可能性是错误的,因此您必须进行必要的工作才能找出答案。99%的时间,它确实会在那儿,所以这项工作并非一无是处。
亚历克斯解释得很好。对于那些仍不太了解它的人,希望这个例子可以帮助您理解:
假设我在Chrome小组中为Google工作,并且想向浏览器添加一项功能,该功能可以通知用户输入的网址是否是恶意网址。因此,我有大约100万个恶意URL的数据集,此文件的大小约为25MB。由于大小很大(与浏览器本身的大小相比很大),因此我将这些数据存储在远程服务器上。
情况1:我将哈希函数与哈希表一起使用。我决定使用高效的哈希函数,并通过哈希函数运行所有100万个url以获取哈希键。然后,我创建一个哈希表(一个数组),其中哈希键将为我提供放置该URL的索引。因此,现在一旦对哈希表进行哈希处理并填满,就可以检查其大小。我已经将所有100万个URL及其密钥存储在哈希表中。因此大小至少为25 MB。由于哈希表的大小,该哈希表将存储在远程服务器上。当用户出现并在地址栏中输入URL时,我需要检查它是否是恶意的。因此,我通过哈希函数运行URL(浏览器本身可以执行此操作),并且获得了该URL的哈希键。现在,我必须使用该哈希键向远程服务器发出请求,检查具有特定键的哈希表中的特定URL是否与用户输入的URL相同。如果是,则表示是恶意的,如果不是,则表示不是恶意的。因此,每次用户输入URL时,都必须向远程服务器发出请求,以检查它是否为恶意URL。这将花费大量时间,从而使我的浏览器变慢。
情况2:我使用布隆过滤器。一百万个URL的整个列表通过使用多个哈希函数的Bloom筛选器运行,并且各个位置被标记为1(以0组成的庞大数组)。假设我们要使用布隆过滤器计算器将误报率设为1%(http://hur.st/bloomfilter?n=1000000&p=0.01),则所需的布隆过滤器的大小仅为1.13 MB。这样的小尺寸是可以预期的,因为即使数组的大小很大,我们也只存储1或0,而不存储哈希表中的URL。该数组可以视为位数组。也就是说,由于我们只有两个值1和0,因此可以设置单个位而不是字节。这样可以减少占用空间8倍。这个1.13 MB的bloom过滤器由于体积小,可以存储在Web浏览器中!因此,当用户出现并输入URL时,我们只需应用所需的哈希函数(在浏览器本身中),并检查Bloom过滤器(存储在浏览器中)中的所有位置。任何位置的0值都告诉我们该URL绝对不在恶意URL列表中,用户可以自由进行。因此,我们没有呼叫服务器,因此节省了时间。值为1表示URL可能在恶意URL列表中。在这些情况下,我们将调用远程服务器,在那儿,我们可以像在第一种情况中一样,使用带有某些哈希表的其他哈希函数来检索并检查URL是否实际存在。在大多数情况下,URL不太可能是恶意的,因此浏览器中的小型Bloom过滤器指出了这一点,从而避免了对远程服务器的调用,从而节省了时间。仅在某些情况下,如果Bloom筛选器告诉我们URL MIGHT是恶意的,则仅在这些情况下,我们才对服务器进行调用。那“ MIGHT”是99%正确的。在这些情况下,我们将调用远程服务器,在那儿,我们可以像在第一种情况中一样,使用带有某些哈希表的其他哈希函数来检索并检查URL是否实际存在。在大多数情况下,URL不太可能是恶意的,因此浏览器中的小型Bloom过滤器指出了这一点,从而避免了对远程服务器的调用,从而节省了时间。仅在某些情况下,如果Bloom筛选器告诉我们URL MIGHT是恶意的,则仅在这些情况下,我们才对服务器进行调用。那“ MIGHT”是99%正确的。在这些情况下,我们将调用远程服务器,在那儿,我们可以像在第一种情况中一样,使用带有某些哈希表的其他哈希函数来检索并检查URL是否实际存在。在大多数情况下,URL不太可能是恶意的,因此浏览器中的小型Bloom过滤器指出了这一点,从而避免了对远程服务器的调用,从而节省了时间。仅在某些情况下,如果Bloom筛选器告诉我们URL MIGHT是恶意的,则仅在这些情况下,我们才对服务器进行调用。那个“ MIGHT”是99%正确的。浏览器中的小布鲁姆过滤器可以识别出来,从而避免了对远程服务器的调用,从而节省了时间。仅在某些情况下,如果Bloom筛选器告诉我们URL MIGHT是恶意的,则仅在这些情况下,我们才对服务器进行调用。那个“ MIGHT”是99%正确的。浏览器中的小Bloom过滤器可以解决这一问题,从而避免了对远程服务器的调用,从而节省了时间。仅在某些情况下,如果Bloom筛选器告诉我们URL MIGHT是恶意的,则仅在这些情况下,我们才对服务器进行调用。那个“ MIGHT”是99%正确的。
因此,通过在浏览器中使用小的Bloom过滤器,我们节省了很多时间,因为我们不需要为输入的每个URL进行服务器调用。
我们可以看到,具有单个哈希函数的哈希表与bloom过滤器的用途完全不同。希望这可以消除您的疑虑:)
我已经为Python中的恶意URL测试任务实现了Bloom Bloom过滤器。可以在这里找到代码-https: //github.com/tarunsharma1/Bloom-Filter 该代码非常易于理解,并且自述文件中提供了详细说明。
HashSet<String>
在哈希表完全充满的最佳情况下,常规的哈希表(例如C#)将在每个元素元素上使用16个字节:从“存储桶”到条目表中的条目(映射为数组的单链接数组)映射4个字节列表),4个字节(用于缓存的哈希码),4个字节(用于“下一个”指针),4个字节(用于指向键的指针)。这还不包括字符串大小。在最坏的情况下,它是40个字节:一旦String
指针扩展到64位体系结构的8个字节,则有一半的条目未使用,每个条目20个字节。
我将首先解释什么是bloom过滤器,它可以做什么,不能做什么,我们为什么需要它,显示它的工作原理的直观描述,然后举例说明它们何时有用。
definitely not in the set
或检查元素是否在集合中possibly in the set
这possibly in the set
就是为什么它被称为概率论的原因。使用智能词意味着错误肯定是可能的(在某些情况下它会错误地认为元素是肯定的),而错误否定是不可能的。
但却不能 *:
* 这套可以/不能用于基本的布隆过滤器。因为它是很久以前创建的有用数据结构,所以人们发现了如何使用其他有用功能来对其进行扩充。
但是,请稍等:我们已经知道一个数据结构可以在没有模糊的“可能”且没有所有限制的情况下回答所有这些问题(无法删除,无法显示全部)。它称为集合。布隆过滤器的主要优点是:空间效率高且空间常数。
这意味着我们在那里存储多少元素都没有关系,空间将相同。是的,具有10^6
元素的bloom过滤器(无用的bloom过滤器)将与具有元素的bloom过滤器占用相同的空间,并且与具有10^20
元素的bloom过滤器占用相同的空间0
。那么需要多少空间?由您决定(但是要权衡:您拥有的要素越多,possible in the set
回答的不确定性就越大。
另一个很酷的事情是它是空间常数。将数据保存到集合中时,实际上必须保存此数据。因此,如果存储this long string in the set
,则必须至少使用27个字节的空间。但是对于1%的错误和k **的最佳值,每个元素(无论是int的短文本还是巨大的文本墙)都需要〜9.6位(<2个字节)。
另一个特性是,所有操作都采用恒定时间,这与集合的情况下的分摊的恒定时间绝对不同(请记住,如果集合发生冲突,则O(n)
时间可能会恶化)。
** k是布隆过滤器中使用的哈希函数的值
我不会描述布隆过滤器的工作原理(维基百科文章在解释所有内容方面做得很好)。在这里,我将简要介绍一下基本知识。
m
k
不同的哈希函数(越独立越好)k
值的所有哈希并将相应的位设置为1k
哈希,如果没有设置至少其中之一,则肯定不在集合中。否则,它可以在集合中。甚至这个描述也足以理解为什么我们不能确定(您可以从其他各种值中设置所有位)。这是一个很好的可视化工作原理。
那么布隆过滤器什么时候有用?简短的答案是在任何地方都可以接受误报,并且您希望检查其中是否有东西,但是即使不是,也可以作为排除昂贵的要求验证者的第一道防线。
这是更具体的描述列表:
布隆过滤器在生物信息学中非常有用。与使用常规散列相比,它们可以更节省空间,尤其是当您使用的字符串的大小可以是亿万个字母且字母非常小的字母,例如{A,G,T,C}时。它们通常用于评估基因组中是否存在某种k-mer。这里有一个例子用于相关的事情。
编辑:
多个哈希函数用于最小化误报。希望与所有其他可能值相比,在所有k哈希函数之间,每个值在位数组中将具有唯一的签名。但是,确实存在误报,但可以将其最小化到可管理的水平。使用此技术,您可以独立于元素的大小对哈希进行哈希处理。搜索它们时,请使用每个哈希函数,并检查以确保它们的位值均为1。
将此与人类基因组进行比较,在人类基因组中,元素大小的增加会显着增加哈希表的大小(表大小为4 * 4 k)。假设您使用2位/字母对元素进行编码。