(这个我也没有怎么懂,为了防止以后能用上,还是记录下来)
谱聚类
注意:谱聚类核心聚类算法还是K-means 算法进行聚类~
谱聚类的实现过程:
1.根据数据构造一个 图结构(Graph) ,Graph 的每一个节点对应一个数据点,将相 似的点连接起来,并且边的权重用于表示数据之间的相似度。把这个 Graph 用邻接矩阵的形式表示出来,记为 W 。
2. 把 W 的每一列元素加起来得到 N 个数,把它们放在对角线上(其他地方都是零), 组成一个 N * N的矩阵,记为 D 。并令 L = D-W 。
3. 求出 L 的前 k 个特征值,以及对应的特征向量。
4. 把这 k 个特征(列)向量排列在一起组成一个 N * k 的矩阵,将其中每一行看作 k 维空间中的一个向量,并使用 K-means 算法进行聚类。聚类的结果中每一行所属的类 别就是原来 Graph 中的节点亦即最初的N 个数据点分别所属的类别。
简单抽象谱聚类过程实现步骤:
简单抽象谱聚类过程,主要有两步:
1.构图,将采样点数据构造成一张网图。
2.切图,即将第一步构造出来的按照一定的切边准则,切分成不同的图,而不同的子图,即我们对 应的聚类结果。
代码实习:
总体感觉上是:先降维,然后再用K-means 算法聚类
import matplotlib.pyplot as plt
import numpy as np
from numpy import linalg as LA
from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs
from sklearn.metrics.pairwise import rbf_kernel
from sklearn.preprocessing import normalizedef similarity_function(points):"""相似性函数,利用径向基核函数计算相似性矩阵,对角线元素置为0对角线元素为什么要置为0我也不清楚,但是论文里是这么说的:param points::return:"""res = rbf_kernel(points)for i in range(len(res)):res[i, i] = 0return resdef spectral_clustering(points, k):"""谱聚类:param points: 样本点:param k: 聚类个数:return: 聚类结果"""W = similarity_function(points)# 度矩阵D可以从相似度矩阵W得到,这里计算的是D^(-1/2)# D = np.diag(np.sum(W, axis=1))# Dn = np.sqrt(LA.inv(D))# 本来应该像上面那样写,我做了点数学变换,写成了下面一行Dn = np.diag(np.power(np.sum(W, axis=1), -0.5))# 拉普拉斯矩阵:L=Dn*(D-W)*Dn=I-Dn*W*Dn(降维)# 也是做了数学变换的,简写为下面一行L = np.eye(len(points)) - np.dot(np.dot(Dn, W), Dn)eigvals, eigvecs = LA.eig(L)# 前k小的特征值对应的索引,argsort函数indices = np.argsort(eigvals)[:k]# 取出前k小的特征值对应的特征向量,并进行正则化k_smallest_eigenvectors = normalize(eigvecs[:, indices])# 利用KMeans进行聚类return KMeans(n_clusters=k).fit_predict(k_smallest_eigenvectors)'''
sklearn中的make_blobs()函数---为聚类产生数据集n_samples是待生成的样本的总数。n_features是每个样本的特征数。centers表示类别数。cluster_std表示每个类别的方差,例如我们希望生成2类数据,其中一类比另一类具有更大的方差,可以将cluster_std设置为[1.0,3.0]。
'''X, y = make_blobs(n_samples=100, n_features=2, centers=2)
labels = spectral_clustering(X, 3)# 画图
plt.style.use('ggplot')
# 原数据
fig, (ax0, ax1) = plt.subplots(ncols=2)
ax0.scatter(X[:, 0], X[:, 1], c=y)
ax0.set_title('raw data')
# 谱聚类结果
ax1.scatter(X[:, 0], X[:, 1], c=labels)
ax1.set_title('Spectral Clustering')
plt.show()