完整的最简单的谱聚类python代码

本文针对 Karate Club 数据集进行了谱聚类分析,通过计算正规化后的拉普拉斯矩阵并利用其第二特征值进行简单聚类,得到清晰的两分群组结果,并展示了聚类效果。

http://blog.youkuaiyun.com/waleking/article/details/7584084

针对karate_club数据集,做了谱聚类。由于是2-way clustering,比较简单,得到了图的新的表示空间之后,没有做k-means,仅仅针对正规化后的拉普拉斯矩阵的第二特征值做了符号判断,这和Spectral Clustering Tutorial 一文中的描述一致。

引用了numpy scipy matplotlib networkx包

#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):
	"""
	"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 are %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 are %s" % kEigVal)
print("k eig vec are %s" % kEigVec)
checkResult(Lbar,kEigVec,kEigVal,k)

#跳过k means,用最简单的符号判别的方法来求点的归属

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()

所得聚类结果:


感谢python社区!

life is short, use python!


### 各种聚类算法的Python实现 #### K-Means 聚类 K-Means 是一种简单而广泛使用的聚类算法,在 `scikit-learn` 库中有很好的支持。 ```python from sklearn.cluster import KMeans import numpy as np data = np.random.rand(100, 2) # 随机生成二维数据作为例子 kmeans = KMeans(n_clusters=3).fit(data) labels = kmeans.labels_ centroids = kmeans.cluster_centers_ print(labels) print(centroids) ``` 此代码展示了如何利用 `scikit-learn` 的 `KMeans` 类来执行 K-means 聚类分析[^1]。 #### 层次聚类 (Agglomerative Clustering) 层次聚类通过逐步合并最相似的数据点形成簇,直到达到指定数量为止。下面是一个基于 `sklearn` 的 AgglomerativeClustering 实现的例子: ```python from sklearn.cluster import AgglomerativeClustering clustering = AgglomerativeClustering(n_clusters=3).fit(data) labels = clustering.labels_ print(labels) ``` 这段代码实现了自底向上的层次聚合过程,并最终形成了三个类别标签[^2]。 #### DBSCAN 密度基聚类 DBSCAN 不需要预先设定簇的数量,而是依据密度自动发现任意形状的簇。 ```python from sklearn.cluster import DBSCAN dbscan = DBSCAN(eps=0.3, min_samples=10).fit(data) core_samples_mask = np.zeros_like(dbscan.labels_, dtype=bool) core_samples_mask[dbscan.core_sample_indices_] = True labels = dbscan.labels_ n_clusters_ = len(set(labels)) - (1 if -1 in labels else 0) print('Estimated number of clusters: %d' % n_clusters_) ``` 这里使用了 `DBSCAN` 来识别核心样本并计算估计出来的簇数目。 #### Mean Shift 均值漂移聚类 均值漂移是一种不需要提前定义簇数目的无监督学习方法。 ```python from sklearn.cluster import MeanShift, estimate_bandwidth bandwidth = estimate_bandwidth(data, quantile=0.2, n_samples=500) ms = MeanShift(bandwidth=bandwidth, bin_seeding=True) ms.fit(data) labels = ms.labels_ cluster_centers = ms.cluster_centers_ labels_unique = np.unique(labels) n_clusters_ = len(labels_unique) print("number of estimated clusters : %d" % n_clusters_) ``` 上述代码片段说明了怎样应用 `MeanShift` 进行聚类操作以及估算带宽参数。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值