
基本思想
谱聚类是从图论中演化出来的算法,后来在聚类中得到了广泛的应用。它的主要思想是把所有的数据看做空间中的点,这些点之间可以用边连接起来。距离较远的两个点之间的边权重值较低,而距离较近的两个点之间的边权重值较高,通过对所有数据点组成的图进行切图,让切图后不同的子图间边权重和尽可能的低,而子图内的边权重和尽可能的高,从而达到聚类的目的。
谱聚类的算法流程可总结如下:
输入:样本集
D
=
(
x
1
,
x
2
,
⋯
,
x
n
)
D=(x_1,x_2,cdots,x_n)
D=(x1,x2,⋯,xn),相似矩阵的生成方式,降维后的维度
k
1
k_1
k1,聚类方法,聚类后的维度
k
2
k_2
k2
输出:簇划分
C
(
c
1
,
c
2
,
⋯
,
c
k
2
)
C(c_1,c_2,cdots,c_{k_2})
C(c1,c2,⋯,ck2)
(1)根据输入的相似矩阵的生成方式构建样本的相似矩阵
S
S
S
(2)根据相似矩阵
S
S
S构建邻接矩阵
W
W
W,构建度矩阵
D
D
D
(3)计算出拉普拉斯矩阵
L
L
L
(4)构建标准化后的拉普拉斯矩阵
D
−
1
2
L
D
−
1
2
D^{-frac{1}{2}}LD^{-frac{1}{2}}
D−21LD−21
(5)计算
D
−
1
2
L
D
−
1
2
D^{-frac{1}{2}}LD^{-frac{1}{2}}
D−21LD−21最小的
k
1
k_1
k1个特征值所各自对应的特征向量
f
f
f
(6)将各自对应的特征向量
f
f
f组成的矩阵按行标准化,最终组成
n
×
k
1
n times k_1
n×k1维的特征矩阵
F
F
F
(7)对
F
F
F中的每一行作为一个
k
1
k_1
k1维的样本,共
n
n
n个样本,用输入的聚类方法进行聚类,聚类维数为
k
2
k_2
k2
(8)得到簇划分
C
(
c
1
,
c
2
,
⋯
,
c
k
2
)
C(c_1,c_2,cdots,c_{k_2})
C(c1,c2,⋯,ck2)
谱聚类的主要优点有:
(1)谱聚类只需要数据之间的相似度矩阵,因此对于处理稀疏数据的聚类很有效。传统聚类算法比如K-Means很难做到这一点
(2)由于使用了降维,因此在处理高维数据聚类时的复杂度比传统聚类算法好
谱聚类的主要缺点有:
(1)如果最终聚类的维度非常高,则由于降维的幅度不够,谱聚类的运行速度和最后的聚类效果可能都不好
(2)聚类效果依赖于相似矩阵,不同的相似矩阵得到的最终聚类效果可能很不同
API学习
sklearn.cluster.spectral_clustering( affinity, *, n_clusters=8, n_components=None, eigen_solver=None, random_state=None, n_init=10, eigen_tol=0.0, assign_labels='kmeans', verbose=False )
代码示例
>>> from sklearn.cluster import SpectralClustering >>> sc = SpectralClustering(3, affinity='precomputed', n_init=100, ... assign_labels='discretize') >>> sc.fit_predict(adjacency_matrix)
作品学习
import numpy as np import matplotlib.pyplot as plt from sklearn.feature_extraction import image from sklearn.cluster import spectral_clustering l = 100 x, y = np.indices((l, l)) center1 = (28, 24) center2 = (40, 50) center3 = (67, 58) center4 = (24, 70) radius1, radius2, radius3, radius4 = 16, 14, 15, 14 circle1 = (x - center1[0]) ** 2 + (y - center1[1]) ** 2 < radius1 ** 2 circle2 = (x - center2[0]) ** 2 + (y - center2[1]) ** 2 < radius2 ** 2 circle3 = (x - center3[0]) ** 2 + (y - center3[1]) ** 2 < radius3 ** 2 circle4 = (x - center4[0]) ** 2 + (y - center4[1]) ** 2 < radius4 ** 2 # ############################################################################# # 4 circles img = circle1 + circle2 + circle3 + circle4 # We use a mask that limits to the foreground: the problem that we are # interested in here is not separating the objects from the background, # but separating them one from the other. mask = img.astype(bool) img = img.astype(float) img += 1 + 0.2 * np.random.randn(*img.shape) # Convert the image into a graph with the value of the gradient on the # edges. graph = image.img_to_graph(img, mask=mask) # Take a decreasing function of the gradient: we take it weakly # dependent from the gradient the segmentation is close to a voronoi graph.data = np.exp(-graph.data / graph.data.std()) # Force the solver to be arpack, since amg is numerically # unstable on this example labels = spectral_clustering(graph, n_clusters=4, eigen_solver="arpack") label_im = np.full(mask.shape, -1.0) label_im[mask] = labels plt.matshow(img) plt.matshow(label_im) # ############################################################################# # 2 circles img = circle1 + circle2 mask = img.astype(bool) img = img.astype(float) img += 1 + 0.2 * np.random.randn(*img.shape) graph = image.img_to_graph(img, mask=mask) graph.data = np.exp(-graph.data / graph.data.std()) labels = spectral_clustering(graph, n_clusters=2, eigen_solver="arpack") label_im = np.full(mask.shape, -1.0) label_im[mask] = labels plt.matshow(img) plt.matshow(label_im) plt.show()
运行结果:
参考文献
[1] Normalized cuts and image segmentation, 2000 Jianbo Shi, Jitendra Malik
[2] A Tutorial on Spectral Clustering, 2007 Ulrike von Luxburg
[3] Multiclass spectral clustering, 2003 Stella X. Yu, Jianbo Shi
[4] Toward the Optimal Preconditioned Eigensolver: Locally Optimal Block Preconditioned Conjugate Gradient Method, 2001. A. V. Knyazev SIAM Journal on Scientific Computing 23, no. 2, pp. 517-541.
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)