我正在阅读一篇文章,他们提到他们能够使用前缀树在O(1)中找到单个最近邻居。我将描述一般问题,然后是经典解决方案,最后是论文中提出的解决方案:
问题:给定一个位向量列表L(所有向量具有相同的长度)和查询位向量q,我们希望找到q的最近邻居。距离度量是汉明距离(多少位不同)。天真的方法是通过列表并计算列表中每个向量和q之间的汉明距离,这将取O(N)。但是,鉴于我们将有数百万的位向量非常昂贵,所以我们希望减少它。
经典解决方案: 这个问题的经典解决方案是使用近似来找到最近的邻居,从而实现O(logN)。这样做的方法是首先按字典顺序对L进行排序,以使类似的位向量彼此接近。然后给定q,我们在排序列表上应用二进制搜索以获得q可以在排序列表中的位置,并在列表中取上面和下面的向量(因为它们类似于排序)并计算他们之间的距离,选择最短的汉明距离。然而,仅仅进行一次排序我们仍然会遗漏许多类似的向量,因此为了覆盖尽可能多的相似向量,我们使用P个列表和P个jumbling函数。每个jumbling函数对应于每个列表。然后我们将每个位向量插入到P中的每个列表中,然后使用相应的jumbling函数对其进行混音。因此,我们最终得到P列表,每个列表具有位向量,但具有不同顺序的位。我们再次按字典顺序对P中的每个列表进行排序。现在给出q,我们对P中的每个列表应用相同的二进制搜索,但是在这里我们在根据我们访问的列表将jumbling函数应用于q之前。在这一步中,我们得到P个最相似的向量到q,所以我们最终得到一个与q最相似的向量。这样我们就可以覆盖最相似的向量。通过忽略排序所需的时间,找到最近邻居所需的时间是O(log n),这是在每个列表上进行二进制搜索的时间。
建议的解决方案: 本文提出的这个解决方案(但没有任何解释)说我们可以使用前缀树在O(1)时间内获得最近邻居。在论文中他们说他们使用P个前缀树和P个jumbling函数,其中每个jumbling函数对应于每个树。然后,在用相应的混音函数对每个向量的位进行混淆之后,它们将位向量插入到每个树中。给定q,我们将跳跃函数应用于对应于每个树的q,并且我们从每个树中检索q的最相似的向量。现在我们最终得到从树中检索到的P位向量。在论文中,他们说只是从前缀树中获得与q最相似的向量是O(1)。我根本不理解这一点,因为我知道搜索前缀树是O(M),其中M是位向量的长度。有人理解为什么是O(1)?
这是我所指的论文(第3.3.2节):实时网络上基于内容的人群检索
http://students.cse.tamu.edu/kykamath/papers/cikm2012/fp105-kamath.pdf
如果您能回答我与此相关的其他问题,我也希望如此:How to lookup the most similar bit vector in an prefix tree for NN-search?
答案 0 :(得分:1)
我认为论文中的论点是,如果它是O(f(x))那么x必须是树中存储的项目数,而不是维数。正如你所指出的,对于前缀树,时间上升为O(M),其中M是位向量的长度,但如果你认为M是固定的,你感兴趣的是行为作为项目的数量树增加你有O(1)。
顺便说一句,Muja和Lowe撰写的“快速近似最近邻居和自动算法配置”也将基于树的竞争对手视为LSH。这里的想法似乎是随机化树形结构,创建多个树,并对每棵树进行快速但粗略的搜索,选择在任何树中找到的最佳答案。
答案 1 :(得分:1)
O(1)
这只是一种非常松散的定义。事实上,我会在这种情况下挑战他们的用法。
从他们的论文中,确定用户的最近邻居u
。
u
”:根据“签名”可以O(1)
P
中的每个前缀树:呃哦,听起来不是O(1)
,O(P)
会更正确。O(d)
是树的深度或单词的长度。 (这很慷慨,因为找到前缀树中最近的点可能比这更多)d
签名......其中选择了最小的汉明距离”:所以另一个|P|
计算乘以单词的长度。 P
。更准确地说,总运行时间为O(Pd)
我相信@mcdowella在分析他们如何尝试制作O(1) + O(P)+ O(Pd) + O(Pd) = O(Pd)
时是正确的,但从我读过的内容来看,他们并没有说服我。
答案 2 :(得分:0)
我假设他们在树中引用了P的节点,并且可以导航到O(1)摊销时间中的下一个或上一个条目。即技巧是访问底层节点。