谱聚类(spectral clustering)是广泛使用的聚类算法,比起传统的K-Means算法,谱聚类对数据分布的适应性更强,聚类效果也很优秀,同时聚类的计算量也小很多,更加难能可贵的是实现起来也不复杂。在处理实际的聚类问题时,个人认为谱聚类是应该首先考虑的几种算法之一。下面我们就对谱聚类的算法原理做一个总结。
谱聚类是从图论中演化出来的算法,后来在聚类问题中得到了广泛的应用。它的主要思想是把所有的数据看作空间中的点,这些点之间可以用边连接起来。距离较远的两个点之间的边权重较低,距离越近权重越高,通过对所有数据点组成的图进行切图,让切图后不同的子图间边权重和尽可能的低,而子图内的边权重和尽可能的高,从而达到聚类的目的。
乍一看,这个算法的原理的确简单,但是要完全理解这个算法的话,需要对图论中的无向图,线性代数和矩阵分析都有一定的了解。下面我们就从这些基础知识开始,一步步学习谱聚类。
对于一个图,我们一般用点的集合V和边的集合E来描述,即为G(V,E)。
对于有边连接的两个点 v i , v j v_i,v_j vi,vj, w i , j > 0 w_{i,j}>0 wi,j>0;对于没有边相连的两个点, w i , j = 0 w_{i,j}=0 wi,j=0;由于我们是无向图,所以, w i , j = w j , i w_{i,j}=w_{j,i} wi,j=wj,i
对于图中的任意一个点 v i v_i vi,它的度 d i d_i di定义为和它相连的所有边的权重之和,即:
d i = ∑ j = 1 n w i j d_i=\sum_{j=1}^{n}w_{ij} di=j=1∑nwij
利用每个点度的定义,我们可以得到一个nxn的度矩阵D,它是一个对角矩阵,只有主对角线有值,对应第i行的第i个点的度数,定义如下:
D = [ d 1 . . . . . . . . . d 2 . . . . . . . . . d n ] D=\begin{bmatrix} d_1 & ...&... \\ ... &d_2 &... \\ ... &... & d_n \end{bmatrix} D=⎣⎡d1.........d2.........dn⎦⎤
利用点和点之间的权重值,我们可以得到图的邻接矩阵W,除此之外,我们定义:
∣ A ∣ : 子 集 A 中 点 的 个 数 |A|:子集A中点的个数 ∣A∣:子集A中点的个数
v o l ( A ) = ∑ i ∈ A d i vol(A)=\sum_{i\in A}d_i vol(A)=i∈A∑di
如何得到邻接矩阵呢?方法有三类: ∈ \in ∈-邻近法、K近邻法、全连接法。
w i , j = { 0 , s i j > ∈ ∈ , s i j < = ∈ w_{i,j}= \begin{cases} 0, & s_{ij}>\in \\ \in, & s_{ij}<=\in \end{cases} wi,j={0,∈,sij>∈sij<=∈
从上式可见,两点间的权重要不就是 ∈ \in ∈,要不就是0,没有其他的信息了。距离远近的度量很不精确,因此在实际生活中,很少用该方法。
**第一种方法是:**只要一个点在另一个点的K近邻中,则保留 x i j x_{ij} xij
w i j = w j i = { 0 x i ∉ K N N ( x j ) a n d x j ∉ K N N ( x i ) e x p ( − ∣ ∣ x i − x j ∣ ∣ 2 2 θ 2 ) x i ∉ K N N ( x j ) o r x j ∉ K N N ( x i ) w_{ij}=w_{ji}= \begin{cases} 0 &x_i\notin KNN(x_j) and x_j\notin KNN(x_i)\\ exp(-\frac{||x_i-x_j||^2}{2\theta^2}) &x_i\notin KNN(x_j) or x_j\notin KNN(x_i) \end{cases} wij=wji={0exp(−2θ2∣∣xi−xj∣∣2)xi∈/KNN(xj)andxj∈/KNN(xi)xi∈/KNN(xj)orxj∈/KNN(xi)
**第二种方法是:**必须两个点互为K近邻,则保留 x i j x_{ij} xij
w i j = w j i = { 0 x i ∉ K N N ( x j ) o r x j ∉ K N N ( x i ) e x p ( − ∣ ∣ x i − x j ∣ ∣ 2 2 θ 2 ) x i ∉ K N N ( x j ) a n d x j ∉ K N N ( x i ) w_{ij}=w_{ji}=\begin{cases}0 &x_i\notin KNN(x_j) or x_j\notin KNN(x_i)\\exp(-\frac{||x_i-x_j||^2}{2\theta^2}) &x_i\notin KNN(x_j) and x_j\notin KNN(x_i)\end{cases} wij=wji={0exp(−2θ2∣∣xi−xj∣∣2)xi∈/KNN(xj)orxj∈/KNN(xi)xi∈/KNN(xj)andxj∈/KNN(xi)
w i j = s i j = e x p ( − ∣ ∣ x i − x j ∣ ∣ 2 2 θ 2 ) w_{ij}=s_{ij}=exp(-\frac{||x_i-x_j||^2}{2\theta^2}) wij=sij=exp(−2θ2∣∣xi−xj∣∣2)
在实际的应用中,使用第三种全连接法来简历邻接矩阵是最普遍的,而在全连接法中使用高斯径向核RBF是最普遍的。
拉普拉斯矩阵(Graph Laplacians)和后面要介绍的算法息息相关,它的定义很简单:
L = D − W L=D-W L=D−W
其中,D是度矩阵,W是邻接矩阵。
拉普拉斯矩阵的性质:
f T L f = 1 2 ∑ i , j = 1 n w i j ( f i − f j ) 2 f^TLf=\frac{1}{2}\sum_{i,j=1}^nw_{ij}(f_i-f_j)^2 fTLf=21i,j=1∑nwij(fi−fj)2
利用拉普拉斯矩阵的定义,证明过程如下:
f T L f = f T D f − f T W f = ∑ i = 1 n d i f i 2 − ∑ i , j = 1 n w i j f i f j f^TLf=f^TDf-f^TWf=\sum_{i=1}^nd_if_i^2-\sum_{i,j=1}^nw_{ij}f_if_j fTLf=fTDf−fTWf=i=1∑ndifi2−i,j=1∑nwijfifj
= 1 2 ( ∑ i = 1 n d i f i 2 − 2 ∑ i , j = 1 n w i j f i f j + ∑ j = 1 n d j f j 2 ) = 1 2 ∑ i , j = 1 n w i j ( f i − f j ) 2 =\frac{1}{2}(\sum_{i=1}^nd_if_i^2-2\sum_{i,j=1}^nw_{ij}f_if_j+\sum_{j=1}^nd_jf_j^2) =\frac{1}{2}\sum_{i,j=1}^nw_{ij}(f_i-f_j)^2 =21(i=1∑ndifi2−2i,j=1∑nwijfifj+j=1∑ndjfj2)=21i,j=1∑nwij(fi−fj)2
对于无向图G的切图,我们的目标是将图G(V,E)切成相互没有连接的k个子图,每个子图点的集合是: A 1 , A 2 , . . . , A k A_1,A_2,...,A_k A1,A2,...,Ak,他们满足 A i ∩ A j = 0 A_i\cap A_j=0 Ai∩Aj=0,且 A 1 ∪ A 2 ∪ . . . ∪ A k = V A_1\cup A_2\cup...\cup A_k=V A1∪A2∪...∪Ak=V。
对于任意两个子图点的集合A、B,我们定义A和B之间的切图权重为:
W ( A , B ) = ∑ i ∈ A , j ∈ B w i j W(A,B)=\sum_{i\in A,j\in B}w_{ij} W(A,B)=i∈A,j∈B∑wij
那么对于我们k个子图间的集合: A 1 , A 2 , . . . , A k A_1,A_2,...,A_k A1,A2,...,Ak,我们定义切图cut为:
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_{i=1}^{k}W(A_i,\bar{A_i}) cut(A1,A2,...,Ak)=21i=1∑kW(Ai,Aiˉ)
其中 A i ˉ \bar{A_i} Aiˉ为 A i A_i Ai的补集,意思是除 A i A_i Ai子集外其他V的子集的并集。
那么如何切图让子图内的点权重和高,子图间的点权重和低呢?一个自然的想法就是最小化 c u t ( A 1 , A 2 , . . . , A k ) cut(A_1,A_2,...,A_k) cut(A1,A2,...,Ak),但是可以发现,这种方法存在很大的问题,如下图
我们选择一个权重最小的边缘的点,比如C和H之间进行cut,这样确实可以最小化,但是却不是最优的子图,那么如何找到最优切图呢?请看下一节。
为了避免最小化切图方式导致的效果不佳,我们需要对每个子图的规模做出限定,一般来说,有两种切图方式:RatioCut、Ncut。下面我们分别加以介绍:
对每个切图,不光考虑最小化 c u t ( A 1 , A 2 , . . . , A k ) cut(A_1,A_2,...,A_k) cut(A1,A2,...,Ak),它还同时考虑最大化每个子图点的个数,即:
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_{i=1}^{k}\frac{W(A_i,\bar{A_i})}{|A_i|} RatioCut(A1,A2,...,Ak)=21i=1∑k∣Ai∣W(Ai,Aiˉ)
∣ A ∣ : 子 集 A 中 点 的 个 数 |A|:子集A中点的个数 ∣A∣:子集A中点的个数
**具体方法:**引入指示向量 h j ∈ ( h 1 , h 2 , . . . , h k ) , j = 1 , 2 , . . . k h_j\in (h_1,h_2,...,h_k),j=1,2,...k hj∈(h1,h2,...,hk),j=1,2,...k,对于任意一个向量 h j h_j hj,它是一个n维向量(n为样本数),我们定义 h i j h_{ij} hij为:
h i j = { 0 v i ∉ A j 1 ∣ A j ∣ v i ∈ A j h_{ij}= \begin{cases} 0 & v_i \notin A_j\\ \frac{1}{\sqrt{|A_j|} }& v_i \in A_j \end{cases} hij={0∣Aj∣1vi∈/Ajvi∈Aj
那么我们对于 h i T L h i h_i^TLh_i hiTLhi有:
h i T L h i = 1 2 ∑ m = 1 ∑ n = 1 w m n ( h i m − h i n ) 2 h_i^TLh_i=\frac{1}{2}\sum_{m=1}\sum_{n=1}w_{mn}(h_{im}-h_{in})^2 hiTLhi=21m=1∑n=1∑wmn(him−hin)2
= 1 2 ∑ m ∈ A i ∑ n ∉ A i w m n ( 1 ∣ A j ∣ − 0 ) 2 = 1 2 ∑ m ∉ A i ∑ n ∈ A i w m n ( 0 − 1 ∣ A j ∣ ) 2 =\frac{1}{2}\sum_{m\in A_i}\sum_{n\notin A_i}w_{mn}(\frac{1}{\sqrt{|A_j|} }-0)^2=\frac{1}{2}\sum_{m\notin A_i}\sum_{n\in A_i}w_{mn}(0-\frac{1}{\sqrt{|A_j|} })^2 =21m∈Ai∑n∈/Ai∑wmn(∣Aj∣1−0)2=21m∈/Ai∑n∈Ai∑wmn(0−∣Aj∣1)2
= 1 2 ∑ m ∈ A i ∑ n ∉ A i w m n 1 ∣ A j ∣ = 1 2 ∑ m ∉ A i ∑ n ∈ A i w m n 1 ∣ A j ∣ =\frac{1}{2}\sum_{m\in A_i}\sum_{n\notin A_i}w_{mn}\frac{1}{|A_j| }=\frac{1}{2}\sum_{m\notin A_i}\sum_{n\in A_i}w_{mn}\frac{1}{|A_j| } =21m∈Ai∑n∈/Ai∑wmn∣Aj∣1=21m∈/Ai∑n∈Ai∑wmn∣Aj∣1
= 1 2 ( c u t ( A i , A i ˉ ) 1 ∣ A i ∣ + c u t ( A i ˉ , A i ) 1 ∣ A i ∣ ) = c u t ( A i , A i ˉ ) ∣ A i ∣ =\frac{1}{2}(cut(A_i,\bar{A_i})\frac{1}{|A_i|}+cut(\bar{A_i},A_i)\frac{1}{|A_i|})=\frac{cut(A_i,\bar{A_i})}{|A_i|} =21(cut(Ai,Aiˉ)∣Ai∣1+cut(Aiˉ,Ai)∣Ai∣1)=∣Ai∣cut(Ai,Aiˉ)
可以看出,对于某一个子图i,它的RatioCut对应于 h i T L h i h_i^TLh_i hiTLhi,那么我们的k个子图呢?对应的RatioCut的表达式是:
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_{i=1}^kh_i^TLh_i=\sum_{i=1}^k(H^TLH)_{ii}=tr(H^TLH) RatioCut(A1,A2,...,Ak)=i=1∑khiTLhi=i=1∑k(HTLH)ii=tr(HTLH)
其中, t r ( H T L H ) tr(H^TLH) tr(HTLH)为矩阵的迹,也就是说,我们的RatioCut切图,实际上就是最小化我们的 t r ( H T L H ) tr(H^TLH) tr(HTLH),则我们的切图目标为:
a r g m i n ( t r ( H T L H ) ) s . t . H T H = I argmin(tr(H^TLH)) s.t. H^TH=I argmin(tr(HTLH))s.t.HTH=I
注意到:H矩阵里的每一个指示向量都是n维的,向量种每个变量的取值有两种,就有 2 n 2^n 2n种取值,有k个子图的话就有k个指示向量,共有 k 2 n k2^n k2n种H,因此找到满足上面最优化的目标是一个NP难的问题,那么是不是就没有办法了呢?
注意观察 t r ( H T L H ) tr(H^TLH) tr(HTLH)中每一个优化子目标 h i T L h i h^T_iLh_i hiTLhi,其中 h i h_i hi是单位正交基, L为对称矩阵,此时 h i T L h i h^T_iLh_i hiTLhi的最大值为L的最大特征值,最小值是L的最小特征值。如果你对主成分分析PCA很熟悉的话,这里很好理解。在PCA中,我们的目标是找到协方差矩阵(对应此处的拉普拉斯矩阵L)的最大的特征值,而在我们的谱聚类中,我们的目标是找到目标的最小的特征值,得到对应的特征向量,此时对应二分切图效果最佳。也就是说,我们这里要用到维度规约的思想来近似去解决这个NP难的问题。
对于 h i T L h i h^T_iLh_i hiTLhi,我们的目标是找到最小的L的特征值,而对于 t r ( H T L H ) = ∑ i = 1 k h i T L h i tr(H^TLH)=\sum_{i=1}^kh^T_iLh_i tr(HTLH)=∑i=1khiTLhi,则我们的目标就是找到k个最小的特征值,一般来说,k远远小于n,也就是说,此时我们进行了维度规约,将维度从n降到了k,从而近似可以解决这个NP难的问题。
通过找到L的最小的k个特征值,可以得到对应的k个特征向量,这k个特征向量组成一个nxk维度的矩阵,即为我们的H。一般需要对H矩阵按行做标准化,即
h i j ∗ = h i j ( ∑ t = 1 k h i t 2 ) 1 / 2 h^*_{ij}=\frac{h_{ij}}{(\sum_{t=1}^kh^2_{it})^{1/2}} hij∗=(∑t=1khit2)1/2hij
由于我们在使用维度规约的时候损失了少量信息,导致得到的优化后的指示向量h对应的H现在不能完全指示各样本的归属,因此一般在得到nxk维度的矩阵H后还需要对每一行进行一次传统的聚类,比如使用K-Means聚类。
对每个切图,不光考虑最小化 c u t ( A 1 , A 2 , . . . , A k ) cut(A_1,A_2,...,A_k) cut(A1,A2,...,Ak),它还同时考虑最大化每个子图点的个数,即:
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_{i=1}^{k}\frac{W(A_i,\bar{A_i})}{vol(A_i)} Ncut(A1,A2,...,Ak)=21i=1∑kvol(Ai)W(Ai,Aiˉ)
v o l ( A ) = ∑ i ∈ A d i vol(A)=\sum_{i\in A}d_i vol(A)=i∈A∑di
**具体方法:**引入指示向量 h j ∈ ( h 1 , h 2 , . . . , h k ) , j = 1 , 2 , . . . k h_j\in (h_1,h_2,...,h_k),j=1,2,...k hj∈(h1,h2,...,hk),j=1,2,...k,对于任意一个向量 h j h_j hj,它是一个n维向量(n为样本数),我们定义 h i j h_{ij} hij为:
h i j = { 0 v i ∉ A j 1 v o l ( A j ) v i ∈ A j h_{ij}=\begin{cases}0 & v_i \notin A_j\\\frac{1}{\sqrt{vol(A_j)} }& v_i \in A_j\end{cases} hij={0vol(Aj)1vi∈/Ajvi∈Aj
那么我们对于 h i T L h i h_i^TLh_i hiTLhi有:
h i T L h i = 1 2 ∑ m = 1 ∑ n = 1 w m n ( h i m − h i n ) 2 h_i^TLh_i=\frac{1}{2}\sum_{m=1}\sum_{n=1}w_{mn}(h_{im}-h_{in})^2 hiTLhi=21m=1∑n=1∑wmn(him−hin)2
= 1 2 ∑ m ∈ A i ∑ n ∉ A i w m n ( 1 v o l ( A i ) − 0 ) 2 = 1 2 ∑ m ∉ A j ∑ n ∈ A j w m n ( 0 − 1 v o l ( A j ) ) 2 =\frac{1}{2}\sum_{m\in A_i}\sum_{n\notin A_i}w_{mn}(\frac{1}{\sqrt{vol(A_i)} }-0)^2=\frac{1}{2}\sum_{m\notin A_j}\sum_{n\in A_j}w_{mn}(0-\frac{1}{\sqrt{vol(A_j)} })^2 =21m∈Ai∑n∈/Ai∑wmn(vol(Ai)1−0)2=21m∈/Aj∑n∈Aj∑wmn(0−vol(Aj)1)2
= 1 2 ∑ m ∈ A i ∑ n ∉ A i w m n 1 v o l ( A i ) + 1 2 ∑ m ∉ A j ∑ n ∈ A j w m n 1 v o l ( A j ) =\frac{1}{2}\sum_{m\in A_i}\sum_{n\notin A_i}w_{mn}\frac{1}{vol(A_i) }+\frac{1}{2}\sum_{m\notin A_j}\sum_{n\in A_j}w_{mn}\frac{1}{vol(A_j) } =21m∈Ai∑n∈/Ai∑wmnvol(Ai)1+21m∈/Aj∑n∈Aj∑wmnvol(Aj)1
= 1 2 ( c u t ( A i , A i ˉ ) 1 v o l ( A i ) + c u t ( A i ˉ , A i ) 1 v o l ( A i ) ) = c u t ( A i , A i ˉ ) v o l ( A i ) =\frac{1}{2}(cut(A_i,\bar{A_i})\frac{1}{vol(A_i)}+cut(\bar{A_i},A_i)\frac{1}{vol(A_i)})=\frac{cut(A_i,\bar{A_i})}{vol(A_i)} =21(cut(Ai,Aiˉ)vol(Ai)1+cut(Aiˉ,Ai)vol(Ai)1)=vol(Ai)cut(Ai,Aiˉ)
可以看出,对于某一个子图i,它的Ncut对应于 h i T L h i h_i^TLh_i hiTLhi,那么我们的k个子图呢?对应的Ncut的表达式是:
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_{i=1}^kh_i^TLh_i=\sum_{i=1}^k(H^TLH)_{ii}=tr(H^TLH) Ncut(A1,A2,...,Ak)=i=1∑khiTLhi=i=1∑k(HTLH)ii=tr(HTLH)
但是此时我们的 H T H 不 等 于 I H^TH不等于I HTH不等于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^TDh_i=\sum_{j=1}^nh_{ij}^2d_j=\frac{1}{vol(A_i)}\sum_{j\in A_i}d_j=\frac{1}{vol(A_i)}vol(A_i)=1 hiTDhi=j=1∑nhij2dj=vol(Ai)1j∈Ai∑dj=vol(Ai)1vol(Ai)=1
其中, t r ( H T L H ) tr(H^TLH) tr(HTLH)为矩阵的迹,也就是说,我们的Ncut切图,实际上就是最小化我们的 t r ( H T L H ) tr(H^TLH) tr(HTLH),则我们的切图目标为:
a r g m i n ( t r ( H T L H ) ) s . t . H T D H = I argmin(tr(H^TLH)) s.t. H^TDH=I argmin(tr(HTLH))s.t.HTDH=I
我们令 H = D − 1 / 2 F H=D^{-1/2}F H=D−1/2F,可以得到 F T F = I F^TF=I FTF=I,也就是优化目标变成了:
a r g m i n ( t r ( F T D − 1 / 2 F L D − 1 / 2 F ) ) s . t . F T F = I argmin(tr(F^TD^{-1/2}FLD^{-1/2}F)) s.t. F^TF=I argmin(tr(FTD−1/2FLD−1/2F))s.t.FTF=I
可以发现这个式子和RatioCut基本一致,只是中间的L变成了 D − 1 / 2 L D − 1 / 2 D^{-1/2}LD^{-1/2} D−1/2LD−1/2。这样我们就可以继续按照RatioCut的思想,求出 D − 1 / 2 L D − 1 / 2 D^{-1/2}LD^{-1/2} D−1/2LD−1/2的最小的前k个特征值,然后求出对应的特征向量,并标准化,得到最后的特征矩阵F,最后对F进行一次传统的聚类(比如K-Means)即可。
一般来说, D − 1 / 2 L D − 1 / 2 D^{-1/2}LD^{-1/2} D−1/2LD−1/2相当于对拉普拉斯矩阵LL做了一次标准化,即:
L i j d i ∗ d j \frac{L_{ij}}{\sqrt{d_i*d_j}} di∗djLij
铺垫了这么久,终于可以总结下谱聚类的基本流程了。一般来说,谱聚类主要的注意点是邻接矩阵的生成方式、切图的方式、以及最后的聚类方法。
最常用的邻接矩阵是基于高斯核距离的全连接方式,最常用的切图方式是Ncut,最常用的聚类方法是Kmeans方法。下面以Ncut总结谱聚类算法流程。
**输入:**样本集 D = ( x 1 , x 2 , . . . , x n ) D=(x_1,x_2,...,x_n) D=(x1,x2,...,xn),相似矩阵的生成方式,降维后的维度k1,聚类方法,聚类后的维度k2。
**输出:**簇划分 C ( c 1 , c 2 , . . . , c k 2 ) C(c_1,c_2,...,c_{k2}) C(c1,c2,...,ck2)。
谱聚类算法是一个使用起来简答,但是讲清楚却不是那么容易的算法,它需要你有一定的数学基础。如果你掌握了谱聚类,相信你会对矩阵分析、图论有更深入的理解,同时对降维里的主成分分析也会加深理解。
下面总结谱聚类算法的优缺点:
优点
缺点