有关我的问题的背景信息:
如果两个对象彼此相邻,则称为彼此的 k -倒数最近邻居。我只对不交集的对象感兴趣。例如,考虑两组数字 S = {0,1,2} , T = {0.1,1.1,1.9} 和 k = 2 。 对于组 S
对于组 T
因此,成对的 k -倒数最近邻居是(0,0.1),(1,1.1),(1,1.9),(2,1.9) 。
让 {A,B,C,D,E} 和 {W,X,Y,Z} 是某些对象的两个不相交的组。假设欧氏度量在这两个组之间有意义,并且我们有以下 5x4 距离矩阵:
distmat = np.array([[5, 1, 4, 7.5],
[3, 10, 2, 11],
[9, 2.5, 8, 3],
[1, 3, 5.5, 5],
[4, 6, 3.5, 8]])
五行分别表示对象 A,B,C,D,E 与 W,X,Y,Z 的距离。
问题:获得 A 和 B k 倒数最近的邻居的有效方法是什么? >?
获取 k 最近的邻居是可以的,我使用np.argsort(distmat)
,然后检索索引小于 k 的对象。
这就是我尝试的对等部分。 wlog考虑对象 A 。对于 A 的每个 k 个最近邻居 N ,转置distmat
并检查 N -th行。如果 A 是 N 的 k 最近邻,则它们是倒数;否则他们不是。一些粗略的代码:
for index_N, N in enumerate(knn_A):
knn_N = get_knn(distmat.T[index_N]
if A in knn_N:
print("{} and {} are {}-reciprocals".format(A, N, k))
有什么改进建议吗?这很慢,因为我已经有许多嵌套的for循环,而且这两个组的大小可能很大。
答案 0 :(得分:0)
由于您提供的代码中没有嵌套的for循环,因此您必须检查这是否更快。使用您的示例(由于行“ T中2的k最近邻为1.9,2.1。”这一行,我认为它的对等邻居是错误的。-其中2.1不在集合中,如果您的意思是1.1,则(2, 1.1)也是互惠的邻居。
import numpy as np
import itertools
# set k and make the example set
k = 2
s1 = [0, 1, 2]
s2 = [.1, 1.1, 1.9]
#create the distance matrix
newarray = [ [ abs(s2j-s1i) for s2j in s2] for s1i in s1]
distmat = np.array( newarray )
#get the nearest neighbors for each set
neighbors_si = np.argsort( distmat )
neighbors_sj = np.argsort( distmat.T )
#map element of each set to k nearest neighbors
neighbors_si = { i: neighbors_si[i][0:k] for i in range(len(neighbors_si)) }
neighbors_sj = { j: neighbors_sj[j][0:k] for j in range(len(neighbors_sj)) }
#for each combination of i and j determine if they are in each others neighbor list
for i, j in itertools.product( neighbors_si.keys(), neighbors_sj.keys() ):
if j in neighbors_si[i] and i in neighbors_sj[j]:
print( '{} and {} are {}-reciprocals'.format( s1[i], s2[j], k ))