ユーリッド距離行列の計算から始めて (scipy.spatial.distance.cdist を使用)、次に K 最近傍法とダイクストラ アルゴリズム (最短経路を決定するため) に基づいて Isomap 関数をコーディングしました。パス、最後にマップ計算を行い、続いて次元削減を行いました。しかし、次のようにK最近傍の代わりにイプシロンを使用したい:
Y = アイソマップ (X、イプシロン、d)
• X は、m 属性を持つ n ポイントに対応する n × m マトリックスです。
• epsilon は、近傍のパラメーターを見つけるために使用される距離行列の無名関数です。(近傍グラフは、幅が完全な距離グラフのイプシロンより大きいエッジを削除することによって形成する必要があります)。
• d は、出力次元を表すパラメーターです。
• Y は n × d 行列であり、isomap による埋め込みを表します。
前もって感謝します
import numpy as np
import matplotlib.pyplot as plt
from scipy.spatial.distance import cdist
def distance_Matrix(X):
return cdist(X,X,'euclidean')
def Dijkstra(h):
q = h.copy()
for i in range(ndata):
for j in range(ndata):
k = np.argmin(q[i,:])
while not(np.isinf(q[i,k])):
q[i,k] = np.inf
for l in neighbours[k,:]:
possible = h[i,l] + h[l,k]
if possible < h[i,k]:
h[i,k] = possible
k = np.argmin(q[i,:])
return h
def MDS(D,newdim=2):
n = D.shape[0]
# Torgerson formula
I = np.eye(n)
J = np.ones(D.shape)
J = I-(1/n)*J
B = (-1/2)*np.dot(np.dot(J,D),np.dot(D,J)) # B = -(1/2).JD²J
#
eigenval, eigenvec = np.linalg.eig(B)
indices = np.argsort(eigenval)[::-1]
eigenval = eigenval[indices]
eigenvec = eigenvec[:, indices]
# dimension reduction
K = eigenvec[:, :newdim]
L = np.diag(eigenval[:newdim])
# result
Y = K @ L **(1/2)
return np.real(Y)
def isomap(data,newdim=2,K=12):
ndata = np.shape(data)[0]
ndim = np.shape(data)[1]
d = distance_Matrix(X)
# replace begin
# K-nearest neighbours
indices = d.argsort()
#notneighbours = indices[:,K+1:]
neighbours = indices[:,:K+1]
# replace end
h = np.ones((ndata,ndata),dtype=float)*np.inf
for i in range(ndata):
h[i,neighbours[i,:]] = d[i,neighbours[i,:]]
h = Dijkstra(h)
return MDS(h,newdim)