聚类的概念
对于有标签的数据,我们进行有监督学习,常见的分类任务就是监督学习;而对于无标签的数据,我们希望发现无标签的数据中的潜在信息,这就是无监督学习。聚类,就是无监督学习的一种,它的概念是:将相似的对象归到同一个簇中,使得同一个簇内的数据对象的相似性尽可能大,同时不在同一个簇中的数据对象的差异性也尽可能地大。即聚类后同一类的数据尽可能聚集到一起,不同数据尽量分离。
聚类算法的分类
聚类算法有很多种分法,体系也很大,这里举例几种分法:
基于划分的聚类:聚类目标是使得类内的点足够近,类间的点足够远,常见的如k-means及其衍生算法
基于密度的聚类:当邻近区域的密度超过某个阈值,则继续聚类,如DBSCAN; OPTICS
层次聚类:这个下面会具体介绍到,包括合并的层次聚类,分裂的层次聚类,实际上可以看作是二叉树的生成和分裂过程。下面会介绍实际应用中常用的HDBSCAN
基于图的聚类: 通过建图来进行聚类,这是聚类算法中的大头,很多较新的聚类算法都有图聚类的思想。这篇文章会介绍以Chinese Whisper,谱聚类两大具有代表性的图聚类算法
基于GCN(图神经网络)的聚类:实际上这个本质上也是基于图的聚类,然而基于GCN的聚类算法会有深度学习中的训练的概念,而传统的聚类算法则是通过人工设定阈值来决定的,所以这里也分开列了一类, 这篇文章会介绍《Learning to Cluster Faces on Affinity Graph》、CDP两篇论文的思想
…
其实还有很多分类,但这里不再列举了,有兴趣的同学可以参考sklearn文档中关于聚类的划分 https://scikit-learn.org/stable/modules/clustering.html#clustering
K-Means
这个可以说是最基础的聚类算法了,它的输入需要簇的个数k,这个k是用户指定的,也就是说需要提前确定类别,其算法流程是:
随机确定k个初始点u1, u2…uk作为聚类质心
重复以下过程直到收敛:
对于每一个样例,找到离它最近的质心作为label:
对于每一个类j, 更新其质心:
[公式]
优点: 速度快
缺点:
必须提前知道"k", 也就是有多少个簇
容易陷入局部最优
数据必须符合“数据之间的相似度可以使用欧式距离衡量”,这个是什么意思呢,看下图,这种数据的分布,样本点的距离不能简单地用欧式距离来衡量,否则分类效果会非常差。这里的距离衡量应该是“测地距离”,也就是样本沿着曲面到达另一个样本点的距离。如果在这种数据空间想要使用kmeans,必须先进行空间的转化
k-means有一些改进算法,多是针对k-means会受异常点的影响这一点来改进的,比如K-Means++, K-Medians…
基于密度的算法-DBSCAN
基于密度的算法,要求聚类空间的一定区域所包含的对象的数目不小于某一给定阈值,先了解一些基本概念:
(1)Eps邻域:给定对象半径Eps内的邻域称为该对象的Eps邻域;
(2)核心对象(core point):如果对象的Eps邻域至少包含最小数目MinPts的对象,则称该对象为核心对象;
(3)直接密度可达(directly density-reachable):若某点p在点的q的Eps领域内,且q是一个核心对象,则p-q直接密度可达
(4)密度可达(density-reachable):如果存在一个对象链 p1, …,pi,…, pn,如果对于任意pi, pi-1都是直接密度可达的,则称pi到pi-1密度可达,实际上是直接密度可达的传播链
(5)密度相连(density-connected):如果从某个核心对象p出发,点q和点k都是密度可达的,则称点q和k是密度相连的。
(6)边界点(edge point):边界点不是核心对象,但落在某个核心对象的邻域内;
(7)噪音点(outlier point):既不是核心点,也不是边界点的任何点;
看看上图,红色点是所谓的核心对象,以它为圆心,Eps为半径去画圆,在圆内样本点数目大于MinPts的就是核心对象;被包含在核心对象的范围内,但是自身不是核心对象的点是样本点;即不被包含在核心对象内,自身也不是核心对象的点为噪音点,将被抛弃。
DBSCAN的核心思想是从某个核心点出发,不断向密度可达的区域扩张,从而得到一个包含核心点和边界点的最大化区域,区域中任意两点密度相连。现在我们来看看DBSCAN的一个算法流程,会更容易理解:
输入:给定点在领域内成为核心对象的最小领域点数(MinPts), 领域半径: Eps
输出:簇集合
首先将数据集D中所有的对象标记为未处理状态:
对数据集D中的每个对象p:
if p已经归入了某个簇:
continue
else:
检查对象p的Eps领域 NEps§
if NEps§包含的对象数小于MinPts:
标记对象p为边界点或者噪声点;
else:
标记对象p为核心点,并建立新簇C,将p领域内的所有点加入C
for (NEPs§中所有尚未处理的对象q):
检查对象q的领域NEps(q), 若NEps(q)包含至少MInPts个对象,则将NEps(q)中未归入
任何一个簇的对象加入C
优点:
不需要指定簇的数目(不需要 k)
可以发现任意形状的聚类簇
对噪声不敏感
从这张图中kmeans和DBSCAN的对比可以看出DBSCAN对这种数据分布的拟合更好
缺点:
需要设置半径Eps和MinPts, 空间聚类密度不均匀时难以设置参数,所以有一个问题就是,在数据集A上挑好的参数很可能到数据集B上就不能用了
随着数据量的增大,计算量显著增大,反正大规模数据集用DBSCAN很可能会崩的
层次密度聚类 HDBSCAN
这是一个对DBSCAN的改进算法,结合了密度聚类和层次聚类。它的优化点主要如下:
使用相互可达距离替换欧氏距离,该距离可以使得密度低的点离密度高的区域更远,减少dbscan对Eps阈值的依赖性
使用最小生成树构建层次聚类模型,引入层次聚类思想
对最小生成树的最小子树做了限制,减少计算量,同时保证生成的类簇不要过小
使用“簇稳定性”的度量方式自动划分类簇,不需要自行设定阈值
这里面有一些专业术语可能一看起来不太能明白,我们来逐一解释。
可达距离
可达距离是对DBSCAN中核心距离的一个改进版,也是DBSCAN的改进算法OPTICS的主要核心思想,也就是通过改变距离的度量方式减少dbscan对阈值Eps的敏感性;该距离可以让稀疏的点离密度高的区域更远。了解可达距离之前,我们先看看核心距离:
核心距离:对于给定的样本点,使得该点成为核心点的最小Eps为该点的核心距离。假设样本点为p, 找到以p为圆心,刚好满足minPts的最外层的点q,则p和q的距离为核心距离;看下图,加入我们的MinPts设为3,那么找到以红色点P为圆心,MinPts正好为3的半径 [公式] 即为核心距离
可达距离:对于样本点p周围的点q1,q2…,1n,如果这些点到点p的距离大于p的核心距离,则可达距离为该点到p的实际距离;如小于,则可达距离为点x的核心距离。我们继续看上图,点1,2,3的可达距离均为核心距离,而在核心距离之外的点4, 5, 它们到点P的距离仍然是欧式距离。那么为什么要用可达距离替换欧氏距离呢?我们看看下面这张图就知道了,下图中,蓝色核心点和绿色核心点原本的距离应该是两点的欧氏距离,但是因为蓝色核心点在绿色核心点的核心距离内,所以此时它们的可达距离为绿色核心点的半径>两点的欧氏距离,相当于把蓝色核心点和绿色核心点区分开了;红色核心点到蓝色核心点的距离一样,它们的可达距离要大于蓝色核心点和红色核心点的实际距离,这样以蓝色核心点为代表的高密度区域与红色核心点、绿色核心点的低密度区域就被推开了;而绿色核心点和红色核心点的距离则依旧是它们的欧氏距离。
层次聚类
要理解HDBSCAN,首先要搞清楚层次聚类到底是什么。层次聚类有自上而下的方式和自下而上的方式。在这里我们只介绍自下而上的方式,也就是HDBSCAN算法中用到的方式。
假设有 n 个待聚类的样本
(初始化)将每个样本都视为一个簇;
计算各个聚类之间的相似度;
寻找最近的两个聚类,将他们归为一类;
重复步骤二,步骤三;直到所有样本归为一类。
其实就是一个不断归一化最后归成一类的过程。实际上层次不同的层次聚类算法考虑的主要是相似度的衡量方式和终止聚类的条件的不同。相似度的衡量方式决定了哪些样本将被聚到一起,而中止聚类的条件决定了选择哪一层级的类别作为最终的聚类输出。
而HDBSCAN是以可达距离作为领接边权重,对所有节点构建最小生成树,之后进行层次聚类
簇压缩
我们将HDBSCAN的样本点进行层次聚类,构造成上面的生成树图之后,HDBSCAN会进行一个压缩树的过程。它的原理是,对于我们生成的最小生成树,从上往下遍历,在一个簇被划分为两个子簇的过程中,如果子簇的样本点数量小于设定的最小值(也就是前面可达距离的概念中设置的MinPts,那么这个小于MinPts的子簇将会不会被保留,子簇中的样本将作为-1类被删除。
簇选择
在聚类的簇完成簇压缩的过程后,此时我们得到了一个更小的最小生成树,此时,我们需要开始决定保留那些簇作为我们的类。对于DBSCAN算法来说,实际上是在某个阈值下画了一条线,来决定选取哪些类作为聚类类别。
DBSCAN的簇选择方式
而HDBSCAN使用了一个簇稳定性的概念。
定义s为簇稳定性,其计算方式如下:
实际上是说,我们可以将 [公式] 看作是一个相似度,而簇稳定性则是说,在不同的 [公式] 的取值下,有一些簇会被合并为一个更大的簇,此时我们说这些被合并的簇“消失了”,而在一个 [公式] 值更小的时候,也就是相似度更低,不那么严格的情况下,这些簇刚刚被它们的子簇合并出来。也就是说,簇稳定性定义的是这些簇从第一次出现到被合并进更高层次的的簇的范围,代表着这个簇的生存周期。在做簇选择的时候,实际上要选择那些簇稳定性最高的簇。那么选择原则就是:
如果当前节点的稳定性大于两个子节点的簇稳定性,将当前节点作为提取簇,不再提取其子节点;如果当前节点的稳定性小于两个子节点的稳定性总和,将该节点设置为其子节点的稳定性之和
上图中,只选择了簇稳定性最高的簇
到这里,整个HDBSCAN的算法就介绍完了。
优点:
不需要自行设置阈值,只需定义最小簇的数量
计算消耗相对小,速度较快(使用最小生成树建图,并使用了簇压缩)
参数敏感度较低
基于Graph的聚类算法–Chinese Whisper
下面说到基于Graph的聚类算法,这种类型的算法实际应用效果比较好,还挺重要的。其中代表的基础算法Chinese Whisper还挺简单的:
初始化:将所有的样本点初始化为不同的类,自下而上的进行聚类
建图:根据样本点之间的距离,设定相似度,低于相似度阈值的两个样本点之间建立边,高于阈值则无边,由此构建加权无向图,边的权重为相似度
迭代:
-
随机选取一个节点i开始,在其相连节点中选取边权重最大者j, 并将i归为节点j类(若相连节点中有多个节点属于同一类,则将这些权重相加再做比较)
-
遍历所有节点后,重复迭代至满足迭代次数
优点:不用设定k,只需指定相似度阈值
缺点:
-
对向量的要求度较高,需要向量能够增大类间距离,减小类内距离
-
由于随机初始化,每次聚类的结果有可能不一致
中间的节点可能被归到任何一类,由于随机初始化
改进:
CW需要自行设置相似度阈值,且该阈值敏感度较高,后续优化方向是自动选择阈值,有兴趣可以参考下面这篇论文:
Linkage Based Face Clustering via GCN(CVPR2019)
谱聚类是相对来说比较复杂的一个聚类算法,所以这里也不详细展开说了,大概说一下它的原理:它解决的问题是kmeans中无法对非欧式空间的分布进行聚类的问题,主要原理是对聚类数据进行变换,然后进行k-means聚类,之后再还原到原空间。
算法思路:它的主要思想是把所有的数据看做空间中的点,这些点之间可以用边连接起来。距离较远的两个点之间的边权重值较低,而距离较近的两个点之间的边权重值较高,通过对所有数据点组成的图进行切图,让切图后不同的子图间边权重和尽可能的低,而子图内的边权重和尽可能的高,从而达到聚类的目的。
谱聚类的流程是:
输入:n个样本, 类别k
根据输入的相似度的衡量方式对样本建图,根据相似图建立邻接矩阵W
计算出拉普拉斯矩阵L, 其中L=D-W, D为度矩阵
计算L的最小的k个特征向量u1, u2,…,uk(此步相当于降维),将这些向量组成为n*k维的矩阵U
将U中的每一行作为一个样本,共n个样本,使用k-means对这n个样本进行聚类
得到簇划分C(c1,c2,…ck).
这里的拉普拉斯、度矩阵的推断都需要一定篇幅,之前写过一篇谱聚类的算法原理,有兴趣可移步至:
谱聚类的原理和优化目标
这里只简单介绍几个概念:
邻接矩阵:
邻接矩阵是聚类中经常听到的一个概念,实际上是表示定点之间相邻关系的矩阵,也就是其实可以看作一个表格,每个元素代表两个点的关联程度
最小割
最小割是指去掉图中的一些带权边,在使得图从联通图变为不联通图的前提下,尽可能的让去掉的边权值之和尽可能小。对于数据的相似性图来说,最小割就是要去除一些很弱的相似性,把数据点从一个互相连接的整体分为两个或者多个独立的部分,这其实就是一个聚类的过程
具体的最小割的优化可参见:谱聚类的原理和优化目标
优点:在算法中使用了降维,对于高维空间效果较好
缺点:
-
如果向量维度过高,而降维的幅度不够,则最后的聚类效果与运行速度均不好
-
需要提前知道k
-
不同的领接矩阵的聚类结果可能不一样
最新
这里再介绍两篇比较新的论文,也可以看作是未来聚类的一个发展趋势。在现在万物皆可深度学习的潮流下,如今的聚类也开始向GNN(图神经)网络的方向去发展了。
基于GNN的聚类
GNN这块的话,其实简单来说,我们知道CNN的输入是图片,RNN的输入是文本或者语音等序列,而GNN的输入则是图。实际上走的都是深度学习梯度下降的优化路线, 只是不同网络的输入不一样而已。
Learning to Cluster Faces on Affinity Graphy(CVPR2019)
第一篇paper就是基于图神经网络(GCN)的聚类算法
算法流程(级联式的算法流程,类似mtcnn):
-
将样本点建图(如何建图可以参照前面图聚类算法,实际上有很多种构建方式,主要取决于相似度如何衡量以及如何建边)
-
Cluster Proposal:从前面建好的图中选择出多个sub-graph,也就是proposal,就是子图的概念。(这里其实和Faster RCNN等检测网络有些像),这一步实际上主要是为了降低计算消耗,我们不在一整幅图上去做聚类,而是在子图上去做。每一个cluster proposal里的向量数是比较少的。比如说一个包含1M向量的全图可以转化为50K包含20向量的proposal
-
Cluster Detection: 将上面的Cluster Proposal利用GCN提取特征后聚类,计算预测类别与gt的差异,评价指标为:
这个IoU目标检测的同学应该很熟了,原理是类似的,总之是用这个指标来进行训练
- Cluster Segmentation: 上面那个模块是检测,这个模块是剔除负样本点,评价指标和上面那一步是一样的。使用的loss均为MSE,训练然后梯度下降
这篇文章中还用到了Ablation Study,这也算是近年来Paper必备的一个部分吧。可以参考
Affinity Graph: Graph在半监督学习和聚类上经常出现。Affinity graph的节点是数据样本,边代表数据之间的相似度。
标题的Affinity Graphy也是在半监督学习中经常出现的一个术语,实际上就是指节点代表数据样本,边代表数据之间相似度的图。
CDP(ECCV2018)
这一篇是针对人脸识别提出的优化算法,解决的是在大数据集下传统算法聚类性能过差的问题
级联模型的思想,想象一下mtcnn。
流程:
该算法有3个部分,base model, committe model(决策者模型)和Mediator(融合模型), 其实就是base model建一个大图,多个简单的committe model对大图进行断边,Mediator根据多个committe的结果来判断两个节点之间的边是保留还是断开。
base model: 建knn图
Committe model: 多个committe model对base model建的图,对每一条边,判断其是否应该断开,输出多个子图
Mediator: 集成committe输出的pairs的关系,最终输出聚类结果。看下图,假设我们有6个committe model, 对于节点1和节点2的边,所有的committe model均判断其有边,则保留边;对于节点4,8,6个model中有四个committe model将其断开,则mediator将其断开,最后就会是节点4和节点8在不同的cluster中。
各个模块都是使用GCN来训练,而非设置阈值
优点: 只探索局部关系,因为它的主要计算量集中在两个节点组成的pairs的关系,而不是整个图的关系,计算效率较高,可以用于大规模数据集
聚类算法选型
下面是一点个人经验,如何进行聚类算法选型
•特征:聚类算法达到瓶颈时,应该优化特征,减少类内距离,增大类间距离;对于杂质较多的特征,需要采取一定的过滤措施:如根据图像质量、光照、模糊、内容识别等进行过滤
•参数配置:实际应用中能否知道“k”,如果不能,k-means和谱聚类就不能用
•性能: 聚类算法往往涉及两两计算相似度,如果算法不做优化时间消耗可能很大,常见优化如使用向量运算替换循环;像一些没有经过计算效率优化的算法,如DBSCAN,其实在大规模数据集上是用不了的
•参数敏感度:聚类时需要考虑参数敏感度的分析,如果算法对参数过于敏感,可以寻找是否有基于当前算法的参数自调整算法;