谱聚类算法详解

article/2025/10/9 0:06:34

  谱聚类(Spectral Clustering)算法简单易行,其聚类性能优于传统的K-means算法。谱聚类将数据的划分转化为对图的分割,是一种基于图论的聚类方法,其直观理解为根据图内点的相似度将图分为多个子图,使子图内部的点相似度最高,子图之间点的相似度最低。

1. 图论基础

1.1 图的表示

  记 G=(V,E) 表示一个无向加权图, V 表示所有顶点的集合V={v1,...,vn} E 表示所有边的集合,并且任意两点vi vj 的边具有非负权值 wij0 。图的邻接矩阵为 W=(wij)i,j=1,...,n ,如果 wij=0 则表示点 vi vj 之间没有连接。由于 G 为无向图,所以其邻接矩阵具有对称性,即wij=wij。图中任一点 vi 的度为 di=nj=1wij ,表示一个点与其他所有点的连接情况,图的度矩阵 D 为每个点的度所构成的对角矩阵D=diag{d1,...,dn}

1.2 相似度图的构造方法

  给定一组数据集 V={v1,...,vn} ,将其构造为相似度图的意义在于描述点对之间的局部近邻关系。此处介绍三种构造相似度图的方法。
  (1)ε近邻图。如果两点之间的距离小于给定值ε,则连接两点。ε的值需要根据图中各点的距离选择,使与某一点连接的点不会太多,也不会太少。
  (2) k 近邻图。如果点vj vi k 近邻点之一,则连接两点。由于近邻点的非相互性,按此方法构造的邻接矩阵不对称,一种方法是采取“或”的方式,即如果vj vi k 近邻点之一,或vi vj k 近邻点之一,则连接两点;另一种方法是采取“与”的方式,如果vj vi 的k近邻点之一,并且 vi vj 的k近邻点之一,则连接两点。
  (3)全连接图。不考虑任何因素,直接将所有的点两两相连,由于图表示点之间的局部邻接特性,常用的相似性函数为 s(xi,xj)=exp(xixj22σ2)

1.3 图的Laplacian矩阵

  这里我们要讲到谱聚类中的关键内容——拉普拉斯矩阵,其定义为 L=DW ,其中 D W就是上文定义的图的度矩阵和邻接矩阵。下面我们给出谱聚类中用到的拉普拉斯矩阵的一些性质。
  (1)对任意的向量 fRn ,有 fTLf=12i,j=1nwij(fifj)2
  证明:(此处用到了W的对称性)

fTLf=fTDffTWf=i=1nf2idii,j=1nwijfifj=i,j=1nwijf2ii,j=1nwijfifj=12i,j=1nwijf2i+i,j=1nwijf2ji,j=1nwijfifj=12i,j=1nwij(fifj)2

(2) L 是对称半正定矩阵,该性质可由(1)直接得到。
(3)L的最小特征值为 0 ,对应的特征向量为常数向量1,即 L 的行和或列和为0
(4)本文假设 L 的特征值按照从小到大的顺序排列,0=λ1...λn
  此外,还有normalized Laplacian,分别定义为
Lsym=D12LD12=ID12WD12 ,和 Lrm=D1L=ID1W ,其中两个下标sym和rw分别代表symmetric和random walk,此处不再介绍这两个矩阵的性质。

2. 谱聚类算法

2.1 图的分割问题

  谱聚类算法源于图的分割(cut),首先将所有的样本点连接成图,然后将图分割成不同的子图,使得不同子图之间的连接权值最小。
  定义两个子图之间的连接权值为 W(A,B)=iA,jBwij ,记 A¯¯¯ A 的补集,为了表达方便,我们记viA iA 。如果将图分割为 k 个子图A1,...,Ak,那么最优分割问题可通过最小化如下表达式来实现:

cut(A1,...,Ak)=12i=1kW(Ai,Ai¯¯¯¯)
   然而,此优化问题通常不能生成有效的分割,它会将图中的一个点与其余 n1 个点分割开来,如下图所示,导致图的分割不均衡。

图1

解决该问题的有效办法是让每个子图都有合理的大小,子图大小的度量方式不同就会得出不同的最小分割问题,常用的两种方法是RaioCut和Normalized Cut,分别如下:
RatioCut(A1,...,Ak)=12i=1kW(Ai,Ai¯¯¯¯)|Ai|=i=1kcut(Ai,Ai¯¯¯¯)|Ai|
Ncut(A1,...,Ak)=12i=1kW(Ai,Ai¯¯¯¯)vol(Ai)=i=1kcut(Ai,Ai¯¯¯¯)vol(Ai)
这两个目标函数均将子图的大小作为分母,这样就可以使每个子图不会太小,其中RatioCut以子图中点的个数 |Ai| 作为子图大小的度量,Normalized Cut以子图内所有点的度的和作为子图大小的衡量,即 vol(Ai)=jAidj
  下面我们分别讨论RatioCut和Normalized Cut是如何通过谱聚类来求解的。

2.2 求解RatioCut

  首先从二聚类问题开始分析,其目标函数为最小化

RatioCut(A,A¯¯¯)=cut(A,A¯¯¯)(1|A|+1|A¯¯¯|)

定义向量 f=(f1,...,fn)TRn ,其每个元素的定义如下:
fi=|A¯¯¯|/|A||A|/|A¯¯¯|ifviAifviA¯¯¯

结合图的Laplacian矩阵,我们可以得到RatioCut问题,推导过程如下:

fTLf=12i,j=1nwij(fifj)2=12iA,jA¯wijA¯|A|+|A|A¯2+12iA¯,jAwijA¯|A||A|A¯2=12iA,jA¯wijA¯|A|+|A|A¯+2+12iA¯,jAwijA¯|A|+|A|A¯+2=12iA,jA¯wij+iA¯,jAwijA¯|A|+|A|A¯+2=cut(A,A¯)A¯+|A||A|+|A|+A¯A¯=|V|cut(A,A¯)1|A|+1A¯=|V|RatioCut(A,A¯)
其中, |V| 表示所有点的个数,给定样本点后, |V| 是个常数。
  因为,求解RatioCut问题可以转变为最小化 fTLf 的问题,其中 f 的取值如上面所定义,然而,该离散优化问题是NP-hard,因此,我们将其进行松弛,使fi能够取任意实数。同时,为了和原问题尽量保持一致,我们加入 f 的两个约束,f1 f=n ,这两个约束可从 f 的定义得到。最后,二聚类问题就转化成了有约束的优化问题:

minfRnfTLfs.t.f1,f=n
根据Rayleigh-Ritz定理可知,该问题的解为Laplacian矩阵 L 的最小特征值所对应的特征向量,由于L的最小特征值为 0 ,对应的特征向量为常数向量1,不满足约束条件,因此,应取第 2 小的特征值所对应的特征向量。
求解上述优化问题后,要将数据集分为2个簇,我们可简单地采取如下的方式:

{viAvi(¯A)iffi0iffi<0
  上述的二聚类问题可以很容易地推广到 k 聚类问题,如果将一个数据集分为k个子集 Ai,...,Ak ,首先定义 k 个示性向量H=(h1,...,hk)T,其中

hij={1/|Aj|0ifviAjotherwise,i=1,...,n;j=1,...,k

由该定义可知, H 的列相互正交,即HTH=I。类似上面的推导(此处不再给出详细过程):

hTjLhj=cut(Aj,Aj¯¯¯¯)|Aj|

此外, hTjLhj=(HTLH)jj ,因此

RatioCut(A1,...,Ak)=j=1khTjLhj=j=1k(HTLH)jj=Tr(HTLH)

所以,多聚类的RatioCut问题可以转化为最小化 Tr(HTLH) 的问题, H 的取值如上面所定义。同样,我们将该NP-hard问题松弛,使H的元素取任意实数,松弛问题就变为:

minHRn×kTr(HTLH),s.t.HTH=I

这是标准的迹最小化问题,其解为 L 的的前k个特征向量所构成的矩阵。最后采用k-means方法对该矩阵的行进行聚类,就可以实现对该数据集的 k 聚类。

2.3 求解Normalized Cut

  类似于RatioCut,下面我们简要给出Normalized Cut的实现过程。
首先分析二聚类的情况,定义示性函数如下:

fi=vol(A¯¯¯)/vol(A)vol(A)/vol(A¯¯¯)ifviAifviA¯¯¯
按照该定义, f 具有性质(Df)T1=0 fTDf=vol(V) ,并且可以证明 fTLf=vol(V)Ncut(A,A¯¯¯) ,加上松弛条件,使 f 可以取任意实数向量,Normalized Cut可以转化成有约束的优化问题
minfRnfTLf,s.t.Df1,fTDf=vol(V)
  该问题需要求解广义特征向量问题 Lf=λDf f L的第二小的广义特征值对应的特征向量。
  再扩展到 k 聚类问题,定义k个示性向量 H=(h1,...,hk)T ,其中

hij={1/vol(Aj)0ifviAjotherwise,i=1,...,n;j=1,...,k

按照该定义, H 具有性质hTjDhj=1,那么 HTDH=I ,并且可以证明

hTjLhj=cut(Aj,Aj¯¯¯¯)/vol(Aj)

因此, Ncut(A1,...,Ak)=Tr(HTLH) ,加上松弛条件,使 H 的元素可以取任意实数,Normalized Cut就可以转化为如下有约束的优化问题:

minHRn×kTr(HTLH)s.t.HTDH=I
该问题的解为广义特征值问题 Lh=λDh 的前 k 个特征向量所构成的矩阵。最后采用k-means方法对该矩阵的行进行聚类,就可以实现对该数据集的k聚类。

2.4 小结

  针对以上两种图分割方法,谱聚类算法的步骤如下:
  Step1:将每个样本看做图的顶点,构造无向加权图;
  Step2:计算图的邻接矩阵W和拉普拉斯矩阵L;
  Step3:根据图的分割准则计算拉普拉斯矩阵的前k个特征向量;
  Step4:将拉普拉斯矩阵的前k个特征向量构成矩阵Y,把Y的每一行看做一个样本,然后用k-means方法对Y进行聚类。

3. 总结

  谱聚类相当于先进行非线性降维,使原始数据点能够线性可分,最后再使用k-means聚类就可以得到比较好的聚类效果。
  谱聚类算法也存在以下几点不足:
  (1) 谱聚类的松弛条件是对原问题的一个近似,但是并不能保证该近似是合适的,其误差有可能非常大,而且导致聚类问题不稳定;
  (2) 构造相似度矩阵的尺度参数根据经验设定,尺度参数的选择对聚类效果影响较大;
  (3) 同其他聚类方法一样,聚类数目的选择难以确定;
  (4) 根据图最小分割的目标函数可知,谱聚类适用于均衡分类问题,即各簇之间点的个数相差不大,对于簇之间点个数相差悬殊的聚类问题,谱聚类则不适用。
  以下一组图均为采用谱聚类方法进行聚类的结果,左侧一列的数据点个数分布比较均衡,聚类效果比较好,可以看出,右侧一列数据点的分布不均衡,谱聚类算法仍然将数据分成几个均衡的簇,而不能体现数据的分布结构。




http://chatgpt.dhexx.cn/article/5bAZJkHe.shtml

相关文章

谱聚类算法简单理解

一、算法思想 谱聚类是基于图论的知识所演化出的算法&#xff0c;在聚类中广泛使用。主要思想是将所有的数据看成空间中的点&#xff0c;这些点之间可以用边连接起来&#xff0c;距离较远的两点之间边的权重值较低&#xff0c;距离较近的两点间边的权重值较高&#xff0c;然后…

了解聚类是什么。聚类方法:k-means、核聚类、层次聚类、谱聚类

聚类 1.什么是聚类2.聚类方法2.1 划分式聚类方法k-meansk-meansbi-kmeans 基于密度的方法DBSCANOPTICS算法 层次化聚类算法核聚类支持向量聚类谱聚类引言优缺点步骤 参考文档:参考 1.什么是聚类 定义 聚类(Clustering) 是按照某个特定标准(如距离)把一个数据集分割成不同的类…

【聚类】谱聚类解读、代码示例

【聚类】谱聚类详解、代码示例 文章目录 【聚类】谱聚类详解、代码示例1. 介绍2. 方法解读2.1 先验知识2.1.1 无向权重图2.1.2 拉普拉斯矩阵 2.2 构建图&#xff08;第一步&#xff09;2.2.1 ϵ \epsilon ϵ 邻近法2.2.2 k 近邻法2.2.3 全连接法 2.3 切图&#xff08;第二步&a…

谱聚类(Spectral Clustering)原理及Python实现

谱聚类原理及Python实现 图模型 无向带权图模型 G<V,E> G < V , E > &#xff0c;每一条边上的权重 wij w i j 为两个顶点的相似度&#xff0c;从而可以定义相似度矩阵 W W ,此外还可以定义度矩阵D" role="presentation" style="position: …

谱聚类算法(Spectral Clustering)

谱聚类算法(Spectral Clustering) 谱聚类(Spectral Clustering, SC)是一种基于图论的聚类方法——将带权无向图划分为两个或两个以上的最优子图&#xff0c;使子图内部尽量相似&#xff0c;而子图间距离尽量距离较远&#xff0c;以达到常见的聚类的目的。其中的最优是指最优目标…

谱聚类(spectral clustering)及其实现详解

Preface 开了很多题&#xff0c;手稿都是写好一直思考如何放到CSDN上来&#xff0c;一方面由于公司技术隐私&#xff0c;一方面由于面向对象不同&#xff0c;要大改&#xff0c;所以一直没贴出完整&#xff0c;希望日后可以把开的题都补充全。 先把大纲列出来&#xff1a; 一…

谱聚类算法

1. 算法思想 将所有的数据看成空间中的点&#xff0c;这些点之间可以用边连接起来。距离较远的点之间边的权重低&#xff0c;距离较近的点间边的权重高。然后对原图进行切图&#xff0c;使得不同子图间边的权重之和尽可能低&#xff0c;子图内边的权重之和尽可能高&#xff0c…

谱聚类(Spectral Clustering)算法介绍

一. 前言 本来想写关于聚类系列算法的介绍,但是聚类系列的其它几个算法原理比较简单,网上有大量的教程可以查阅。这里主要是介绍一下谱聚类算法,做一个学习笔记,同时也希望对想要了解该算法的朋友有一个帮助。关于聚类的其他系列算法,这里推荐一个写的很不错的博客。 谱…

聚类系列-谱聚类(spectral clustering)

聚类讲到此&#xff0c;也是我聚类系列的最后一篇博客了&#xff0c;最后一篇的话我们就来讲一下谱聚类。 谱聚类&#xff08;spectral clustering&#xff09;是一种基于图论的聚类方法&#xff0c;主要思想是把所有的数据看做空间中的点&#xff0c;这些点之间可以用边连接起…

谱聚类(spectral clustering)

1. 谱聚类概述 谱聚类是从图论中演化出来的算法&#xff0c;后来在聚类中得到了广泛的应用。它的主要思想是把所有的数据看做空间中的点&#xff0c;这些点之间可以用边连接起来。距离较远的两个点之间的边权重值较低&#xff0c;而距离较近的两个点之间的边权重值较高&#x…

谱聚类

谱聚类&#xff08;spectral clustering&#xff09;原理总结&#xff1a; 谱聚类&#xff08;spectral clustering&#xff09;是广泛使用的聚类算法&#xff0c;比起传统的K-Means算法&#xff0c;谱聚类对数据分布的适应性更强&#xff0c;聚类效果也很优秀&#xff0c;同时…

【机器学习】谱聚类(Spectral Clustering)

疑问 谱聚类的概念 谱聚类是一种针对图结构的聚类方法&#xff0c;将每个点都看作是一个图结构上的点&#xff0c;所以&#xff0c;判断两个点是否属于同一类的依据就是&#xff0c;两个点在图结构上是否有边相连&#xff0c;可以是直接相连也可以是间接相连。本质上就是一个图…

介绍谱聚类(spectral clustering)

文章目录 1、谱聚类概览2、谱聚类构图3、拉普拉斯矩阵4、切图聚类4.1RatioCut4.2Ncut5、总结流程 1、谱聚类概览 谱聚类演化于图论&#xff0c;后由于其表现出优秀的性能被广泛应用于聚类中&#xff0c;对比其他无监督聚类&#xff08;如kmeans&#xff09;&#xff0c;spectr…

聚类算法之谱聚类

谱聚类 1. 基本原理 它的主要思想&#xff1a;把所有数据看成空间中的点&#xff0c;这些点之间可以用变连接起来&#xff0c;距离较远的两个点之间的边权重较低&#xff0c;而距离较近的两个点之间的权重较高&#xff0c;通过对所有数据点组成的图进行切图&#xff0c;让切图…

非常全面的谱聚类算法原理总结

谱聚类算法是目前最流行的聚类算法之一&#xff0c;其性能及适用场景优于传统的聚类算法如k-均值算法&#xff0c;本文对谱聚类算法进行了详细总结&#xff0c;内容主要参考论文《A Tutorial on Spectral Clustering》&#xff0c;下载链接&#xff1a;https://github.com/zhan…

C语言遍历文件目录:readdir,opendir

环境&#xff1a;Linux系统 头文件&#xff1a; #include<sys/types.h> #include<dirent.h> 一、opendir 原型 DIR* opendir (const char * path ); 参数与功能 path为目录路径&#xff0c;打开一个目录&#xff0c;在失败的时候返回一个空的指针。 返回值…

嵌入式学习之Linux系统编程---9 目录IO之readdir函数

1、readdir函数的函数原型 #include <dirent.h> struct dirent *readdir(DIR *dirp);对于readdir函数来说&#xff0c;它只有目录流指针这一个参数&#xff0c;这个目录流指针就是使用opendir这个函数的返回值。 该函数在man手册的第三页&#xff0c;该函数如果执行成功…

readdir函数解析

函数原型: struct dirent *readdir(DIR *dirp); 首先纠正一个很多人都错误理解的事实,readdir不是系统调用,它是glibc的封装函数,而且readdir系统调用是存在的,原型如下: int readdir(unsigend int fd, struct old_linux_dirent *dirp, unsigned int count); glibc的readdi…

C/C++的readdir和readdir_r函数(遍历目录)

1.首先要打开目录文件 DIR *opendir( const char *name); DIR *fdopendir( int fd); 2.读取目录文件信息的函数 注意&#xff1a;这是个库函数 struct dirent *readdir( DIR *dirp); int readdir_r( DIR *dirp, struct dirent *entry, struct dirent **res…

Linux下 C 遍历目录(opendir,readdir函数)

opendir()函数: 头文件&#xff1a; #include <sys/types.h> #include <dirent.h> 函数原型&#xff1a; Dir* opendir(const char* pathname); 函数功能&#xff1a; 获取pathname目录下的所有文件和目录的列表&#xff0c;如果pathname是个文件或失败则返…