我正在尝试按照以下帖子(多维缩放)中指定的方法从距离矩阵中获取 0 和 1 之间的 2D 坐标:
python - 如何基于gram-matrix实现从python中的距离矩阵中查找点的坐标?
但是,当尝试实现它时,我得到一个错误,我很难找到这个错误的根源。这就是我正在做的事情:
这是距离矩阵(如您所见,最大距离为 1,因此所有点都可以在 0 和 1 之间):
import numpy as np
import math
distance_matrix = np.array(
[
[0.0, 0.47659458, 0.22173311, 0.46660708, 0.78423276],
[0.47659458, 0.0, 0.69805139, 0.01200111, 0.6629441],
[0.22173311, 0.69805139, 0.0, 0.68249177, 1.0],
[0.46660708, 0.01200111, 0.68249177, 0.0, 0.6850815],
[0.78423276, 0.6629441, 1.0, 0.6850815, 0.0],
]
)
这是我进行多维缩放的地方:
def x_coord_of_point(D, j):
return ( D[0,j]**2 + D[0,1]**2 - D[1,j]**2 ) / ( 2*D[0,1] )
def coords_of_point(D, j):
x = x_coord_of_point(D, j)
return np.array([x, math.sqrt( D[0,j]**2 - x**2 )])
def calculate_positions(D):
(m, n) = D.shape
P = np.zeros( (n, 2) )
tr = ( min(min(D[2,0:2]), min(D[2,3:n])) / 2)**2
P[1,0] = D[0,1]
P[2,:] = coords_of_point(D, 2)
for j in range(3,n):
P[j,:] = coords_of_point(D, j)
if abs( np.dot(P[j,:] - P[2,:], P[j,:] - P[2,:]) - D[2,j]**2 ) > tr:
P[j,1] = - P[j,1]
return P
P = calculate_positions(distance_matrix)
print(P)
Output: [[ 0. 0. ]
[ 0.47659458 0. ]
[-0.22132834 0.01339166]
[ 0.46656063 0.0065838 ]
[ 0.42244347 -0.66072879]]
我这样做是为了使所有点都在 0 和 1 之间:
P = P-P.min(axis=0)
一旦我有了一组应该满足距离矩阵的点,我就从这些点计算距离矩阵,看看它是否等于原始矩阵:
def compute_dist_matrix(P):
dist_matrix = []
for i in range(len(P)):
lis_pos = []
for j in range(len(P)):
dist = np.linalg.norm(P[i]-P[j])
lis_pos.append(dist)
dist_matrix.append(lis_pos)
return np.array(dist_matrix)
compute_dist_matrix(P)
Output: array([[0. , 0.47659458, 0.22173311, 0.46660708, 0.78423276],
[0.47659458, 0. , 0.69805139, 0.01200111, 0.6629441 ],
[0.22173311, 0.69805139, 0. , 0.68792266, 0.93213762],
[0.46660708, 0.01200111, 0.68792266, 0. , 0.66876934],
[0.78423276, 0.6629441 , 0.93213762, 0.66876934, 0. ]])
如你所见,如果我们将这个数组与文章开头的原始距离矩阵进行比较,矩阵的前项没有误差,但随着接近结尾,误差越来越大。如果距离矩阵比我在这个例子中使用的大,那么错误就会变得很大。
我不知道错误的根源是在计算 P 的函数中,还是函数“compute_dist_matrix”是问题所在。
你能找出错误的根源吗?或者,有没有更简单的方法来计算所有这些?也许某些库中的某些函数已经执行了这种转换。