Algorithm 如何在高维数据中高效地寻找k-近邻?

Algorithm 如何在高维数据中高效地寻找k-近邻?,algorithm,data-structures,computational-geometry,nearest-neighbor,dimensionality-reduction,Algorithm,Data Structures,Computational Geometry,Nearest Neighbor,Dimensionality Reduction,因此,我有大约16000个75维数据点,对于每个点,我想找到它的k个最近邻(使用欧几里德距离,如果这使它更容易,目前k=2) 我的第一个想法是使用kd树来实现这一点,但随着维度数量的增加,它们变得相当低效。在我的示例实现中,它只比穷举搜索稍微快一点 我的下一个想法是使用PCA(主成分分析)来减少维度的数量,但我想知道:是否有一些聪明的算法或数据结构可以在合理的时间内准确地解决这个问题?你可以想象使用,但如果有75个维度,它们将是巨大的。如果你只有16000个数据点,那么彻底搜索不会花费太长时间。

因此,我有大约16000个75维数据点,对于每个点,我想找到它的k个最近邻(使用欧几里德距离,如果这使它更容易,目前k=2)

我的第一个想法是使用kd树来实现这一点,但随着维度数量的增加,它们变得相当低效。在我的示例实现中,它只比穷举搜索稍微快一点


我的下一个想法是使用PCA(主成分分析)来减少维度的数量,但我想知道:是否有一些聪明的算法或数据结构可以在合理的时间内准确地解决这个问题?

你可以想象使用,但如果有75个维度,它们将是巨大的。如果你只有16000个数据点,那么彻底搜索不会花费太长时间。

没有理由相信这是NP完全的。你没有真正优化任何东西,我很难想出如何将其转化为另一个NP完全问题(我的书架上有,找不到类似的问题)。真的,我只想寻求更有效的搜索和排序方法。如果你有n个观测值,你必须计算n x n的距离。然后,对于每次观察,您都需要选择前k个最近邻居。距离计算是n的平方,排序是n log(n),但必须进行n次排序(每n个值都不同)。杂乱无章,但仍然需要多项式时间才能得到答案

BK-Tree并不是一个坏主意。看一看。虽然他的重点是字符串,但它应该为您提供一个跳板,供您使用其他方法。我能想到的另一件事是,但是我不知道它们是否已经被推广到大维度。我不能说更多,因为我既没有直接使用它们,也没有亲自实现它们。

维基百科关于kd trees的文章有一个链接:

安是一个用C++编写的图书馆。 支持数据结构和 精确和精确算法 近似近邻搜索 在任意高的维度中

根据我们自己的经验,安 执行效率相当高 集的大小从数千到 数十万,而且 尺寸高达20。(适用于显著高于 维度,其结果相当复杂 斯波蒂,但你还是可以试试看

就算法/数据结构而言:

该库实现了许多功能 不同的数据结构,基于 kd树和, 并且雇佣了几个不同的 搜索策略


我会先直接尝试,如果不能产生令人满意的结果,我会在应用PCA/ICA后将其用于数据集(因为kd树不太可能处理足够少的维数).

一个非常常见的实现是对为每个数据点计算的最近邻数组进行排序。 由于对整个数组进行排序可能非常昂贵,因此可以使用间接排序之类的方法,例如Python Numpy库中的Numpy.argpartition,只对感兴趣的最接近的K值进行排序。不需要对整个阵列进行排序

@格伦博的上述答案应该大大减少。因为您只需要K个最接近的值。无需对每个点的整个距离进行排序

如果您只需要K个邻居,此方法将非常有效,从而降低计算成本和时间复杂性

如果需要排序的K个邻居,请再次对输出排序

使用kd树

不幸的是,在高维数据结构中,这种数据结构严重受到影响,这导致其搜索时间与暴力搜索相当

减少维度的数量

这是一个很好的方法,它在准确性和速度之间提供了一个公平的权衡。当你减少维度时,你会丢失一些信息,但会获得一些速度

所谓精确性,我指的是找到精确的最近邻(NN)

当您希望减少数据所在的维度空间时,主成分分析()是一个好主意

是否有一些聪明的算法或数据结构能够在合理的时间内准确地解决这个问题

近似最近邻搜索(),您可以满意地找到一个点,该点可能不是精确的最近邻,而是一个很好的近似值(例如,在查找第一个NN时,这是查询的第四个NN)

这种方法会降低准确性,但会显著提高性能。此外,找到一个好的NN(足够接近查询)的概率相对较高

您可以在kd GeRaF的介绍中了解更多有关ANN的信息

一个好主意是将人工神经网络与降维相结合

局部敏感哈希()是解决高维最近邻问题的一种现代方法。关键的想法是将彼此靠近的点散列到同一个桶中。因此,当查询到达时,它将被散列到一个bucket中,该bucket(通常是其相邻的bucket)包含好的NN候选项


是一个很好的C++实现,它集中在余弦相似度上。另一个很好的实现是我们的,这是一个更通用的库。

我认为这与其中一个类似:就精确的解决方案而言,我怀疑答案是否定的,但我想提出随机投影,约翰逊-林登斯特劳斯定理可能有助于+1,这与LSH和安的观点相同。我推荐哈南·萨米特的书《多维和度量数据结构的基础》。它有一些章节专门讨论适合高维数据的结构。我删除了我的答案,因为思考它使我意识到它既误导又不正确。这是每一点16000次比较,因此总共16000^2次比较。不是ta