谱聚类

1. 基本原理

它的主要思想:把所有数据看成空间中的点,这些点之间可以用变连接起来,距离较远的两个点之间的边权重较低,而距离较近的两个点之间的权重较高,通过对所有数据点组成的图进行切图,让切图后的不同的子图间边权重和尽可能小(即距离远),而子图内的边权重和尽可能高(即距离近)。

难点:

  1. 如何构建图?
  2. 如何切分图?

2. 谱聚类基础

2.1 无向权重图

对于一个图GGG,我们一般用点集合V={v1,v2,....,vn}V=\{v_1,v_2,....,v_n\}V={v1,v2,....,vn}和边集合EEE来描述,即G=(V,E)G=(V,E)G=(V,E)。我们定义权重wijw_{ij}wij为点vi,vjv_i,v_jvi,vj之间的权重,由于是无向图,故wij=wjiw_{ij}=w_{ji}wij=wji

对于有边连接的两个点vi和vjv_i和v_jvivjwij>0w_{ij} > 0wij>0;对于没有边连接的两个点vi和vjv_i和v_jvivjwij=0w_{ij} = 0wij=0

对于图中的任意一个点viv_ivi,它的度did_idi定义为和它相连的所有边权重之和,即
di=∑j=1nwijd_i=\sum_{j=1}^nw_{ij}di=j=1nwij

利用每个点度的定义,我们可以得到一个n×nn \times nn×n的度矩阵DDD,它是一个对角阵,只有主对角有值,对应第iii行为第iii个点的度;利用所有点之间的权重,我们可以得到图的邻接矩阵WWW,它也是一个n×nn \times nn×n矩阵,第iii行的第jjj个值对应权重wijw_{ij}wij

除此之外,对于点集VVV的一个子集A⊂VA \subset VAV,我们定义:
∣A∣:=子集A中点的个数vol(A):=∑i∈Adi|A|:=子集A中点的个数 \\ vol(A):=\sum_{i \in A}d_iA:=Avol(A):=iAdi

2.2 拉普拉斯矩阵

拉普拉斯矩阵L=D−WL=D-WL=DW,其性质如下:

  1. 对称矩阵,由于D和WD和WDW都为对称矩阵
  2. 由于是对称矩阵,它的所有特征值都是实数
  3. 对于任意向量fff,有
    fTLf=fTDf−fTWf=∑i=1ndifi2−∑i,j=1nwijfifj=12(∑i=1ndifi2−2∑i,j=1nwijfifj+∑j=1ndjfj2)=12∑i,j=1nwij(fi−fj)2f^TLf=f^TDf-f^TWf=\sum_{i=1}^nd_if_i^2-\sum_{i,j=1}^nw_{ij}f_if_j\\=\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)^2fTLf=fTDffTWf=i=1ndifi2i,j=1nwijfifj=21(i=1ndifi22i,j=1nwijfifj+j=1ndjfj2)=21i,j=1nwij(fifj)2
  4. 由于拉普拉斯矩阵是半正定的,其对应的nnn个特征值都大于等于0。

3. 构建图——构建邻接矩阵

3.1 ϵ\epsilonϵ邻近法

通过设置一个阈值ϵ\epsilonϵ,然后利用欧氏距离sijs_{ij}sij度量任意两点vi和vjv_i和v_jvivj的距离,即sij=∣∣vi−vj∣∣22s_{ij}=||v_i-v_j||_2^2sij=vivj22,然后根据sij和ϵs_{ij}和\epsilonsijϵ的大小关系,来定义邻接矩阵WWW
wij={0,sij>ϵϵ,sij≤ϵ w_{ij}= \begin{cases} 0, \quad & s_{ij} >\epsilon \\ \epsilon, \quad & s_{ij} \leq \epsilon \end{cases} wij={0,ϵ,sij>ϵsijϵ

从上式可知,两点间的权重要么ϵ\epsilonϵ,要么0,就没有其他信息了,距离远近度量很不明确,因此在实际应用中,很少采用。

3.2 kkk近邻法

利用KNN算法遍历所有的样本点,取每个样本最近的kkk个点作为近邻,只有和样本距离最近的kkk个点之间的wij>0w_{ij}>0wij>0。但是这种方法会造成重构之后的邻接矩阵WWW非对称,我们后面的算法需要邻接矩阵对称。为了解决这种问题,一般采取下面两种方法之一:

  1. 只要一个点在另一个点的K近邻中,就保留wijw_{ij}wij
    wij=wji={0vi∉KNN(vj)andvj∉KNN(vi)exp(−∣∣vi−xj∣∣222σ2)vi∈KNN(vj)orvj∈KNN(vi) w_{ij}=w_{ji}= \begin{cases} 0 & v_i \notin KNN(v_j) \quad and \quad v_j \notin KNN(v_i) \\ exp(-\frac {||v_i-x_j||_2^2} {2\sigma^2}) & v_i \in KNN(v_j) \quad or \quad v_j \in KNN(v_i) \end{cases} wij=wji={0exp(2σ2vixj22)vi/KNN(vj)andvj/KNN(vi)viKNN(vj)orvjKNN(vi)
  2. 必须两个点互为KKK近邻中,才能保留wijw_{ij}wij
    wij=wji={0vi∉KNN(vj)orvj∉KNN(vi)exp(−∣∣vi−xj∣∣222σ2)vi∈KNN(vj)andvj∈KNN(vi) w_{ij}=w_{ji}= \begin{cases} 0 & v_i \notin KNN(v_j) \quad or \quad v_j \notin KNN(v_i) \\ exp(-\frac {||v_i-x_j||_2^2} {2\sigma^2}) & v_i \in KNN(v_j) \quad and \quad v_j \in KNN(v_i) \end{cases} wij=wji={0exp(2σ2vixj22)vi/KNN(vj)orvj/KNN(vi)viKNN(vj)andvjKNN(vi)

3.3 全连接法

比前两种方法,第三种方法所有的点之间的权重值都大于0,因此称之为全连接法。可以选择不同的核函数来定义边权重,常用的有多项式核函数,高斯核函数和Sigmoid核函数。最常用的是高斯核函数RBF
wij=exp(−∣∣vi−vj∣∣222σ2)w_{ij}=exp(-\frac {||v_i-v_j||_2^2} {2\sigma^2})wij=exp(2σ2vivj22)

在实际的应用中,使用第三种全连接法来建立邻接矩阵是最普遍的,而在全连接法中使用高斯径向核RBF是最普遍的。

4. 图的切分

对于无向图GGG的切分,我们的目标是将图G(V,E)G(V,E)G(V,E)切成相互没有连接的kkk个子图,每个子图集合为:A1,A2,...,AkA_1,A_2,...,A_kA1,A2,...,Ak,它们满足Ai∩Aj=∅且A1∪A2∪...∪Ak=VA_i \cap A_j=\varnothing 且 A_1 \cup A_2 \cup ...\cup A_k=VAiAj=A1A2...Ak=V

对于任意两个子图点的集合A,B⊂V,A∩B=∅A,B \subset V, A \cap B=\varnothingA,BV,AB=,我们定义A和BA和BAB之间的切图权重为:
W(A,B)=∑i∈A,j∈BwijW(A,B)=\sum_{i\in A,j\in B}w_{ij}W(A,B)=iA,jBwij
那么对于我们kkk个子图点的集合:A1,A2,...,AkA_1,A_2,...,A_kA1,A2,...,Ak,我们定义切图cutcutcut为:
cut(A1,A2,...,Ak)=12∑i=1kW(Ai,Aˉi)cut(A_1,A_2,...,A_k)=\frac {1} {2}\sum_{i=1}^kW(A_i, \bar A_i)cut(A1,A2,...,Ak)=21i=1kW(Ai,Aˉi)
其中Aˉi\bar A_iAˉiAiA_iAi的补集

那么如何切图可以让子图内的点权重和高,子图间的点权重和低呢?

一个自然的想法就是最小化cut(A1,A2,...Ak)cut(A_1,A_2,...A_k)cut(A1,A2,...Ak), 但是可以发现,这种极小化的切图存在问题,如下图:
在这里插入图片描述

为了避免最小切图导致的切图效果不佳,我们需要对每个子图的规模做出限定,一般来说,有两种切图方式,第一种是RatioCutRatioCutRatioCut,第二种是NcutNcutNcut

4.1 RatioCutRatioCutRatioCut切图

对于每个切图,不仅要考虑最小化cut(A1,A2,...,Ak)cut(A_1,A_2,...,A_k)cut(A1,A2,...,Ak),还要考虑最大化每个子图样本的个数,即最小化RatioCutRatioCutRatioCut函数:
RatioCut(A1,A2,...,Ak)=12∑i=1kW(Ai,Aˉi)∣Ai∣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=1kAiW(Ai,Aˉi)

我们引入指示向量hj∈{h1,h2,...,hk}h_j\in \{h_1,h_2,...,h_k\}hj{h1,h2,...,hk},对于任意一个向量hj=(h1,j,h2,j,...,hn,j)Th_j=(h_{1,j},h_{2,j},...,h_{n,j})^Thj=(h1,j,h2,j,...,hn,j)T,它是一个nnn维向量(nnn为样本数),我们定义hijh_{ij}hij为:
hij={0vi∉Aj1∣Aj∣vi∈Aj h_{ij}= \begin{cases} 0 & v_i \notin A_j \\ \frac {1} {|A_j|} & v_i \in A_j \end{cases} hij={0Aj1vi/AjviAj
对于hiTLhih_i^TLh_ihiTLhi有:
hiTLhi=12∑m=1∑n=1wmn(hm,i−hn,i)2=12(∑m∈Ai,n∉Aiwmn(1∣Ai∣−0)2+∑m∉Ai,n∈Aiwmn(0−1∣Ai∣)2)=12(∑m∈Ai,n∉Aiwmn1∣Ai∣+∑m∉Ai,n∈Aiwmn1∣Ai∣)=12(cut(Ai,Aˉi)1∣Ai∣+cut(Ai,Aˉi)1∣Ai∣)=cut(Ai,Aˉi)∣Ai∣h_i^TLh_i=\frac {1} {2}\sum_{m=1}\sum_{n=1}w_{mn}(h_{m,i}-h_{n,i})^2 \\ =\frac {1}{2}(\sum_{m \in A_i, n \notin A_i}w_{mn}(\frac {1}{\sqrt {|A_i|}}-0)^2+\sum_{m \notin A_i, n \in A_i}w_{mn}(0-\frac {1} {\sqrt {|A_i|}})^2)\\=\frac {1}{2}(\sum_{m \in A_i,n \notin A_i}w_{mn}\frac {1}{|A_i|}+\sum_{m \notin A_i,n \in A_i}w_{mn}\frac {1}{|A_i|})\\=\frac {1}{2}(cut(A_i,\bar A_i)\frac{1}{|A_i|}+cut(A_i,\bar A_i)\frac{1}{|A_i|})=\frac {cut(A_i,\bar A_i)} {|A_i|}hiTLhi=21m=1n=1wmn(hm,ihn,i)2=21(mAi,n/Aiwmn(Ai 10)2+m/Ai,nAiwmn(0Ai 1)2)=21(mAi,n/AiwmnAi1+m/Ai,nAiwmnAi1)=21(cut(Ai,Aˉi)Ai1+cut(Ai,Aˉi)Ai1)=Aicut(Ai,Aˉi)

由上式可知,RatioCutRatioCutRatioCut函数表达式可改写为:
RatioCut(A1,A2,...,Ak)=∑i=1khiTLhi=∑i=1k(HTLH)ii=tr(HTLH)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=1khiTLhi=i=1k(HTLH)ii=tr(HTLH)
其中tr(HTLH)tr(H^TLH)tr(HTLH)为矩阵的迹,即我们的RatioCutRatioCutRatioCut切图,实际上是最小化迹tr(HTLH)tr(H^TLH)tr(HTLH)。注意到HTH=IH^TH=IHTH=I,则我们的优化目标为:
argmin⁡Htr(HTLH)s.t.HTH=Iarg\min_{H}tr(H^TLH)\\s.t. \quad H^TH=IargHmintr(HTLH)s.t.HTH=I

注意观察tr(HTLH)tr(H^TLH)tr(HTLH)的每一个优化子目标hiTLhih_i^TLh_ihiTLhi,其中hih_ihi是单位正交基,LLL是对称矩阵,此时hiTLhih_i^TLh_ihiTLhi是矩阵LLL的一个特征值。对于hiTLhih_i^TLh_ihiTLhi,我们的目标是找到矩阵LLL的最小特征值,而对于tr(HTLH)=∑i=1khiTLhitr(H^TLH)=\sum_{i=1}^kh_i^TLh_itr(HTLH)=i=1khiTLhi,我们的目标就是找到矩阵LLLkkk个最小特征值。

4.2 NcutNcutNcut切图

NcutNcutNcut切图与RatioRatioRatio切图类似,只是将RatioCutRatioCutRatioCut的分母∣Ai∣|A_i|Ai换成vol(Ai)vol(A_i)vol(Ai)。由于子图样本的个数多不一定权重就大,我们切图时基于权重也更符合我们的目标,因此一般来说NcutNcutNcut优于RatioCutRatioCutRatioCut,定义如下:
Ncut(A1,A2,...,Ak)=12∑i=1kW(Ai,Aˉi)vol(Ai)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=1kvol(Ai)W(Ai,Aˉi)

对应的,NcutNcutNcut切图对指示向量hhh做了改进,定义如下:
hij={0vi∉Aj1vol(Aj)vi∈Aj 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/AjviAj

我们的优化目标依然是:(推导与RatioCutRatioCutRatioCut完全一致)
Ncut(A1,A2,...,Ak)=∑i=1khiTLhi=∑i=1k(HTLH)ii=tr(HTLH)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=1khiTLhi=i=1k(HTLH)ii=tr(HTLH)
但是此时我们的HTH≠IH^TH \not=IHTH=I,而是HTDH=IH^TDH=IHTDH=I。推导如下:
hiTDhi=∑j=1nhji2dj=∑j∈Ai1vol(Ai)dj=1vol(Ai)∑j∈Aidj=1vol(Ai)vol(Ai)=1h_i^TDh_i=\sum_{j=1}^nh_{ji}^2d_j=\sum_{j \in A_i}\frac {1} {vol(A_i)}d_j=\frac {1} {vol(A_i)}\sum_{j \in A_i}d_j=\frac {1} {vol(A_i)}vol(A_i)=1hiTDhi=j=1nhji2dj=jAivol(Ai)1dj=vol(Ai)1jAidj=vol(Ai)1vol(Ai)=1
也就是说,我们的优化目标最终为:
argmin⁡Htr(HTLH)s.t.HTDH=Iarg\min_{H}tr(H^TLH) \\ s.t. \quad H^TDH=IargHmintr(HTLH)s.t.HTDH=I
此时我们的HHH中的指示向量hhh不是单位正交基,所以我们令H=D−12FH=D^{-\frac {1} {2}}FH=D21F,则HTLH=FTD−12LD−12F,HTDH=FTF=IH^TLH=F^TD^{-\frac {1}{2}}LD^{-\frac {1}{2}}F,H^TDH=F^TF=IHTLH=FTD21LD21F,HTDH=FTF=I,也就是优化目标变成了:
argmin⁡Ftr(FTD−12LD−12F)s.t.FTF=Iarg\min_{F}tr(F^TD^{-\frac {1}{2}}LD^{-\frac {1}{2}}F) \\ s.t. \quad F^TF=IargFmintr(FTD21LD21F)s.t.FTF=I
可以发现这个式子和RatioCutRatioCutRatioCut基本一致,只是中间的LLL变成了D−12LD−12D^{-\frac {1}{2}}LD^{-\frac {1}{2}}D21LD21。这样,我们可以按照RatioCutRatioCutRatioCut的思想,求出D−12LD−12D^{-\frac {1}{2}}LD^{-\frac {1}{2}}D21LD21kkk个最小特征值

一般来说,D−12LD−12D^{-\frac {1}{2}}LD^{-\frac {1}{2}}D21LD21相当于对拉普拉斯矩阵LLL做了一次标准化,即Lijdi⋅dj\frac {L_{ij}}{\sqrt {d_i \cdot d_j}}didj Lij

5. 谱聚类算法流程

输入:样本集D=(x1,x2,...,xn),邻接矩阵的生成方式,降维后的维度k1,聚类方法,聚类后的维度k2输入:样本集D=(x_1,x_2,...,x_n),邻接矩阵的生成方式, 降维后的维度k_1, 聚类方法,聚类后的维度k_2D=(x1,x2,...,xn),k1,k2

输出:簇划分C(c1,c2,...ck2)输出: 簇划分C(c_1,c_2,...c_{k_2})C(c1,c2,...ck2)

  1. 根据邻接矩阵生成方式构建邻接矩阵WWW,构建度矩阵DDD
  2. 计算出拉普拉斯矩阵LLL
  3. 构建标准化后的拉普拉斯矩阵D−12LD−12D^{-\frac {1}{2}}LD^{-\frac {1}{2}}D21LD21
  4. 计算D−12LD−12D^{-\frac {1}{2}}LD^{-\frac {1}{2}}D21LD21最小的k1k_1k1个特征值所各自对应的特征向量fff
  5. 将各自对应的特征向量fff组成的矩阵按行标准化,最终组成n×k1n \times k_1n×k1维矩阵FFF
  6. FFF中的每一行作为一个k1k_1k1维样本,共nnn个样本,用输入的聚类方法进行聚类,聚类维数为k2k_2k2
  7. 得到簇划分C(c1,c2,...ck2)C(c_1,c_2,...c_{k_2})C(c1,c2,...ck2)

6. 实例演示

import numpy as np 
import matplotlib.pyplot as plt 

from sklearn import cluster, datasets
from sklearn.preprocessing import StandardScaler

np.random.seed(0)

# 构建数据
n_samples = 1500
noisy_circles = datasets.make_circles(n_samples=n_samples, factor=0.5, noise=0.05)
noisy_moons = datasets.make_moons(n_samples=n_samples, noise=0.05)
blobs = datasets.make_blobs(n_samples=n_samples, random_state=8)

data_sets = [
    (
        noisy_circles,
        {
            "n_clusters": 2
        }
    ),
    (
        noisy_moons,
        {
            "n_clusters": 2
        }
    ), 
    (
        blobs, 
        {
            "n_clusters": 3
        }
    )
]
colors = ["#377eb8", "#ff7f00", "#4daf4a"]
affinity_list = ['rbf', 'nearest_neighbors']

plt.figure(figsize=(17, 10))

for i_dataset, (dataset, algo_params) in enumerate(data_sets):
    # 模型参数
    params = algo_params

    # 数据
    X, y = dataset
    X = StandardScaler().fit_transform(X)

    for i_affinity, affinity_strategy in enumerate(affinity_list):
        # 创建SpectralCluster
        spectral = cluster.SpectralClustering(
            n_clusters=params['n_clusters'],
            eigen_solver='arpack', 
            affinity=affinity_strategy
        )

        # 训练
        spectral.fit(X)

        # 预测
        y_pred = spectral.labels_.astype(int)

        y_pred_colors = []

        for i in y_pred:
            y_pred_colors.append(colors[i])
        
        plt.subplot(3, 4, 4*i_dataset+i_affinity+1)
        plt.title(affinity_strategy)
        plt.scatter(X[:, 0], X[:, 1], color=y_pred_colors)

plt.show()

在这里插入图片描述

7. 谱聚类算法小结

优点:

  1. 谱聚类只需要数据之间的邻接矩阵,因此对于处理稀疏数据的聚类很有效。这点传统聚类算法比如K-Means很难做到
  2. 由于使用了降维,因此在处理高维数据聚类时的复杂度比传统聚类算法好

缺点:

  1. 如果最终聚类的维度非常高,则由于降维的幅度不够,谱聚类的运行速度和最后的聚类效果均不好
  2. 聚类效果依赖于邻接矩阵,不同的邻接矩阵得到的最终聚类效果可能很不同
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐