我有一个单词列表,如 - list1 = [boy,apple,mango,car],我有两个文件,内容如下:
document1= The boy driving a car ate apple and mango.
document2= The boy ate an apple.
我只需要查明文档中是否存在给定的单词列表。
为了检查list1中的单词是否存在于文档中,我可以为list1(比如bloomlist1)和document1(比如bloomdocument1)创建一个bloom过滤器。然后我可以执行按位和检查结果是否与bloomlist1相同。如果相同,我可以说list1中的所有单词都存在于document1中。所以,它将返回True。
如果我对document2采用相同的方法,即按位和,那么结果将为False。但即使列表中的单个单词包含在文档中,我也需要得到True。
这是否可以使用bloom过滤器或我是否需要任何其他数据结构。如果不是,那么什么是满足这两个标准的最佳数据结构。
答案 0 :(得分:3)
我不认为您使用Bloom过滤器是合适的。
您声明需要两个过滤器 构建,一个用于单词列表,另一个用于搜索的文档。那么你 按位和过滤器。如果结果与原始单词列表过滤相同 文件被接受,否则你拒绝它。
如果这是对您的过程的正确理解,则很明显文档只能通过 如果它包含列表中的所有单词(或者通过散列冲突,则会有一些额外的位 在文档Bloom过滤器中设置可能会导致其被接受 - 可能导致误报。
如果要在匹配列表中的一个单词时立即选择文档,则只需要一个Bloom过滤器用于单词列表(对于正在测试的文档,无需一个)。使用Bloom过滤器散列函数逐个散列文档中的每个单词。一旦所得到的散列与单词列表Bloom过滤器中的所有相应位匹配,就接受该文档(这是命中)。然后,您需要验证命中未到期 误报。
Bloom过滤器的“美丽”是它不会遭受漏报。也就是说,如果没有了 您的文档中的单词在Bloom过滤器中有一个“命中”,您可以100%确定没有 文档中的单词出现在关联的单词列表中。
您面临的一个问题是Bloom过滤器容易出错 阳性。误报是Bloom过滤器上有一个不在关联列表中的单词。 因此,你必须这样做 每当Bloom过滤器指示“命中”时,使用实际单词列表明确地验证每次命中的“真实性”。 没有办法解决它。
构建一个好的Bloom过滤器的“艺术”是找到一组廉价的散列函数 执行并导致低误报率(通常这相当于独立性和良好的分配 哈希函数)。快速google search开启 Bloom过滤器将为您提供有关多少哈希函数和过滤器大小的指导 需要达到给定的误报率(假设散列函数很好)。
如果您进行计算,您会发现对于任何显着大小的单词列表,您需要使用 至少7个散列函数,以实现可接受的误报率。针对每个运行7个哈希函数 无论你怎么做,大文档中的单词都会“昂贵”。此外,如果您的文件 包含大量不同的单词在Bloom过滤器上遭受误报的可能性 可能会变得重要 - 降低其实用性。
这里的其他答案表明,更好的方法是为列表中的单词构造一个简单的哈希表,然后对每个单词进行哈希处理 从文档中查看它是否在列表中有一个命中。如果是,请选择文档。简单。这种技术 除非有一些,否则很可能会对这种类型的应用程序执行Bloom过滤器方法 你在问题中没有概述的特殊情况。
编辑 - 最佳方法是什么?
在给定文本上进行多字符串搜索的方法有很多种。它是 很难说哪一个会成为您应用程序的最佳解决方案,因为大多数算法和 他们的实现对复杂因素很敏感(例如,平均字数,数量 不同的单词,文档大小,搜索列表中的单词数,可用内存,具有“命中”的概率等。这里没有一个正确答案。
使用Bloom过滤器可能是一种合理的方法,但是,您至少应该看一下 其他选择。一些例子可能是:
最重要的是,在确定任何特定解决方案之前,您应该考虑更广泛的策略。
答案 1 :(得分:2)
检查文档中是否存在列表中的任何字样:
布隆过滤器当然有可能出现误报 - 即使单词不存在也可以返回true。为了避免这种情况,您可以使用哈希表(以与上述相同的方式) - 但这会使用更多的内存。
答案 2 :(得分:2)
如果您要搜索数百万个文档以查找已知单词集的出现次数,则Bloom过滤器不是最佳选择。您最终会为每个文档中的每个单词插入Bloom过滤器,对于每个文档,您最终必须检查每个单词的Bloom过滤器以确定它是否存在于文档中。
如果您需要知道的是文档中是否存在任何一个单词,您可以构建要检查的单词的哈希表,并测试文档中的每个单词。所以,例如:
hashTable = {"boy", "mango", "car", "apple"}
for each document
{
found = false
for each word in document
{
if word in hash table
{
found = true
break // found a word. Skip the rest of the document.
}
if found then output success else output failure
}
}
这将比Bloom过滤器方法更好,原因如下: