http://blog.csdn.net/waleking/article/details/7584084
Spectral clustering is done for Karate_club datasets. Because it is 2-way clustering, relatively simple, got the new representation space of the diagram, did not do K-means, only for the normalized Laplace matrix of the second eigenvalue to do a symbolic judgment, which and spectral clustering Tutorial The description in the article is consistent.
Reference to NumPy scipy matplotlib NETWORKX Package
- #coding =utf-8
- #MSC means multiple spectral clustering
- import NumPy as NP
- import scipy as sp
- import scipy.linalg as linalg
- import Networkx as NX
- import Matplotlib.pyplot as plt
- def Getnormlaplacian(W):
- "" " Input matrix w= (W_IJ)
- "Compute d=diag (D1,... DN)
- "and L=d-w
- "and lbar=d^ ( -1/2) ld^ ( -1/2)
- "Return Lbar
- """
- D=[np.sum (Row) for row in W]
- D=np.diag (d)
- L=d-w
- #Dn =d^ ( -1/2)
- Dn=np.power (Np.linalg.matrix_power (D,-1),0.5)
- Lbar=np.dot (Np.dot (dn,l), Dn)
- return Lbar
- def Getksmallesteigvec(lbar,k):
- "" "input
- "Matrix Lbar and K
- "Return
- "K smallest eigen values and their corresponding eigen vectors
- """
- Eigval,eigvec=linalg.eig (Lbar)
- Dim=len (Eigval)
- #查找前k小的eigval
- 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):
- """
- the input
- "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 is%s*%s"% (length,np.spacing (1)))
- G=nx.karate_club_graph ()
- Nodenum=len (G.nodes ())
- M=nx.to_numpy_matrix (g)
- Lbar=getnormlaplacian (M)
- k=2
- Keigval,keigvec=getksmallesteigvec (Lbar,k)
- Print ("K Eig Val is%s"% keigval)
- Print ("K Eig Vec is%s"% Keigvec)
- Checkresult (Lbar,keigvec,keigval,k)
- #跳过k means, using the simplest symbolic discriminant method to find the point of attribution
- 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]
- #draw Graph
- Collist=dict.fromkeys (G.nodes ())
- For Node,score in collist.items ():
- if node in clustera:
- collist[node]=0
- Else:
- collist[node]=0.6
- Plt.figure (figsize= (8,8))
- Pos=nx.spring_layout (g)
- Nx.draw_networkx_edges (g,pos,alpha=0.4)
- Nx.draw_networkx_nodes (G,pos,nodelist=collist.keys (),
- Node_color=collist.values (),
- Cmap=plt.cm.reds_r)
- Nx.draw_networkx_labels (g,pos,font_size=10,font_family=' Sans-serif ')
- Plt.axis (' off ')
- Plt.title ("Karate_club spectral Clustering")
- Plt.savefig ("Spectral_clustering_result.png")
- Plt.show ()
Resulting cluster results:
Thanks to the Python community!
Life was short, use python!
Turn: Complete simplest spectral clustering Python code