如何优化用于计算K最近邻算法的算法?

时间:2018-10-03 21:20:39

标签: data-structures time-complexity knn

KNN是一种简单易行的算法,易于实现:

# for each test datapoint in X_test:
#     calculate its distance from every points in X_train
#     find the top k most closest points  
#     take majority vote of the k neighbors and use that as prediction for this test data point

但是我认为时间复杂度不够好。在现实中实现该算法时如何进行优化? (例如它使用的是什么技巧或数据结构?)

2 个答案:

答案 0 :(得分:1)

k最近邻算法与其他学习方法不同,因为没有 从训练实例中得出模型。数据保持原样;他们 只是存储在内存中。

遗传算法与k-NN相结合以提高性能。另一种成功的技术称为实例 还建议选择同时面对,有效存储和噪声 神经网络您可以尝试这样做:何时应该对新实例进行分类;代替 涉及所有学习实例以检索k邻居,这将增加 计算时间,首先要选择较小的实例子集。

您也可以尝试:

  1. 通过减少训练次数来提高k-NN速度 文件
  2. 通过邻域大小和相似度改进k-NN 功能
  3. 通过高级存储结构改进k-NN

答案 1 :(得分:1)

您要描述的是用O(size(X_test)* size(X_train)* d)进行的蛮力kNN计算,其中d是特征向量中的维数。

更有效的解决方案使用空间索引在X_train数据上放置索引。通常,这会将单个查找减少为O(log(size(X_train))* d)甚至O(log(size(X_train))+ d)。

常见空间索引是:

  • kD-Trees(它们经常使用,但是用'd'扩展性很差)
  • R-Trees,例如RStarTree
  • Quadtrees(通常对于大'd'而言效率不高,但是例如PH-Tree在d = 1000时效果很好,并且具有出色的删除/插入时间(免责声明,这是我自己的工作))
  • BallTrees(我对它们并不了解)
  • CoverTrees(非常快的查找'd',但是建立时间长

还有“近似” NN搜索/查询的类别。这些以速度换取正确性,它们可能会跳过一些最近的邻居。您可以在python here中找到性能比较和众多实现。

如果要查找上述某些空间索引的Java实现,请查看my implementations