2

我正在阅读一篇论文,他们提到他们能够使用前缀树在 O(1) 中找到单个最近邻居。我将描述一般问题,然后是经典解决方案,最后是本文中提出的解决方案:

问题:给定一个位向量列表 L(所有向量具有相同的长度)和查询位向量 q,我们想找到 q 的最近邻。距离度量是汉明距离(有多少位不同)。天真的方法是遍历列表并计算列表中每个向量与 q 之间的汉明距离,这将花费 O(N)。然而,鉴于我们将拥有数百万个非常昂贵的位向量,因此我们希望减少它。

经典解决方案:这个问题的经典解决方案是使用近似值来找到最近的邻居,从而达到 O(logN)。这样做的方法是首先按字典顺序对 L 进行排序,以便相似的位向量彼此接近。然后给定 q,我们在排序列表上应用二分搜索来获得 q 在排序列表中的位置,并在列表中获取它上面和下面的向量(因为它们是相似的排序原因)并计算它们之间的距离并选择具有最低汉明距离的那个。然而,仅仅简单地进行一次排序,我们仍然会错过许多相似的向量,因此为了尽可能多地覆盖相似的向量,我们使用了 P 个列表和 P 个混杂函数。每个混杂函数对应每个列表。然后我们将每个位向量插入到 P 中的每个列表中,然后将其位与相应的混杂函数混杂。所以我们最终得到 P 个列表,每个列表都有位向量,但位的顺序不同。我们再次按字典顺序对 P 中的每个列表进行排序。现在给定 q,我们对 P 中的每个列表应用相同的二分搜索,但这里我们之前根据我们正在访问的列表对 q 应用混杂函数。在这一步中,我们得到了与 q 最相似的向量的 P 个,因此我们最终得到了与 q 最相似的向量。这样我们就可以覆盖尽可能多的相似向量。通过忽略排序所需的时间,找到最近邻居所需的时间为 O(log n),即对每个列表进行二分查找的时间。我们再次按字典顺序对 P 中的每个列表进行排序。现在给定 q,我们对 P 中的每个列表应用相同的二分搜索,但这里我们之前根据我们正在访问的列表对 q 应用混杂函数。在这一步中,我们得到了与 q 最相似的向量的 P 个,因此我们最终得到了与 q 最相似的向量。这样我们就可以覆盖尽可能多的相似向量。通过忽略排序所需的时间,找到最近邻居所需的时间为 O(log n),即对每个列表进行二分查找的时间。我们再次按字典顺序对 P 中的每个列表进行排序。现在给定 q,我们对 P 中的每个列表应用相同的二分搜索,但这里我们之前根据我们正在访问的列表对 q 应用混杂函数。在这一步中,我们得到了与 q 最相似的向量的 P 个,因此我们最终得到了与 q 最相似的向量。这样我们就可以覆盖尽可能多的相似向量。通过忽略排序所需的时间,找到最近邻居所需的时间为 O(log n),即对每个列表进行二分查找的时间。这样我们就可以覆盖尽可能多的相似向量。通过忽略排序所需的时间,找到最近邻居所需的时间为 O(log n),即对每个列表进行二分查找的时间。这样我们就可以覆盖尽可能多的相似向量。通过忽略排序所需的时间,找到最近邻居所需的时间为 O(log n),即对每个列表进行二分查找的时间。

建议的解决方案:论文中提出的这个解决方案(但没有任何解释)说我们可以使用前缀树在 O(1) 时间内获得最近的邻居。在论文中他们说他们使用了 P 个前缀树和 P 个混杂函数,其中每个混杂函数对应于每棵树。然后他们在将每个向量的比特与相应的混杂函数混杂之后,将比特向量插入到每棵树中。给定 q,我们将跳跃函数应用于与每棵树对应的 q,并从每棵树中检索与 q 最相似的向量。现在我们最终得到了从树中检索到的 P 位向量。在论文中,他们说从前缀树中获取与 q 最相似的向量是 O(1)。我真的不明白这一点,因为我知道搜索前缀树是 O(M) 其中 M 是位向量的长度。

这是我所指的论文(第 3.3.2 节):实时 Web 上基于内容的人群检索

http://students.cse.tamu.edu/kykamath/papers/cikm2012/fp105-kamath.pdf

我也希望您能回答我与此相关的另一个问题:如何在前缀树中查找最相似的位向量以进行 NN 搜索?

4

3 回答 3

1

O(1)只是在非常松散定义的意义上。事实上,我什至会在这种情况下挑战他们的用法。

从他们的论文中,为了确定与用户最近的邻居,u.

  1. “我们首先计算它的签名,u”:可以O(1)取决于“签名”
  2. “那么对于” 中的每个前缀树P:嗯,听起来不是很正确O(1)O(P)会更正确。
  3. 来自 2 的迭代部分。“......我们在前缀树中找到最近的签名,通过一次遍历树一级...... ”:最好的情况O(d)d树的深度或单词的长度。(这很慷慨,因为在前缀树中找到最近的点可能不止于此)
  4. “这样做之后......我们最终得到|P|签名......其中最小的汉明距离被挑选出来”:所以另一个P计算乘以单词的长度。 O(Pd).

更准确地说,总运行时间是O(1) + O(P)+ O(Pd) + O(Pd) = O(Pd)

我相信@mcdowella 在他对他们如何尝试制作这个的分析中是正确的O(1),但从我读到的内容来看,他们并没有说服我。

于 2013-06-24T19:58:51.767 回答
1

我认为论文中的论点是,如果它是 O(f(x)) 那么 x 必须是存储在树中的项目数,而不是维数。正如您所指出的,对于前缀树,时间随着 O(M) 而增加,其中 M 是位向量的长度,但是如果您认为 M 是固定的并且您感兴趣的是作为项目数的行为树增加你有O(1)。

顺便说一句,Muja 和 Lowe 的论文“使用自动算法配置的快速近似最近邻”也考虑了基于树的 LSH 竞争对手。这里的想法似乎是随机化树结构,创建多棵树,并对每棵树进行快速但粗略的搜索,选择在任何树中找到的最佳答案。

于 2013-06-24T18:40:07.230 回答
0

我假设他们在树中引用了 P 的节点,并且可以导航到 O(1) 摊销时间内的下一个或上一个条目。即诀窍是可以访问底层节点。

于 2013-06-24T18:23:36.450 回答