我正在寻找一个优化良好的函数,它接受n X n
距离矩阵,并返回一个n X k
矩阵,其中包含第{i}个最近邻居的k
个索引。排。
我发现了大量不同的R
软件包可以让你做KNN,但它们似乎都包含了距离计算以及同一函数中的排序算法。特别是,对于大多数例程,主要参数是原始数据矩阵,而不是距离矩阵。就我而言,我在混合变量类型上使用非标准距离,因此我需要将排序问题与距离计算分开。
这不是一个令人生畏的问题 - 我显然可以在循环中使用order
函数来获得我想要的东西(请参阅下面的解决方案),但这远非最佳。例如,当sort
较小(小于11)时,partial = 1:k
函数k
的速度要快得多,但不幸的是只返回已排序的值而不是所需的索引。
答案 0 :(得分:6)
尝试使用FastKNN CRAN包(虽然没有详细记录)。它提供k.nearest.neighbors
函数,可以给出任意距离矩阵。下面是一个计算所需矩阵的例子。
# arbitrary data
train <- matrix(sample(c("a","b","c"),12,replace=TRUE), ncol=2) # n x 2
n = dim(train)[1]
distMatrix <- matrix(runif(n^2,0,1),ncol=n) # n x n
# matrix of neighbours
k=3
nn = matrix(0,n,k) # n x k
for (i in 1:n)
nn[i,] = k.nearest.neighbors(i, distMatrix, k = k)
注意:您可以随时查看Cran包列表中的Ctrl + F =&#39; knn&#39; 相关功能: https://cran.r-project.org/web/packages/available_packages_by_name.html
答案 1 :(得分:0)
对于记录(我不会将此标记为答案),这是一个快速而肮脏的解决方案。假设sd.dist
是特殊距离矩阵。假设k.for.nn
是最近邻居的数量。
n = nrow(sd.dist)
knn.mat = matrix(0, ncol = k.for.nn, nrow = n)
knd.mat = knn.mat
for(i in 1:n){
knn.mat[i,] = order(sd.dist[i,])[1:k.for.nn]
knd.mat[i,] = sd.dist[i,knn.mat[i,]]
}
现在knn.mat
是每行中k
最近邻居的索引的矩阵,为方便起见knd.mat
存储相应的距离。