正确使用kmeans聚类的姿势
1. 聚类介绍
- 聚类试图将数据集中的样本划分为若干个通常是不相交的子集,每个子集称为一个“簇”(cluster).
- 通过这样的划分,使得同一个簇内的数据对象的相似性尽可能大,同时不在同一个簇中的数据对象的差异性也尽可能地大。
- 聚类过程仅能自动形成簇结构,簇所对应的概念语义需由使用者自己来把握。
- 聚类既能作为一个单独的过程用于寻找数据内在的分布结构,也可以作为分类等其他学习任务的前驱过程。
1.1 聚类算法:
- 基于原型的聚类(Prototype-based Clustering)
- K均值聚类(K-means)
- 学习向量量化聚类(Learning Vector Quantization)
- 高斯混合模型聚类 (Gaussian Mixture Model)
- 基于密度的聚类 (Density-based Clustering)
- DBSCAN (Density-Based Spatial Clustering of Application with Noise)
- OPTICS (Ordering Points To Identify the Clustering Structure)
- 层次聚类 (Hierarchical Clustering)
- 基于模型的聚类 (Model-based Clustering)
- 数据准备:特征标准化和降维
- 特征选择:从最初的特征中选择最有效的特征,并将其存储在向量中
- 特征提取:通过对选择的特征进行转换形成新的突出特征
- 聚类:基于某种距离函数进行相似度度量,获取簇
- 聚类结果评估:分析聚类结果,如
距离误差和(SSE)
等
1.3 聚类距离计算:
距离度量(distance measure)函数 $d()$ 需满足的基本性质:
- 非负性: $d(x,y)>=0$
- 同一性:$d(x,y) = 0 \quad if \quad and \quad only \quad if \quad x=y$
- 对称性: $d(x,y) = d(y,x)$
- 直递性:$d(x,y) \leq d(x,z) + d(z,y)$ (可不满足)
常用基于距离的相似度度量方法:
欧几里得距离:
曼哈顿距离:
1.4 聚类性能度量:
聚类性能度量亦称聚类“有效性指标”(validity index).
设置聚类性能度量的目的:
- 对聚类结果,通过某种性能度量来评估其好坏;
- 若明确了最终将要使用的性能度量,则可直接将其作为聚类过程的优化目标,从而更好地得到符合要求的聚类结果。
什么样的聚类结果比较好?
- “簇内相似度”(intra-cluster similarity)高
- “蔟间相似度”(inter-cluster similarity)低
聚类性能度量分类:
- “外部指标”(external index) :将聚类结果与某个“参考模型”(reference model)进行比较
- “内部指标”(internal index): 直接考察聚类结果而不利用任何参考模型
(1) 外部指标
(2) 内部指标
2 聚类算法介绍及实现
聚类算法类型:
- 基于原型的聚类(Prototype-based Clustering)
- K均值聚类(K-means )
- 学习向量量化聚类(Learning vector Quantization)
- 高斯混合聚类(Mixture-of-Gaussian)
- 基于密度的聚类(Density-based Clustering)
- 层次聚类(Hierarchical Clustering)
2.1 基于原型的聚类
原型聚类prototype-based clustering
,假设聚类结构能通过一组原型刻画(原型,即簇类的数目或者聚类中心). 通常情况下, 算法先对原型进行初始化, 然后对原型进行迭代更新求解, 采用不同的原型表示, 不同的求解方式,将产生不同的算法.
2.1.1 K-means
(1) 算法介绍
给定样本集 $D={x_1,x_2,…,x_n}$, K-means 算法针对聚类所得簇划分 $C={C_1,C_2,…,C_k}$, 最小化平方误差:
其中 $u_k$ 是簇 的均值向量:
直观上看, 平方误差在一定程度上刻画了簇内样本围绕均值向量的紧密程度, $err$ 值越小簇内样本相似度越高。但最小化 $err$ 不容易,是一个NP难问题, K-means 算法采用了贪心策略,通过迭代优化来近似求解 EE 的最小值。具体算法如下:
(2) 算法实现
我们的 k-means 实现将分为五个辅助方法和一个运行算法的主循环:
1.计算成对距离
1 |
|
pairwise_dist 函数与前面描述的相似性函数等效。这是我们比较两点相似性的指标。在这里,我使用的是欧几里得距离。我使用的公式可能看起来与欧几里德距离函数的常规公式不同。这是因为我们正在执行矩阵操作,而不是使用两个单个向量。在这里深入阅读。
2.初始化中心
1 |
|
该函数接收点数组并随机选择其中的 K 个作为初始质心。该函数仅返回 K 个选定点。
3.更新分配
1 |
|
更新分配函数负责选择每个点应该属于哪个集群。首先,我使用 pairwise_dist 函数计算每个点和每个质心之间的距离。然后,我得到每一行的最小距离的索引。最小距离的索引也是给定数据点的聚类分配索引,因为我们希望将每个点分配给最近的质心。
4.更新中心
1 |
|
更新中心功能负责对属于给定集群的所有点进行平均。该平均值是相应聚类的新质心。该函数返回新中心的数组。
5.计算损失
1 |
|
损失函数是我们评估聚类算法性能的指标。我们的损失只是每个点与其聚类质心之间的平方距离之和。在我们的实现中,我们首先调用成对距离来获得每个点和每个中心之间的距离矩阵。我们使用 cluster_idx 为每个点选择与集群对应的适当距离2。
主循环
1 |
|
现在,在主循环中,我们可以组合所有实用函数并实现伪代码。首先,中心用_init_centers随机初始化。然后,对于指定的迭代次数,我们重复update_assignment和update_centers步骤。每次迭代后,我们计算总损失并将其与之前的损失进行比较。如果差异小于我们的阈值,则算法执行完成。
补充:
k-means
优点:
- 计算复杂度低,为 ,其中 为迭代次数。
通常 和 要远远小于 ,此时复杂度相当于 。- 思想简单,容易实现。
k-means
缺点:
- 需要首先确定聚类的数量
- 分类结果严重依赖于分类中心的初始化。
通常进行多次k-means
,然后选择最优的那次作为最终聚类结果。- 结果不一定是全局最优的,只能保证局部最优。
- 对噪声敏感。因为簇的中心是取平均,因此聚类簇很远地方的噪音会导致簇的中心点偏移。
- 无法解决不规则形状的聚类。
- 无法处理离散特征,如:
国籍、性别
等。正确使用「K均值聚类」的Tips
- 输入数据一般需要做缩放,如标准化。原因很简单,K均值是建立在距离度量上的,因此不同变量间如果维度差别过大,可能会造成少数变量“施加了过高的影响而造成垄断”。
- 输出结果非固定,多次运行结果可能不同。首先要意识到K-means中是有随机性的,从初始化到收敛结果往往不同。一种看法是强行固定随机性,比如设定sklearn中的random state为固定值。另一种看法是,如果你的K均值结果总在大幅度变化,比如不同簇中的数据量在多次运行中变化很大,那么K均值不适合你的数据,不要试图稳定结果 [2]。
- 运行时间往往可以得到优化,选择最优的工具库。基本上现在的K均值实现都是K-means++,速度都不错。但当数据量过大时,依然可以使用其他方法,如MiniBatchKMeans [3]。上百万个数据点往往可以在数秒钟内完成聚类,推荐Sklearn的实现。
- 高维数据上的有效性有限。建立在距离度量上的算法一般都有类似的问题,那就是在高维空间中距离的意义有了变化,且并非所有维度都有意义。这种情况下,K均值的结果往往不好,而通过划分子空间的算法(sub-spacing method)效果可能更好。
- 运行效率与性能之间的取舍。
K值怎么确定
- 使用 K 均值算法,性能可能会因您使用的集群数量而有很大差异。要知道,K设置得越大,样本划分得就越细,每个簇的聚合程度就越高,误差平方和SSE自然就越小。所以不能单纯像选择初始点那样,用不同的K来做尝试,选择SSE最小的聚类结果对应的K值,因为这样选出来的肯定是你尝试的那些K值中最大的那个。
- “手肘法”(Elbow Method)
为了使用肘部方法,您只需多次运行 K-means 算法,每次迭代将聚类数增加一个。记录每次迭代的损失,然后制作 num cluster vs loss 的折线图。下面是肘部方法的简单实现:
运行此方法将输出一个类似于您在下面看到的图:
现在,为了选择正确数量的簇,我们进行目视检查。损耗曲线开始弯曲的点称为 肘点。肘点代表误差和聚类数量之间的合理权衡。在此示例中,肘点位于x = 3 处。这意味着最佳聚类数为 3。
1 |
|
1 |
|
2.1.2 k-means++
k-means++
是针对k-means
中初始质心点选取的优化算法。该算法的流程和k-means
类似,改变的地方只有初始质心的选取,该部分的算法流程如下
算法步骤:
- 从 中随机选择1个样本作为初始均值向量组 。
- 迭代,直到初始均值向量组有 个向量。
假设初始均值向量组为 。迭代过程如下:- 对每个样本 ,分别计算其距 的距离。这些距离的最小值记做 。
- 对样本 ,其设置为初始均值向量的概率正比于 。即:离所有的初始均值向量越远,则越可能被选中为下一个初始均值向量。
- 以概率分布 (未归一化的)随机挑选一个样本作为下一个初始均值向量 。
- 一旦挑选出初始均值向量组 ,剩下的迭代步骤与
k-means
相同。
2.1.3 LVQ
(1) 算法介绍
Learning vector Quantization (LVQ) 假设数据样本带有类别标记,学习过程利用样本的这些监督信息来辅助聚类。使用通过LVQ得到的原型向量来代表整个簇的过程,称为“向量量化”(Vector Quantization),这种数据压缩方法属于“有损压缩”(Lossy Compression)。
LVQ的目标是学得一组原型向量 ${p_1,p_2,…,p_q}$,每个原型向量代表一个聚类簇。LVQ在训练过程中通过对神经元权向量(原型向量)的不断更新,对其学习率的不断调整,能够使不同类别权向量之间的边界逐步收敛至贝叶斯分类边界。算法中,对获胜神经元(最近邻权向量)的选取是通过计算输入样本和权向量之间的距离的大小来判断的。
具体算法流程图如下所示:
算法解释
- 算法第1行:对原型向量进行初始化。例如:对第$i, i=(1,2,…,q)$ 个簇,从类别标记为 $t_i$ 的样本中随机选取一个作为原型向量。如果类别数小于聚类数,即 k>m ,则重新从第一个类别中继续选取;
- 算法第2-12行:对原型向量进行迭代优化,直到算法收敛。在每一轮迭代中,算法随机选取一个有标记训练样本,找出与其距离最近的原型向量,并根据两者的类别标记是否一致来对原型向量进行相应的更新。
- 算法第2-5行:从样本集中随机选取一个样本 $x_j$,计算该样本与每个原型向量 $p_i$ 之间的欧式距离,并找到与该样本距离最近的原型向量 $p_{i^}$ 的类别标记 $t_{i^}$
- 第6-10行:如何更新原型向量。迭代过程如下:
- 从样本集 中随机选取样本 ,挑选出距离 最近的原型向量 : 。
- 如果 的类别等于 ,则: ,将该原型向量更靠近
- 如果 的类别不等于 ,则: ,将该原型向量更远离
在原型向量的更新过程中:
如果 的类别等于 ,则更新后, 与 距离为:
即,更新后的原型向量 距离 更近。
如果 的类别不等于 ,则更新后, 与 距离为:
即,更新后的原型向量 距离 更远。- 算法第12行:若算法的停止条件已满足(例如已达到最大迭代轮数,或原型向量更新很小甚至不再更新),则将当前原型向量作为最终结果返回。
- 在学得一组原型向量 ${p_1,p_2,…,p_q}$ 后即可实现对样本空间 $X$ 的簇划分. 对任意样本 $x$, 他将被划入与其距离最近的原型向量所代表的簇中
可能涉及到的问题:
首先,既然已经有标签数据,那么为什么还要进行聚类呢?
我们输入的先验标签数据不一定是绝对真实的取值,可能是其他分类器输出的结果,可能是片面的、残缺的,需要靠聚类进行矫正和修补。(可以将先验知识当做一个约束值,该算法相当于在已知的约束条件下求解最最优值的过程)
对于矫正作用,由于输入的只有标签值,需要靠聚类进行类别边界的拟合;对于修补作用,由于LVQ聚类算法允许聚类的簇比输入的标签的类别多,这意味着一个类别可以被重新分割成多个类别。
其次,标签值是必须的吗?
一种说法是标签值是非必须的,如果没有先验的标签值,可以输入随机的标签值。我不太认同这种做法。因为标签值是一种约束,随机的约束即相当于没有约束,那么LVQ算法其实就退化为一般的聚类的算法,甚至更加严重,随机会使得系统更加混沌,算法会因为错误的指导给出效果更差的答案。所以我更偏向于将其归为半监督的聚类算法。
其他注意事项
- 样本异常点对聚类有影响,一般我们需要提前剔除掉
- 难以应用在高维特征空间
- 可以多选择几个簇心,来降低压缩率,提高保持较高的精度?
- 为了得到更精确的代表点需要调整迭代次数和学习率,时间复杂度比较
(2) LVQ算法实现
《手写LVQ(学习向量量化)聚类算法》
《ml/lvq/lvq_test/lvq_test.py》√
《neupy/neupy/algorithms/competitive/lvq.py 》√
《Learning Vector Quantization详解》
1 |
|
(3) LVQ2算法改进
LVQ算法中,对于某个输入向量X,算法只对与其具有最小Euclidean距离的权向量$w_k$ 进行调整。
在LVQ2[2]中,算法还要考虑与X具有次近Euclidean距离的权向量$w_r$,X与$w_k$及$w_r$间的距离分别记为 $d_k$ 与 $d_r$。如果下述3个条件都满足的话,算法就对$w_k$及$w_r$同时进行调整,否则就按照原先的LVQ算法调整权向量$w_k$:
- $w_k$及$w_r$代表不同的分类。
- 次近权向量$w_r$与X代表同一个分类。
- $d_k$ 与 $d_r$大致相等。一般来说.如果 $d_k$ 与 $d_r$能够满足$d_k/d_r>(1一£)$且 $d_r/d_k<(1+£)$,我们就认为 $d_k$ 与 $d_r$是大致相等的,其中£的取值依赖于训练例的多少。
在上述3个条件都满足的情况下,按下述公式调整$w_k$及$w_r$,使得$w_k$远离输入向量X,而$w_r$向输入向量的方向靠近:
- $W_k(new)=W_k(old)一\alpha(X—W_k(old))$
- $W_r(new)=W_r(old)+\alpha(X—W_r(old))$
LVQ2算法通过同时考察两个权值向量$w_k$及$w_r$,可以加快算法的收敛速度,使得各个权向量快速的向目标位置移动。
(4) LVQ2.1算法改进
LVQ2.1在LVQ2的基础上做了一些改进.LVQ2.1也是同时考察与某个输入向量X最近的两个权向量 $w_{c1},w_{c_2}$,但并不关心$w_{c1},w_{c_2}$哪一个离X更近(对应的距离分别为$d_{c1},d_{c_2}$)。当下面两个条件同时满足时将对$w_{c1},w_{c_2}$进行调整:
- $w_{c1},w_{c_2}$中,有一个权向量代表的分类和X所表示的一致,而另一个不一致。
- $max[d_{c_1}/d_{c_2},d_{c_2}/d_{c_1}]<(1+£)$且$min[d_{c_1}/d_{c_2},d_{c_2}/d_{c_1}]>(1-£)$
如果上述条件满足,不妨设 $w_{c1}$与X代表的类别相同,算法将调整权向量$w_{c1},w_{c_2}$,使得 $w_{c1}$输入向量X的方向靠近,而 $w_{c_2}$远离输入向量.调整公式为:
- $W_{c_1}(new)=W_{c_1}(old)+\alpha(X—W_{c_1}(old))$
- $W_{c_2}(new)=W_{c_2}(old)-\alpha(X—W_{c_2}(old))$
(5) LVQ3算法改进
LVQ3也是同时考虑与输入向量X距离最近的两个权向量 $w_{c1},w_{c_2}$。当条件 $min[d_{c_1}/d_{c_2},d_{c_2}/d_{c_1}]>(1-£)(1+£)$ 满足时 (£的一个典型取值为0.2). 权向量将按照下述规则进行调整:
- 如果 $w_{c1},w_{c_2}$两个权向量中有一个对应的分类与输入向量X一致,另一个不一致,则权向量的调整规则同 LVQ2.1
- 如果 $w_{c1},w_{c_2}$代表相同的分类,则权向量 $w_{c1},w_{c_2}$均采用公式 $W_{c}(new)=W_{c}(old)+\beta(X—W_{c}(old))$ 进行调整,其中$\beta=m\alpha, 0.1<m<0.5$
LVQ3算法通过对标准LVQ算法学习过程的修改,可以使得在网络学习过程不断进行的同时,网络的权向量能够很好地反映输入空间的概率密度分布,并且防止权向量偏离最优的位置。
(6) G-LVQ
G-LVQ将遗传算法应用于LVQ算法中,以克服LVQ算法本身的一些缺陷。
2.1.4 高斯混合聚类(Mixture-of-Gaussian)
高斯混合聚类(Mixture-of-Gaussian)采用概率模型来表达聚类原型.
- 对于 维样本空间 中的随机向量 ,若 服从高斯分布,则其概率密度函数为 :
其中 为 维均值向量, 是 的协方差矩阵。 的概率密度函数由参数 决定。 - 定义高斯混合分布: 。该分布由 个混合成分组成,每个混合成分对应一个高斯分布。其中:
- 是第 个高斯混合成分的参数。
- 是相应的混合系数,满足 。
- 假设训练集 的生成过程是由高斯混合分布给出。
令随机变量 表示生成样本 的高斯混合成分序号, 的先验概率 。
生成样本的过程分为两步:- 首先根据概率分布 生成随机变量 。
- 再根据 的结果,比如 , 根据概率 生成样本。
- 根据贝叶斯定理, 若已知输出为 ,则 的后验分布为:
其物理意义为:所有导致输出为 的情况中, 发生的概率。 - 当高斯混合分布已知时,高斯混合聚类将样本集 划分成 个簇 。
对于每个样本 ,给出它的簇标记 为:
即:如果 最有可能是 产生的,则将该样本划归到簇 。
这就是通过最大后验概率确定样本所属的聚类。 - 现在的问题是,如何学习高斯混合分布的参数。由于涉及到隐变量 ,可以采用
EM
算法求解。
具体求解参考EM
算法的章节部分。
2.2 基于密度的聚类
k-means
算法对于凸性数据具有良好的效果,能够根据距离来讲数据分为球状类的簇,但对于非凸形状的数据点,就无能为力了,当k-means
算法在环形数据的聚类时,我们看看会发生什么情况。
从上图可以看到,kmeans
聚类产生了错误的结果,这个时候就需要用到基于密度的聚类方法了。基于密度的聚类(Density-based Clustering)假设聚类结构能通过样本分布的紧密程度确定.密度聚类算法从样本密度的角度来考察样本之间的可连续性,并基于可连续样本不断扩展聚类簇以获得最终的聚类结果.
基于密度的聚类(Density-based Clustering)
- DBSCAN (Density-Based Spatial Clustering of Application with Noise)
- OPTICS (Ordering Points To Identify the Clustering Structure)
2.2.1 DBSCAN
DBSCAN(Density-Based Spatial Clustering of Applications with Noise)是一种基于密度的空间聚类算法,它不需要定义簇的个数,而是将具有足够高密度的区域划分为簇,并在有噪声的数据中发现任意形状的簇,在此算法中将簇定义为密度相连的点的最大集合。
首先介绍几个概念,考虑集合,表示定义密度的邻域半径,设聚类的邻域密度阈值为,有以下定义:
- 邻域(-neighborhood)
- 密度(desity)的密度为
- 核心点(core-point)
设,若,则称为的核心点,记中所有核心点构成的集合为,记所有非核心点构成的集合为。 - 边界点(border-point)
若,且,满足
即的邻域中存在核心点,则称为的边界点,记中所有的边界点构成的集合为。
此外,边界点也可以这么定义:若,且落在某个核心点的邻域内,则称为的一个边界点,一个边界点可能同时落入一个或多个核心点的邻域。 - 噪声点(noise-point)
若满足
则称为噪声点。
如下图所示,设,则A为核心点,B、C是边界点,而N是噪声点。
该算法的流程如下:
算法说明:
- DBSCAN算法先任选数据集中的一个核心对象为 “种子 (seed)”,再由此出发确定相应的聚类簇;
- 第1-7行:先根据给定的邻域簇 $(c,MinPts)$ 找出所有核心对象;
- 第10-24行:以任一核心对象为出发点,找出由其密度可达的样本生成聚类簇,直到所有核心对象均被访问过为止.
一般来说,
DBSCAN
算法有以下几个特点:
- 需要提前确定和值
- 不需要提前设置聚类的个数
- 对初值选取敏感,对噪声不敏感
- 对密度不均的数据聚合效果不好
2.2.2 OPTICS
OPTICS (Ordering Points To Identify the Clustering Structure). OPTICS和DBSCAN聚类相同,都是基于密度的聚类,但是,OPTICS的好处在于可以处理不同密度的类,结果有点像基于连通性的聚类,不过还是有些区别的.
2.3 层次聚类方法
前面介绍的几种算法确实可以在较小的复杂度内获取较好的结果,但是这几种算法却存在一个
链式效应
的现象,比如:A与B相似,B与C相似,那么在聚类的时候便会将A、B、C聚合到一起,但是如果A与C不相似,就会造成聚类误差,严重的时候这个误差可以一直传递下去。为了降低链式效应
,这时候层次聚类就该发挥作用了。
层次聚类(Hierarchical Clustering) 也称为基于连通性的聚类。这种算法试图在不同层次对数据进行划分,从而形成树形的聚类结构。
数据集的划分采用不同的策略会生成不同的层次聚类算法:
- “自底向上”的聚合策略
(Agglomerative)。每一个对象最开始都是一个cluster
,每次按一定的准则将最相近的两个cluster
合并生成一个新的cluster
,如此往复,直至最终所有的对象都属于一个cluster
。这里主要关注此类算法。- AGNES(Agglomerative Nesting)
- “自顶向下”的分拆策略
(Divisive)。最开始所有的对象均属于一个cluster
,每次按一定的准则将某个cluster
划分为多个cluster
,如此往复,直至每个对象均是一个cluster
。
2.3.1 AGNES
(1) 算法介绍
AGNES(Agglomerative Nesting)是一种采用自底向上聚合策略的层次聚类算法,算法的步骤为:
- 先将数据集中的每个样本当做是一个初始聚类簇;
- 然后在算法运行的每一步中找出距离最近的两个点(聚类簇)进行合并为一个聚类簇;
- 上述过程不断重复,直至所有的样本点合并为一个聚类簇或达到预设的聚类簇个数。 最终算法会产生一棵树,称为树状图(dendrogram), 树状图展示了数据点是如何合并的.
这个算法的关键是如何计算两点之间以及两个聚类簇之间的距离
- 如何计算两点之间的距离[距离矩阵(Metric)]:
- 如何计算两个聚类簇(集合)之间的距离[链接准则(Linkage criteria)]:
- Complete-linkage clustering(全链接)
- Single-linkage clustering(单链接)
- Mean-linkage clustering(平均链接 UPGMA)
- Centroid-linkage clustering(中心链接 UPGMC)
- Minimum energy clustering
3 聚类效果评价指标
互信息(Mutual information)
互信息的计算公式如下:
标准化互信息(NMI, Normalized Mutual Information)
通常采用NMI和AMI来作为衡量聚类效果的指标。
标准化互信息的计算方法如下:
调整互信息(AMI, Adjusted Mutual Information)
调整互信息的计算要复杂一些,其计算方法如下:
Python实现
Python中的 sklearn 库里有这三个指标的类,可以直接调用;
1 |
|