http://blog.csdn.net/waleking/article/details/7584084
针对karate_club数据集,做了谱聚类。由于是2-way clustering,比较简单,得到了图的新的表示空间之后,没有做k-means,仅仅针对正规化后的拉普拉斯矩阵的第二特征值做了符号判断,这和Spectral Clustering Tutorial 一文中的描述一致。
引用了numpy scipy matplotlib networkx包
-
-
-
-
-
import scipy.linalg as linalg
-
-
import matplotlib.pyplot as plt
-
-
-
-
"compute D=diag(d1,...dn)
-
-
"and Lbar=D^(-1/2)LD^(-1/2)
-
-
-
d=[np.sum(row) for row in W]
-
-
-
-
Dn=np.power(np.linalg.matrix_power(D,-1),0.5)
-
Lbar=np.dot(np.dot(Dn,L),Dn)
-
-
-
def getKSmallestEigVec(Lbar,k):
-
-
-
-
"k smallest eigen values and their corresponding eigen vectors
-
-
eigval,eigvec=linalg.eig(Lbar)
-
-
-
-
dictEigval=dict(zip(eigval,range(0,dim)))
-
kEig=np.sort(eigval)[0:k]
-
ix=[dictEigval[k] for k in kEig]
-
return eigval[ix],eigvec[:,ix]
-
-
def checkResult(Lbar,eigvec,eigval,k):
-
-
-
"matrix Lbar and k eig values and k eig vectors
-
"print norm(Lbar*eigvec[:,i]-lamda[i]*eigvec[:,i])
-
-
check=[np.dot(Lbar,eigvec[:,i])-eigval[i]*eigvec[:,i] for i in range(0,k)]
-
length=[np.linalg.norm(e) for e in check]/np.spacing(1)
-
print("Lbar*v-lamda*v are %s*%s" % (length,np.spacing(1)))
-
-
-
-
-
-
-
kEigVal,kEigVec=getKSmallestEigVec(Lbar,k)
-
print("k eig val are %s" % kEigVal)
-
print("k eig vec are %s" % kEigVec)
-
checkResult(Lbar,kEigVec,kEigVal,k)
-
-
-
-
clusterA=[i for i in range(0,nodeNum) if kEigVec[i,1]>0]
-
clusterB=[i for i in range(0,nodeNum) if kEigVec[i,1]<0]
-
-
-
colList=dict.fromkeys(g.nodes())
-
for node,score in colList.items():
-
-
-
-
-
plt.figure(figsize=(8,8))
-
-
nx.draw_networkx_edges(g,pos,alpha=0.4)
-
nx.draw_networkx_nodes(g,pos,nodelist=colList.keys(),
-
node_color=colList.values(),
-
-
nx.draw_networkx_labels(g,pos,font_size=10,font_family=‘sans-serif‘)
-
-
plt.title("karate_club spectral clustering")
-
plt.savefig("spectral_clustering_result.png")
-
所得聚类结果:

感谢python社区!
life is short, use python!
转:完整的最简单的谱聚类python代码
原文:https://www.cnblogs.com/lm3306/p/9337639.html