我正在尝试实现laplacian eigenmaps算法,该算法包括:
2)将每个边缘与重量相关联
3)定义对角线(对角线放置的行的总和)
4)执行广义特征分解(应该是Lv = lambdaDv,其中L和D在下面的代码中计算)
我认为这可以用scipy.linalg.eig(vals)以某种方式解决,但我不明白如何正确输入我的两个矩阵.有人可以帮助我理解如何执行广义特征分解步骤吗?
import numpy as np import random as r from math import exp as exp from scipy.spatial import distance def rweights((vectors,features)): return 1 * np.random.random_sample((vectors,features)) - 0 def vEuclidean(v,m): return np.apply_along_axis(lambda x: distance.euclidean(v,x),1,m) def mEuclideans(m): return np.apply_along_axis(lambda v: vEuclidean(v,m),m) def neighbours(vector,neigh): size = (vector.shape[0] - neigh) for i in range(1,size): vector[np.argmax(vector)] = 0.0 return vector def kNN(m,k): me = mEuclideans(m) return np.array(map(lambda v: neighbours(v,k),me)) def diag(m): sums = np.sum(m,1) (vectors,features) = m.shape zeros = np.zeros(vectors*features).reshape((vectors,features)) for i in range(features): zeros[i][i] = sums[i] return zeros def vectorWeight(v,sigma): f = lambda x: exp((-(x)/(sigma**2))) size = v.shape[0] for i in range(size): v[i] = f(v[i]) return v def weight(m): return np.array(np.apply_along_axis(lambda v: vectorWeight(v,0.5),m)) if __name__ == "__main__": np.random.seed(666) m = rweights((5,3)) w = weight(kNN(m,2)) D = diag(w) L = D-w
解决方法
好,
这个答案得到了沃伦斯的帮助(所以他值得赞扬),但我发现了一个关于光谱聚类的视频 https://www.youtube.com/watch?v=Ln0mgyvXNQE,他在图上使用了laplacian.我认为根据他的结果检查我的实现会很好.因此,我补充说:
这个答案得到了沃伦斯的帮助(所以他值得赞扬),但我发现了一个关于光谱聚类的视频 https://www.youtube.com/watch?v=Ln0mgyvXNQE,他在图上使用了laplacian.我认为根据他的结果检查我的实现会很好.因此,我补充说:
from scipy.linalg import eig def distanceM(): return np.array([[0.0,0.8,0.6,0.1,0.0,0.0],[0.8,0.9,[0.6,0.2],[0.1,0.7],[0.0,0.8] [0.0,0.2,0.7,0.0]]) if __name__ == "__main__": w = distanceM() D = diag(w) L = D-w w,vr = eig(L) print vr
我发现我得到了相同的拉普拉斯矩阵,也有相同的特征向量(vr的第二列).