获得最接近的k项的最有效实现

时间:2018-08-27 05:15:09

标签: algorithm data-structures heap asymptotic-complexity

在K最近邻算法中,我们从N个观测值中找到最接近新点的前k个邻居,并使用这些邻居对点进行分类。根据对数据结构的了解,我可以想到此过程的两种实现:

方法1

  1. 从N个观测值中计算到新点的距离
  2. 使用quicksort对距离进行排序并获取前k个点

需要花费O(N + NlogN)= O(NlogN)时间。

方法2

  1. 创建大小为k的最大堆
  2. 计算前k个点到新点的距离
  3. 对于以下每个观察,如果距离小于堆中的最大距离,请从堆中弹出该点并将其替换为当前观察
  4. 重新堆砌(N点的logk操作)
  5. 继续进行,直到没有更多的观察值为止,此时我们应该只在堆中拥有最接近的前5个距离。

此方法将采用O(N + NlogK)= O(NlogK)运算。

我的分析正确吗?如何在像sklearn这样的标准软件包中优化此过程?谢谢!

1 个答案:

答案 0 :(得分:4)

以下是常用方法的很好概述:https://en.wikipedia.org/wiki/Nearest_neighbor_search

您描述的是线性搜索(因为您需要计算到数据集中每个点的距离)。 好消息是,这始终有效。不好的是,它很慢,特别是如果您查询很多的话。

如果您对数据了解更多,则可以得到更好的性能。如果数据的维数较低(2D,3D)并且分布均匀(这并不意味着完美,就不是在非常密集和非常紧密的群集中),那么空间分区就可以发挥很大的作用,因为它可以在距离太远的点上迅速地进行缩减无论如何(复杂度O(logN))。它们还可以用于更高的维数性或是否存在某些聚类,但是性能会有所下降(总体上比线性搜索要好)。

通常,空间分区或对位置敏感的哈希对于常见数据集就足够了。

权衡是您使用更多的内存和一些设置时间来加快以后的查询。如果您有很多查询,那是值得的。如果您只有少数几个,则不是很多。