【数据聚类】第八章第二节:谱聚类算法之切图聚类、算法流程及其实现
【数据聚类】第八章第二节:谱聚类算法之切图聚类、算法流程及其实现本文部分内容源自刘建平博客,在此基础上进行总结拓展
原文链接
文章目录
一:谱聚类与图划分
(1)比例割
(2)规范割(常用)
二:谱聚类算法流程
三:Python实现
四:谱聚类算法优缺点
(1)优点
(2)缺点
一:谱聚类与图划分
无向图切图:谱聚类算法根据数据点之间的相似度将数据点划分到不同簇中,因此将数据点映射到无向图之后,可以转化为图划分的问题。对于无向图G GG,切图的目标是将图G ( V , E ) G(V,E)G(V,E)切分成互相无连接k kk个子图,其中
每个子图点的集合为{ A 1 , A 2 , . . . , A k } \{A_{1},A_{2},...,A_{k}\}{A
1
,A
2
,...,A
k
},且满足A i ∩ A j = ∅ A_{i}\cap A_{j}=\emptyA
i
∩A
j
=∅、A 1 ∪ A 2 ∪ . . . ∪ A k = V A_{1}\cup A_{2}\cup ... \cup A_{k}=VA
1
∪A
2
∪...∪A
k
=V
对于任意两个子图点的集合A AA、B BB,我们定义A AA和B BB之间的切图权重为W ( A , B ) = ∑ i ∈ A , j ∈ B w i j W(A,B)=\sum\limits_{i\in A,j \in B} w_{ij}W(A,B)=
i∈A,j∈B
∑
w
ij
对于k kk个子图点的集合{ A 1 , A 2 , . . . , A k } \{A_{1},A_{2},...,A_{k}\}{A
1
,A
2
,...,A
k
},定义切图c u t ( A 1 , A 2 , . . . , A k ) = 1 2 ∑ i = 1 k W ( A i , A ˉ i ) cut(A_{1},A_{2},...,A_{k})=\frac{1}{2}\sum\limits_{i=1}^{k}W(A_{i},\bar A_{i})cut(A
1
,A
2
,...,A
k
)=
2
1
i=1
∑
k
W(A
i
,
A
ˉ
i
) (其中A ˉ i \bar A_{i}
A
ˉ
i
为A i A_{i}A
i
的补集)
可以看出,c u t cutcut描述了子图之间的相似性,c u t cutcut越小那么子图的差异性就越大。但是c u t ( A 1 , A 2 , . . . , A k ) = 1 2 ∑ i = 1 k W ( A i , A ˉ i ) cut(A_{1},A_{2},...,A_{k})=\frac{1}{2}\sum\limits_{i=1}^{k}W(A_{i},\bar A_{i})cut(A
1
,A
2
,...,A
k
)=
2
1
i=1
∑
k
W(A
i
,
A
ˉ
i
)在划分子图时并没有考虑每个子图中节点的个数。所以在某些情况下,最小化c u t ( A 1 , A 2 , . . . , A k ) cut(A_{1},A_{2},...,A_{k})cut(A
1
,A
2
,...,A
k
)可能会把一个数据点或是很少数据点看做一个子图,导致子图划分结果不平衡
例如下图,选择一个权重最小的边缘的点,比如C CC和H HH之间进行c u t cutcut,这样可以最小化c u t ( A 1 , A 2 , . . . , A k ) cut(A_{1},A_{2},...,A_{k})cut(A
1
,A
2
,...,A
k
)但是却不是最优的切图
为了解决这个问题,会引入一些正则化方法。最常用的两种方法为比例割和规范割
比例割:R a t i o c u t ( A 1 , A 2 , . . . , A k ) = 1 2 ∑ i = 1 k W ( A i , A ˉ i ) ∣ A i ∣ Ratiocut(A_{1},A_{2},...,A_{k})=\frac{1}{2}\sum\limits_{i=1}^{k}\frac{W(A_{i},\bar A_{i})}{|A_{i}|}Ratiocut(A
1
,A
2
,...,A
k
)=
2
1
i=1
∑
k
∣A
i
∣
W(A
i
,
A
ˉ
i
)
规范割:N C u t ( A 1 , A 2 , . . . , A k ) = 1 2 ∑ i = 1 k W ( A i , A ˉ i ) v o l ( A i ) NCut(A_{1},A_{2},...,A_{k})=\frac{1}{2}\sum\limits_{i=1}^{k}\frac{W(A_{i},\bar A_{i})}{vol(A _{i})}NCut(A
1
,A
2
,...,A
k
)=
2
1
i=1
∑
k
vol(A
i
)
W(A
i
,
A
ˉ
i
)
(1)比例割
引入指示向量(点击可查看指示向量定义)h j ∈ { h 1 , h 2 , . . . , h k } h_{j}\in\{h_{1},h_{2},...,h_{k}\}h
j
∈{h
1
,h
2
,...,h
k
},j = 1 , 2 , . . . , k j=1,2,...,kj=1,2,...,k。对于任意一个向量h j h_{j}h
j
,它是一个n nn维向量(n nn表示样本数),定义h i j h_{ij}h
ij
如下
h i j = { 0 , v i ∉ A j ∣ A j ∣ , v i ∈ A j h_{ij}=
{0,vi∉Aj|Aj|−−−√,vi∈Aj
{0,vi∉Aj|Aj|,vi∈Aj
h
ij
={
0,v
i
∈
/
A
j
∣A
j
∣
,v
i
∈A
j
于是,对于h i T L h i h_{i}^{T}Lh_{i}h
i
T
Lh
i
,根据拉普拉斯矩阵性质可知
对于任意向量f = ( f 1 , . . . , f n ) T ∈ R n f=(f_{1},...,f_{n})^{T} \in R^{n}f=(f
1
,...,f
n
)
T
∈R
n
,有f T L f = 1 2 ∑ i , j = 1 n w i j ( f i − f j ) 2 f^{T}Lf=\frac{1}{2}\sum\limits_{i,j=1}^{n}w_{ij}(f_{i}-f_{j})^{2}f
T
Lf=
2
1
i,j=1
∑
n
w
ij
(f
i
−f
j
)
2
h i T L h i = 1 2 ∑ m = 1 ∑ n = 1 w m n ( h i m − h i n ) 2 = c u t ( A i , A ˉ i ) ∣ A i ∣ h_{i}^{T}Lh_{i}=\frac{1}{2}\sum\limits_{m=1}\sum\limits_{n=1}w_{mn}(h_{im}-h_{in})^{2}=\frac{cut(A_{i},\bar A_{i})}{|A_{i}|}
h
i
T
Lh
i
=
2
1
m=1
∑
n=1
∑
w
mn
(h
im
−h
in
)
2
=
∣A
i
∣
cut(A
i
,
A
ˉ
i
)
严格证明过程请看刘建平博客:链接
可以看到,对于某一个子图i ii,R a t i o n C u t RationCutRationCut就对应于h i T L h i h_{i}^{T}Lh_{i}h
i
T
Lh
i
,那么对于k kk个子图
R a t i o C u t ( A 1 , A 2 , . . . , A k ) = ∑ i = 1 k h i T L h i = ∑ i = 1 k ( H T L H ) i i = t r ( H T L H ) RatioCut(A_{1},A_{2},...,A_{k})=\sum\limits_{i=1}^{k}h_{i}^{T}Lh_{i}=\sum\limits_{i=1}^{k}(H^{T}LH)_{ii}=tr(H^{T}LH)
RatioCut(A
1
,A
2
,...,A
k
)=
i=1
∑
k
h
i
T
Lh
i
=
i=1
∑
k
(H
T
LH)
ii
=tr(H
T
LH)
因此,R a t i o n C u t RationCutRationCut切图本质就是最小化t r ( H T L H ) tr(H^{T}LH)tr(H
T
LH)。又因为H T H = I H^{T}H=IH
T
H=I(单位矩阵),则切图优化目标为
a r g m i n ⏟ H t r ( H T L H ) s . t . H T H = I \underbrace{argmin}_{H} tr(H^{T}LH) s.t.H^{T}H=I
H
argmin
tr(H
T
LH)s.t.H
T
H=I
对于优化目标t r ( H t L H ) tr(H^{t}LH)tr(H
t
LH)中的每一个优化子目标h i T L h i h_{i}^{T}Lh_{i}h
i
T
Lh
i
,其中的h hh是单位正交基,L LL为对称矩阵,所以此时h i T L h i h_{i}^{T}Lh_{i}h
i
T
Lh
i
的最大值即为L LL的最大特征值、最小值即为L LL的最小特征值。而在谱聚类中,我们的目标就是要找到目标的最小特征值,得到对应特征值向量,此时切图效果最佳。所以对于h i T L h i h_{i}^{T}Lh_{i}h
i
T
Lh
i
,目标就是找到L LL的最小特征值,而对于t r ( H t L H ) = ∑ i = 1 k h i T L h i tr(H^{t}LH)=\sum\limits_{i=1}^{k}h_{i}^{T}Lh_{i}tr(H
t
LH)=
i=1
∑
k
h
i
T
Lh
i
,则目标就是要找到k kk个最小的特征值
因此,通过找到L LL的最小的k kk个特征值,可以得到对应的k kk个特征向量,这k kk特特征向量组成一个n nn×k kk维矩阵,也即H HH。一般需要对矩阵H HH按行做标准化,如下
一般来说,k kk远小于n nn,也就说进行了降维
h i j ∗ = h i j ( ∑ t = 1 k h i t 2 ) 1 2 h_{ij}^{*}=\frac{h_{ij}}{(\sum\limits_{t=1}^{k}h_{it}^2)^{\frac{1}{2}}}
h
ij
∗
=
(
t=1
∑
k
h
it
2
)
2
1
h
ij
这里需要注意,降维后导致得到的指示向量h hh对应的H HH现在并不能完全指示各样本的归属,因此一般在得到n × k n×kn×k维的矩阵H HH后还需要对每一行进行一次传统的聚类,比如使用K-Means聚类
(2)规范割(常用)
规范割和比例割类似,只是把比例割的分母∣ A i ∣ |A_{i}|∣A
i
∣换成了v o l ( A i ) vol(A_{i})vol(A
i
),定义指示向量h i j h_{ij}h
ij
如下
h i j = { 0 , v i ∉ A j v o l ( A i ) , v i ∈ A j h_{ij}=
{0,vi∉Ajvol(Ai)−−−−−−√,vi∈Aj
{0,vi∉Ajvol(Ai),vi∈Aj
h
ij
={
0,v
i
∈
/
A
j
vol(A
i
)
,v
i
∈A
j
于是,对于h i T L h i h_{i}^{T}Lh_{i}h
i
T
Lh
i
,根据拉普拉斯矩阵性质可知
对于任意向量f = ( f 1 , . . . , f n ) T ∈ R n f=(f_{1},...,f_{n})^{T} \in R^{n}f=(f
1
,...,f
n
)
T
∈R
n
,有f T L f = 1 2 ∑ i , j = 1 n w i j ( f i − f j ) 2 f^{T}Lf=\frac{1}{2}\sum\limits_{i,j=1}^{n}w_{ij}(f_{i}-f_{j})^{2}f
T
Lf=
2
1
i,j=1
∑
n
w
ij
(f
i
−f
j
)
2
h i T L h i = 1 2 ∑ m = 1 ∑ n = 1 w m n ( h i m − h i n ) 2 = c u t ( A i , A ˉ i ) v o l ( A i ) h_{i}^{T}Lh_{i}=\frac{1}{2}\sum\limits_{m=1}\sum\limits_{n=1}w_{mn}(h_{im}-h_{in})^{2}=\frac{cut(A_{i},\bar A_{i})}{vol(A_{i})}
h
i
T
Lh
i
=
2
1
m=1
∑
n=1
∑
w
mn
(h
im
−h
in
)
2
=
vol(A
i
)
cut(A
i
,
A
ˉ
i
)
严格证明过程请看刘建平博客:链接
可以看到,对于某一个子图i ii,R a t i o n C u t RationCutRationCut就对应于h i T L h i h_{i}^{T}Lh_{i}h
i
T
Lh
i
,那么对于k kk个子图
N C u t ( A 1 , A 2 , . . . , A k ) = ∑ i = 1 k h i T L h i = ∑ i = 1 k ( H T L H ) i i = t r ( H T L H ) NCut(A_{1},A_{2},...,A_{k})=\sum\limits_{i=1}^{k}h_{i}^{T}Lh_{i}=\sum\limits_{i=1}^{k}(H^{T}LH)_{ii}=tr(H^{T}LH)
NCut(A
1
,A
2
,...,A
k
)=
i=1
∑
k
h
i
T
Lh
i
=
i=1
∑
k
(H
T
LH)
ii
=tr(H
T
LH)
但此时H T H ≠ I H^{T}H \not=IH
T
H
=I,而是H T D H = I H^{T}DH =IH
T
DH=I
这是因为h i T D h i = ∑ j = 1 n h i j 2 d j = 1 v o l ( A i ) ∑ j ∈ A i d j = 1 v o l ( A i ) v o l ( A i ) = 1 h_{i}^{T}Dh_{i}=\sum\limits_{j=1}^{n}h_{ij}^{2}d_{j}=\frac{1}{vol(A_{i})}\sum\limits_{j\in A_{i}}d_{j}=\frac{1}{vol(A_{i})}vol(A_{i})=1h
i
T
Dh
i
=
j=1
∑
n
h
ij
2
d
j
=
vol(A
i
)
1
j∈A
i
∑
d
j
=
vol(A
i
)
1
vol(A
i
)=1
因此,此时切图优化目标为
a r g m i n ⏟ H t r ( H T L H ) s . t . H T D H = I \underbrace{argmin}_{H} tr(H^{T}LH) s.t.H^{T}DH=I
H
argmin
tr(H
T
LH)s.t.H
T
DH=I
但是现在矩阵H HH中的指示向量h hh并不是标准正交基,所以需要对H HH做一定转换。令H = D − 1 2 F H=D^{-\frac{1}{2}}FH=D
−
2
1
F,则H T L H = F T D − 1 2 L D − 1 2 F H^{T}LH=F^{T}D^{-\frac{1}{2}}LD^{-\frac{1}{2}}FH
T
LH=F
T
D
−
2
1
LD
−
2
1
F、H T D H = F T F = I H^{T}DH=F^{T}F=IH
T
DH=F
T
F=I,于是优化目标变更为
a r g m i n ⏟ F t r ( F T D − 1 2 L D − 1 2 F ) s . t . F T F = I \underbrace{argmin}_{F} tr(F^{T}D^{-\frac{1}{2}}LD^{-\frac{1}{2}}F) s.t.F^{T}F=I
F
argmin
tr(F
T
D
−
2
1
LD
−
2
1
F)s.t.F
T
F=I
现在,和比例割一样,通过找到D − 1 2 L D − 1 2 D^{-\frac{1}{2}}LD^{-\frac{1}{2}}D
−
2
1
LD
−
2
1
(就是之前的L LL)的最小的k kk个特征值,可以得到对应的k kk个特征向量,这k kk特征向量组成一个n nn×k kk维矩阵,也即F FF,最后对F FF进行传统聚类
一般来说,D − 1 2 L D − 1 2 D^{-\frac{1}{2}}LD^{-\frac{1}{2}}D
−
2
1
LD
−
2
1
相当于对L LL做了一次标准化,也即L i j d i ∗ d j \frac{L_{ij}}{\sqrt{d_{i}*d_{j}}}
d
i
∗d
j
L
ij
二:谱聚类算法流程
给定数据集D = { x 1 , x 2 , . . . , x n } D=\{x_{1}, x_{2}, ... , x_{n}\}D={x
1
,x
2
,...,x
n
}
根据输入的相似矩阵生成方式(一般为高斯核函数)构建相似矩阵S SS(AffinityMatrix)
根据相似矩阵S SS构建邻接矩阵W WW,再构建度矩阵D DD
计算拉普拉斯矩阵L = D − W L=D-WL=D−W
得到标准化后的拉普拉斯矩阵D − 1 2 L D − 1 2 D^{-\frac{1}{2}}LD^{-\frac{1}{2}}D
−
2
1
LD
−
2
1
计算D − 1 2 L D − 1 2 D^{-\frac{1}{2}}LD^{-\frac{1}{2}}D
−
2
1
LD
−
2
1
最小的k kk个特征值对应的特征向量f ff
将特征向量f ff组成矩阵并按行标准化,最终组成n nn×k kk维的特征矩阵F FF
F FF中每一行作为一个k kk维的样本,共n nn个样本,采用某种聚类方法进行聚类,假设聚类维数为k 、 k^{、}k
、
得到簇划分C( c 1 , c 2 , . . . , c k 、 ) (c_{1}, c_{2}, ... , c_{k^{、}})(c
1
,c
2
,...,c
k
、
)
三:Python实现
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from sklearn.cluster import KMeans
from sklearn.metrics.pairwise import rbf_kernel
from sklearn.datasets import make_blobs
from sklearn.preprocessing import normalize
def get_affinity_matrix(data_set):
# 利用高斯核函数计算相似矩阵(全连接)
rbf = rbf_kernel(data_set)
for i in range(len(rbf)):
rbf = 0
return rbf
def distance(x1, x2):
"""
获得两个样本点之间的距离
:param x1: 样本点1
:param x2: 样本点2
:return:
"""
dist = np.sqrt(np.power(x1-x2,2).sum())
return dist
def get_dist_matrix(data):
"""
获取距离矩阵
:param data: 样本集合
:return: 距离矩阵
"""
n = len(data) #样本总数
dist_matrix = np.zeros((n, n)) # 初始化邻接矩阵为n×n的全0矩阵
for i in range(n):
for j in range(i+1, n):
dist_matrix = dist_matrix = distance(data, data)
return dist_matrix
def get_W(data, k):
# 获取邻接矩阵(K邻近法)
n = len(data)
dist_matrix = get_dist_matrix(data)
W = np.zeros((n, n))
for idx, item in enumerate(dist_matrix):
idx_array = np.argsort(item) # 每一行距离列表进行排序,得到对应的索引列表
W] = 1
transpW =np.transpose(W)
return (W+transpW)/2
def spectral_clustering(data_set, k):
# 利用相似矩阵S得到邻接矩阵W
W = get_affinity_matrix(data_set) #高斯核函数(全连接法)
# W = get_W(data_set, k) # K邻近法
# 计算度矩阵D,并得到矩阵D的1/2次方的逆矩阵(便于计算拉普拉斯矩阵)
D_inv = np.diag(np.power(np.sum(W, axis=1), -0.5))
# 计算拉普拉斯矩阵L=D-W
# 标准化拉普拉斯矩阵l = D_inv*L*D_inv=I-D_inv*W*D_inv
L = np.eye(len(data_set)) - np.dot(np.dot(D_inv, W), D_inv)
# 得到特征值和特征向量
eigvals, eigvecs = np.linalg.eig(L)
# 找到前k个最小的特征值(索引)
k_smallest_eigvals_index = np.argsort(eigvals)[:k]
# 取出这k小特征值对应的特征向量,并正则化
k_smallest_eigvecs = normalize(eigvecs[:, k_smallest_eigvals_index])
# 使用K_Means聚类
return KMeans(n_clusters=k).fit_predict(k_smallest_eigvecs)
raw_data = pd.read_csv(r'E:\Postgraduate\Dataset\jain.csv', header=None)
raw_data.columns = ['X', 'Y']
x_axis = 'X'
y_axis = 'Y'
examples_num = raw_data.shape
train_data = raw_data[].values.reshape(examples_num, 2)
min_vals = train_data.min(0)
max_vals = train_data.max(0)
ranges = max_vals - min_vals
normal_data = np.zeros(np.shape(train_data))
nums = train_data.shape
normal_data = train_data - np.tile(min_vals, (nums, 1))
normal_data = normal_data / np.tile(ranges, (nums, 1))
labels = spectral_clustering(normal_data, 2)
# 原数据
fig, (ax0, ax1) = plt.subplots(ncols=2)
ax0.scatter(normal_data[:, 0], normal_data[:, 1], c='black')
ax0.set_title('raw data')
# 谱聚类结果
ax1.scatter(normal_data[:, 0], normal_data[:, 1], c=labels)
ax1.set_title('Spectral Clustering')
plt.show()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
(高斯核函数)
(K邻近法)
四:谱聚类算法优缺点
(1)优点
谱聚类只需要数据之间的相似度矩阵,所以对于稀疏数据的聚类很有效
使用了降维,因此处理高纬数据聚类时复杂度要明显低于传统聚类算法
谱聚类算法建立在谱图理论基础上,与传统聚类算法相比,它具有能在任意形状的样本空间上聚类且收敛于全局最优解
(2)缺点
如果最终聚类的维度非常高,则由于降维的幅度不够,导致算法的运行速度和最后效果都不是很好
聚类效果依赖于相似度矩阵,所以不同的相似度矩阵得到的最终聚类效果大不同相同
————————————————
版权声明:本文为CSDN博主「快乐江湖」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_39183034/article/details/126747494
页:
[1]