Multidimensional Scaling

import numpy as np
import matplotlib.pyplot as plt

D=np.array([[0,411,213,219,296,397],
            [411,0,204,203,120,152],
            [213,204,0,73,136,245],
            [219,203,73,0,90,191],
            [296,120,136,90,0,109],
            [ 397,152,245,191,109,0]])

N = D.shape[0]
T = np.zeros((N,N))

#solution 1
#ss = 1.0/N**2*np.sum(D**2)
#for i in range(N):
#    for j in range(i,N):
#        T[i,j] = T[j,i] = -0.5*(D[i,j]**2 -1.0/N*np.dot(D[i,:],D[i,:]) -1.0/N*np.dot(D[:,j],D[:,j])+ss)

#solution 2
#K = np.dot(D,np.transpose(D))
D2 = D**2
H = np.eye(N) - 1/N
T = -0.5*np.dot(np.dot(H,D2),H)

eigVal,eigVec = np.linalg.eig(T)
X = np.dot(eigVec[:,:2],np.diag(np.sqrt(eigVal[:2])))

print(X.shape)

plt.scatter(X[:,0],X[:,1])
plt.show()

print('original distance','\tnew distance')
for i in range(N):
    for j in range(i+1,N):
        print(np.str(D[i,j]),'\t\t',np.str("%.4f"%np.linalg.norm(X[i]-X[j])))
import numpy as np

# run this to get a test matrix
# A = np.random.randint(1,100,(5,20))
# np.save('mat.npy', A)
# exit()

A = np.load('mat.npy') # 5*20

n,m = A.shape #  n是向量个数5   m是向量维数20
Dist = np.zeros((n,n)) # 距离矩阵5*5
B = np.zeros((n,n)) # 5*5

print(n) # 5
print(m) # 20
for i in range(n):
    for j in range(n):
        Dist[i][j] = sum((ix-jx)**2 for ix,jx in zip(A[i], A[j]))

disti2 = np.array([0]*n) # 5
print(disti2.shape)
distj2 = np.array([0]*n) # 5
print(distj2.shape)

for x in range(n):
    disti2[x] = np.mean([Dist[x][j] for j in range(n)]) # 距离矩阵每行的平均值
    distj2[x] = np.mean([Dist[i][x] for i in range(n)]) # 距离矩阵每列的平均值

distij2 = np.mean([Dist[i][j] for i in range(n) for j in range(n)]) # 距离矩阵的平均值

for i in range(n):
    for j in range(n):
        B[i][j] = -0.5*(Dist[i][j] - disti2[i] - distj2[j] + distij2)  # 投影后的距离矩阵

w,v = np.linalg.eig(B)  #计算矩阵的特征值及特征向量
# w the eigenvalues each repeated according to its multiplicity
# v the normalized(united "length") eigenvectors
# such that the column v[:,i] is the eigenvector corresponding to the eigenvalue w[i]

v=v.transpose()

U = [{'eVal':w[i], 'eVec':v[i]} for i in range(n)]

U.sort(key = lambda obj:obj.get('eVal'), reverse = True) # 按特征值从大到小排序
k=4 # 降至4维
w=np.array([0]*k) # 4*1 all zero
v=np.zeros((k,n)) # 4*5 all zero

print(w)
print(w.shape)
print(v.shape)
print(v)

for i in range(k):
    w[i] = U[i].get('eVal')**0.5  # 特征值开根号
    v[i] = U[i].get('eVec')       # 特征向量


# 5*4 * 4*4 = 5*4
ans = np.dot(v.transpose(), np.diag(w))

print(ans.shape)
print(ans)

ans_dist = np.zeros((n,n))
for i in range(n):
    ans_str=""
    for j in range(n):
        ans_dist[i][j] = sum((ix-jx)**2 for ix,jx in zip(ans[i], ans[j])) # 计算投影后的距离矩阵

print("Orign dis[][] is :")
print(Dist)
print("MDS dis[][] is :")
print(ans_dist)

猜你喜欢

转载自blog.csdn.net/algzjh/article/details/81092354