我有一个存储向量的系统,允许用户找到与用户查询向量最相似的n个向量.也就是说,用户提交一个向量(我称之为查询向量),我的系统吐出“这里是n个最相似的向量”.我使用KD-Tree生成类似的向量,一切运行良好,但我想做更多.我想呈现n个最相似的向量的列表,即使用户没有提交完整的向量(具有缺失值的向量).也就是说,如果用户提交具有三维的矢量,我仍然希望找到我存储的n个最近的矢量(存储的矢量是11维).
我有几个明显的解决方案,但我不确定任何一个看起来非常好:
>创建多个KD树,每个KD树使用用户将搜索的最流行的维度子集构建.也就是说,如果用户提交了维度x,y,z的查询向量,则我将该查询与我已经构建的KD树匹配,该KD树仅包含三维x,y,z的向量.
>当用户提交缺少值的查询向量时,忽略KD-Trees,并使用像点积之类的东西逐个地将查询向量与向量(存储在DB中的表中)进行比较.
这是一个常见问题,有什么建议吗?谢谢您的帮助.
最佳答案 你的第一个解决方案可能是最快的查询(因为树构建不考虑你不关心的方向的拆分),但它肯定会使用大量的内存.如果你不得不重复重建树木,它可能会变慢.
除非你只有几个点,否则第二个选项看起来很慢.如果是这样的话,你可能首先不需要kd树:)
我认为最好的解决方案是在你正在使用的代码中弄脏你的手.据推测,最近邻搜索计算树叶中的点与查询向量之间的距离;您应该能够修改它以处理点和查询向量大小不同的情况.例如.如果树中的点是以3D形式给出的,但查询向量只有长度为2,那么点(p0,p1,p2)和查询向量(x0,x1)之间的“距离”将是
sqrt( (p0-x0)^2 + (p1-x1)^2 )
我没有深入研究您链接到的java代码,但如果您需要帮助,我可以尝试找到更改所需的确切位置.
-克里斯
PS – 你可能不需要上面等式中的sqrt,因为距离平方通常是等价的.
编辑
对不起,没有意识到它在源代码中会如此明显.您应该使用此版本的邻居函数:
nearest(double [] key, int n, Checker<T> checker)
并实现自己的Checker类;看他们的EuclideanDistance.java看欧几里德版本.您可能还需要注释掉查询代码抛出的任何KeySizeException,因为您知道可以处理不同大小的键.