k-means及变种
转自:http://blog.csdn.net/tuqinag/article/details/45893459
聚类算法
聚类算法是属于无监督学习算法中非常常用的一种。算法使用的训练数据中的标签信息是未知的,目标是通过对无标记的训练样本的学习来揭示内在的性质和规律。聚类过程能够自动地形成簇结构,但是簇对应的概念语意需要由使用者来决定。聚类既能作为一个单独的过程,用于寻找数据的内在分布结构,也可以作为分类等其他学习任务的前驱过程。
性能度量
对于任何一个算法,我们都需要有一个性能指标来衡量算法结果的优劣。之前已经有一篇博客介绍了性能度量这一问题,那更多的是对于监督学习算法而言。对于聚类问题来说,有其相对独立的性能度量指标。
聚类是将数据集D划分为若干个互不相交的子集。直观上看,我们希望『物以类聚』,即同一簇的样本尽可能彼此相似,不同簇的样本尽可能不同。换言之,聚类结果的『簇内相似度』高且『簇间相似度』低。
聚类性能度量大致有两类。一类是将聚类结果与某个『参考模型』进行比较,称为『外部指标』;另一类是直接考察聚类结果而不利用任何参考模型,称为『内部指标』。
外部指标
对数据集D,假定通过聚类给出的簇划分为C={C1,C2,...,Ck},参考模型给出的簇划分为C∗={C∗1,C∗2,...,C∗s}。令λ与λ∗分别表示C与C∗对应簇的簇心向量。将样本两两配对考虑,定义:
a=|SS|,SS={(xi,xj)|λi=λj,λ∗i=λ∗j,i<j}
b=|SD|,SD={(xi,xj)|λi=λj,λ∗i≠λ∗j,i<j}
c=|DS|,DS={(xi,xj)|λi≠λj,λ∗i=λ∗j,i<j}
d=|DD|,DD={(xi,xj)|λi≠λj,λ∗i≠λ∗j,i<j}
其中集合SS包含了在C中隶属与相同簇且在C∗中也隶属于相同簇的样本对,集合SD包含了在C中隶属于相同簇但在C∗中隶属于不同簇的样本对。其他集合的含义可以类推得到。
基于以上集合,有下面这些常用的聚类性能度量外部指标:
Jaccard系数:
JC=aa+b+c
FM指数(Fowlkes and Mallows Index):
FMI=(aa+b⋅aa+c)−−−−−−−−−−−−√2
Rand指数:
RI=2(a+d)m(m−1)
上述性能度量的结果均在[0,1]区间内,只越大越好。
内部指标
考虑聚类结果的簇划分C={C1,C2,...,Ck},定义以下符号:
avg(C)=2|C|(|C|−1)∑1≤i<j≤|C|dist(xi,xj)
diam(C)=max1≤i<j≤|C|dist(xi,xj)
dmin(Ci,Cj)=minxi∈Ci,xj∈Cjdist(xi,xj)
dcen(Ci,Cj)=dist(μi,μj)
其中,dist(⋅,⋅)用于计算两个样本之间的距离;μ代表簇C的中心点μ=1|C|∑1≤i≤|C|xi。显然avg(C)对应于簇C内样本间的平均距离,diam(C)对应于簇C内样本间的最远距离,dmin(Ci,Cj)对应于簇Ci与簇Cj最近样本间的距离,dcen(Ci,Cj)对应于簇Ci与簇Cj中心点间的距离。
基于以上这些距离,可以导出以下常用的聚类性能度量的内部指标:
DB指数(Davies-Bouldin Index):
DBI=1k∑i=1kmaxj≠i(avg(Ci)+avg(Cj)dcen(μi,μj))
Dunn指数:
DI=min1≤i≤k{minj≠i(dmin(Ci,Cj)max1≤l≤kdiam(Cl))}
其中,DBI的值越小越好,而DI则相反,值越大越好。
距离度量
在聚类算法中,很多时候都需要用到距离的计算。对于这个问题,其实已经讨论的非常普遍了,这里也不想再展开,只说一些比较特定的问题吧。
我们通常将属性划分为『连续属性』和『离散属性』。然而在距离计算时,属性上是否定义了『序』关系更为重要。例如定义域为{1,2,3}的离散属性与连续属性的性质更为接近一些,能直接在属性上计算距离,这样的属性称为『有序属性』。而定义域为{飞机,火车,轮船}这样的离散属性则不能直接在属性上计算距离,称为『无序属性』。
对于无序属性的距离计算可以使用VDM(Value Difference Metric)。令mu,a表示在属性u上取值为a的样本数,mu,a,i表示在第i个样本簇中属性u上取值为a的样本树,k为样本簇数,则属性u上两个离散值a与b之间的VDM距离为:
VDMp(a,b)=∑i=1k|mu,a,imu,a−mu,b,imu,b|p
关于VDM度量我是有一个疑问的,在一开始没有对数据进行聚类时,如何计算两个属性间的VDM值?希望能给一些解答。
将明可夫斯基距离与VDM相结合即可处理混合属性。假设有nc个有序属性,n−nc个无序属性,令有序属性排列在无序属性之前,则:
MinkovDMp(xi,xj)=(∑u=1nc|xju−xiu|p+∑u=nc+1nVDMp(xiu,xju))1p
基于原型的聚类
这里的『原型』是指样本空间中具有代表性的点。此类算法假设聚类结构能够通过一组原型刻画。通常情况下,算法先对原型进行初始化,然后对原型进行迭代更新求解。采用不同的原型表示,不同的求解方式,将产生不同的算法。
K-means算法
算法的主要流程如下:
选择k个点作为初始质心;
Repeat:将每个点指派到最近的质心,形成k个簇;重新计算每个簇中所有点的均值并将均值作为质心;
Until簇不再发生变化或达到最大的迭代次数。
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
在此,需要对该算法进行如下说明:
1)将点指派到最近的质心:对欧式空间中的点使用欧几里得距离L2(最小化),对文档用余弦相似性(最大化)。这相当于是一种贪心的选择。
2)误差平方和作为度量质量聚类的目标函数。
SSE=∑i=1K∑x∈Cidist(Ci−x)2
Ci是第i个簇的质心,Ci=1|Ci|∑x∈Cix
3)找到的是局部最优,因为是对选定的质心和簇。
选取初始质心的改进
在k-means方法中,k值的选择以及初始聚类中心的选择对于算法的效果影响很大。常见的方法是随机的选取初始质心,但是这样簇的质量常常很差。处理选取初始质心问题的一种常用技术是:多次运行,每次使用一组不同的随机初始质心,然后选取具有最小SSE(误差的平方和)的簇集。这种策略简单,但是效果可能不好,这取决于数据集和寻找的簇的个数。
第二种有效的方法取一个样本,并使用层次聚类(这种方法我们之后会介绍到)技术对训练数据进行聚类。从层次聚类中提取K个簇,并用这些簇的质心作为初始质心。该方法通常很有效,但仅对下列情况有效:
(1)样本相对较小,例如数百到数千(层次聚类开销较大);
(2)K相对于样本大小较小
第三种方法,随机地选择第一个点,或整个训练集的质心作为第一个点。然后,对于每个后继初始质心,选择离已经选取过的初始质心最远的点。使用这种方法,确保了选择的初始质心不仅是随机的,而且是散开的。但是,这种方法可能选中离群点。此外,求离当前初始质心集最远的点开销也非常大。为了克服这个问题,通常该方法用于点样本。由于离群点很少(多了就不是离群点了),它们多半不会在随机样本中出现。计算量也大幅减少。
空聚类的处理
如果有的点在指派步骤都未分配到某个簇,就会得到空簇。如果这种情况发生,则需要某种策略来选择一个替补质心,否则的话,平方误差将会偏大。一种方法是选择一个距离当前任何质心最远的点。这将消除当前对总平方误差影响最大的点。另一种方法是从具有最大SSE的簇中选择一个替补的质心。这将分裂簇并降低聚类的总SSE。如果有多个空簇,则该过程重复多次。另外,编程实现时,要注意空簇可能导致的程序bug。
补充
其实我们也可以用EM算法来解释K-means算法的学习过程(如果还不知道EM算法是什么,可以翻一下我关于EM算法的博客)。我们的目的就是将样本分为k个类,其实说白了就是求一个样本的隐含类别,然后用隐含类别将x归类。由于我们事先不知道类别y,那么首先我们可以对每个样例假定一个y。
E-step:将样本分配到距离最近的聚类中心所属的簇,这相当于对隐含变量y进行求解。
M-step:更新每个簇的聚类中心,使得p(x,c)最大。
混合高斯聚类
混合高斯聚类采用概率模型来表达聚类原型。定义混合高斯分布为:
pM(x)=∑i=1kαi⋅p(x|μi,Σi)
该分布共由k个混合成分组成,每一个混合成分对应一个高斯分布。其中μi与Σi是第i个高斯混合成分的参数,而αi>0为对应的混合系数,∑ki=1αi=1。
假设样本的生成过程由高斯混合分布给出:首先,根据α1,α2,...,αk定义的先验分布选择高斯混合成分,其中αi为选择第i个混合成分的概率;然后,根据被选择的混合成分的概率密度函数进行采样,从而生成相应的样本。
若训练集D由上述过程生成,令随机变量zj∈{1,2,...,k}表示生成样本xj的聚类标签。显然,zj的先验概率P(zj=i)对应于αi。根据贝叶斯定理,zj的后验分布对应于:
PM(zj=i|xj)=P(zj=i)⋅pM(xj|zj=i)pM(xj)=αi⋅p(xj|μi,Σi)∑kl=1αl⋅p(xj|μl,Σl)
pM(zj=i|xj)给出了样本xj由第i个高斯混合成分生成的后验概率,将其简记为γji。当高斯混合分布已知时,高斯混合聚类把样本D划分为k个簇C={C1,C2,...,Ck},每个样本xj的簇标记为λj如下确定:
λj=argmaxi∈{1,2,...,k}γji
对于这个式子如何求解,我们会用到一个叫做EM的算法,之后会专门有一篇博客来介绍该算法以及高斯混合聚类的求解过程。
层次聚类
试图在不同层次对数据集进行划分,从而形成树形的聚类结构。这里的划分方式有两种:
(1)自底向上的:从点作为个体簇开始,每一合并两个最接近的簇。这需要定义簇的邻接性的概念。(主要讲这个)
(2)自顶向下的:从包含所有点的一个簇开始,每一步分裂一个簇,直到仅剩下单点簇。这种情况下,我们需要确定每一步分裂哪个簇,以及如何分裂。
算法的具体流程
输入:样本集D={x1,x2,...,xm},聚类簇距离度量函数d,聚类簇数k
过程:
for j = 1, 2, ..., m do$C_j = \{x_j\}$
end for
for i = 1, 2, ..., m dofor j = 1, 2, ..., m doM(i, j) = d($C_i, C_j$)M(j, i) = M(i, j)end for
end for
设置当前聚类簇数:q = m
while q > k:找出距离最近的两个聚类簇$C_{i^*}$和$C_{j^*}$合并$C_{i^*}$和$C_{j^*}$:$C_{i^*} = C_{i^*} \bigcup C_{j^*}$for j = j^* + 1, j^* + 2,...,q do将聚类簇$C_j$重编号为$C_{j - 1}$end for删除距离矩阵M的第$j^*$行与第$j^*$列for j = 1, 2,..., q - 1 doM($i^*, j$) = d($C_{i^*}, C_j$)M($j, i^*$) = M($i^*, j$)end forq = q - 1
end while
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
输出:簇划分C={C1,C2,...,Ck}
簇之间的距离
从上面的算法中可以看出,需要计算簇之间的距离。这里通常的方法有三种:
最小距离:dmin(Ci,Cj)=minx∈Ci,z∈Cjdist(x,z)
最大距离:dmax(Ci,Cj)=maxx∈Ci,z∈Cjdist(x,z)
平均距离:davg(Ci,Cj)=1|Ci||Cj|∑x∈Ci∑z∈Cjdist(x,z)
在具体的算法中,选择这三种不同的方法又有不同的称呼。
单链接:使用最小距离,擅长于处理非椭圆形状的簇,但对噪声和离群点很敏感。
全链接:使用最大距离,对噪声和离群点不太敏感,但是它可能使大的簇破裂,并且偏好于球形。
组平均:使用平均距离。
可以使用一个简单的例子来说明下这几种方法的异同点:
点 | X坐标 | Y坐标 |
---|---|---|
P1 | 0.4005 | 0.5306 |
P2 | 0.2148 | 0.3854 |
P3 | 0.3457 | 0.3156 |
P4 | 0.2652 | 0.1875 |
P5 | 0.0789 | 0.4139 |
P6 | 0.4548 | 0.3022 |
6个点的欧几里得距离矩阵:
点 | P1 | P2 | P3 | P4 | P5 | P6 |
---|---|---|---|---|---|---|
P1 | 0.0000 | 0.2357 | 0.2218 | 0.3688 | 0.3421 | 0.2347 |
P2 | 0.2357 | 0.0000 | 0.1483 | 0.2042 | 0.1388 | 0.2540 |
P3 | 0.2218 | 0.1483 | 0.0000 | 0.1513 | 0.2483 | 0.1100 |
P4 | 0.3688 | 0.2042 | 0.1513 | 0.0000 | 0.2932 | 0.2216 |
P5 | 0.3412 | 0.1388 | 0.2843 | 0.2932 | 0.0000 | 0.3921 |
P6 | 0.2347 | 0.2540 | 0.1100 | 0.2216 | 0.3912 | 0.0000 |
对于单链聚类:
Dist((3,6),(2,5))=min(dist(3,2),dist(6,2),dist(3,5),dist(6,5))=min(0.13,0.25,0.28,0.39)=0.15
对于全链聚类,与单链的区别就是每次依然是选取两个最近的点形成簇,计算邻近度的时候是比较各个点与簇之间的最长链的最小值:
dist((3,6),(4))=max(dist(3,4),dist(6,4))=max(0.15,0.22)=0.22
dist((3,6),(2,5))=max(dist(3,2),dist(6,2),dist(3,5),dist(6,5))=max(0.15,0.25,0.28,0.39)=0.39
dist((3,6),(1))=max(dist(3,1),dist(6,1))=max(0.22,0.23)=0.23
所以{3,6}与{4}合并。
对于组平均,选取两个最邻近的点形成簇,计算邻近度的时候是比较各个点(簇)与簇之间的均值的最小值。
proximity(Ci,Cj)=∑x⊆Ciy⊆Cjproximity(x,y)mi×mj
其中mi和mj是簇Ci和Cj的大小。
dist((3,6,4),(1))=(0.22+0.37+0.23)/(3×1)=0.28
dist((2,5),(1))=(0.2357+0.3421)/(2×1)=0.2889
dist((3,6,4),(2,5))=(0.15+0.28+0.25+0.39+0.20+0.29)/(3×2)=0.26
所以簇{3,6,4}和簇{2,5}合并。
层次聚类的问题
(1)层次聚类不能视为全局优化一个目标函数。这样的方法没有局部最小问题或很难选择初始点的问题。
(2)处理不同大小的聚类能力。即如何处理待合并的簇对的相对大小。有两种方法:加权,平等的对待所有簇;非加权,考虑每个簇的点数。注意:加权和非加权是对数据而言,而不是对簇。即,平等的对待不同大小的簇意味着赋予不同簇中的点不同的权值,而考虑簇的大小则赋予不同簇中的点相同的权值。一般地,非加权的方法更可取,除非有理由相信个体点具有不同的权值:例如,或许对象类非均匀地抽样。
(3)合并决策是最终的。对于合并两个簇,凝聚层次算法倾向于作出好的局部决策,因为它们可以使用所有点的逐对相似度信息。然而,一旦作出合并两个簇的决策,以后就不能撤销。
基于密度的聚类算法:DBSCAN
此算法假设聚类结构能够通过样本分布的紧密程度确定。通常情况下,密度聚类算法从样本密度的角度来考察样本间的可连接性,并基于可连接性不断扩展聚类簇以获得最终聚类结果。
这里需要介绍几个重要的概念:
ϵ-邻域:对xj∈D,其ϵ-邻域包含数据集D中与xj的距离不大于ϵ的样本。
核心对象:若xj的ϵ-邻域至少包含MinPts个样本,则xj是一个核心对象。
密度直达:若xj位于xi的ϵ-邻域中,且xi是核心对象,则称xj由xi密度直达。xj可能是也可能不是核心对象。
密度可达:对xi与xj,若存在样本序列p1,p2,...,pn,其中p1=xi,pn=xj,且pi+1由pi密度直达,则称xj由xi密度可达。这里除了xj其余肯定是核心对象,而xj可能是可能也不是。
密度相连:对xi与xj,若存在xk使得xi与xj均由xk密度可达,则称xi与xj密度相连。xk肯定是核心对象,xi与xj则可能是可能也不是。
基于上述这些概念,DBSCAN算法将『簇』定义为:由密度可达关系导出的最大的密度相连的样本集合。
算法描述
输入:样本集D={x1,x2,...,xm},领域参数(ϵ,MinPts)
过程:
初始化核心对象集合:$\Omega = \varnothing$
for j = 1,2,...,m do确定样本$x_j$的$\epsilon$-邻域$N_{\epsilon}(x_j)$if $|N_{\epsilon}(x_j)| \geq MinPts$ then将样本$x_j$加入核心对象集合:$\Omega = \Omega \bigcup \{x_j\}$end if
end for
初始化聚类簇数:k = 0
初始化未访问样本集合:T = D
while $\Omega \neq \varnothing$ do记录当前未访问样本集合:$T_{old} = T$随机选取一个核心对象$o \in \Omega$,初始化队列Q = <o>T = T \ {o}while $Q \neq \varnothing$ do取出队列Q中首个样本qif $|N_{\epsilon}(q)| \geq MinPts$ then令$\Delta = N_{\epsilon}(q) \bigcap T$ //取出其中还没有被访问的点将$\Delta$中的样本加入队列QT = T \ $\Delta$end ifend whilek = k + 1,生成聚类簇$C_k = T_{old} \ T$$\Omega = \Omega \ C_k$
end while
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
输出:簇划分C={C1,C2,...,Ck}
算法优缺点
优点:
- 与k-means算法相比,DBSCAN不需要指定簇的具体数目。
- DBSCAN能够形成任意形状的簇。
- DBSCAN能够对噪声进行过滤,没有属于任何簇的样本点被认为是噪声。
缺点:
- DBSCAN不能很好地处理高维数据,在计算密度时的计算量很大。
- DBSCAN不很好地反应数据集的密度变化。
写在最后
该文档的总结一开始是由刘金凤师姐完成的,之后我又在其中增加了一部分内容,部分内容出自《机器学习》(周志华)。
k-means及变种相关推荐
- OpenCV的k - means聚类 -对图片进行颜色量化
OpenCV的k - means聚类 目标 学习使用cv2.kmeans()数据聚类函数OpenCV 理解参数 输入参数 样品:它应该的np.float32数据类型,每个特性应该被放在一个单独的列. ...
- OpenCV官方文档 理解k - means聚类
理解k - means聚类 目标 在这一章中,我们将了解k - means聚类的概念,它是如何工作等. 理论 我们将这个处理是常用的一个例子. t恤尺寸问题 考虑一个公司要发布一个新模型的t恤. 显然 ...
- kmeans改进 matlab,基于距离函数的改进k―means 算法
摘要:聚类算法在自然科学和和社会科学中都有很普遍的应用,而K-means算法是聚类算法中经典的划分方法之一.但如果数据集内相邻的簇之间离散度相差较大,或者是属性分布区间相差较大,则算法的聚类效果十分有 ...
- 文献记录(part89)--I-k-means-+:An iterative clustering algorithm based on an enhanced k -means
学习笔记,仅供参考,有错必究 关键词:k均值:解决方案改进:准确的k均值:迭代改进 I-k-means-+:An iterative clustering algorithm based on an ...
- K means 图片压缩
k-means的基本原理较为清晰,这里不多赘述,本次博客主要通过基础的k means算法进行图像的压缩处理. 原理分析 在彩色图像中,每个像素的大小为3字节(RGB),可以表示的颜色总数为256 * ...
- 为了联盟还是为了部落 | K means
1. 问题 人类有个很有趣的现象,一群人在一起,过一段时间就会自发的形成一个个的小团体.好像我们很擅长寻找和自己气质接近的同类.其实不只是人类,数据也有类似情况,这就是聚类(Clustering)的意 ...
- k均值聚类算法(K Means)及其实战案例
算法说明 K均值聚类算法其实就是根据距离来看属性,近朱者赤近墨者黑.其中K表示要聚类的数量,就是说样本要被划分成几个类别.而均值则是因为需要求得每个类别的中心点,比如一维样本的中心点一般就是求这些样本 ...
- k means聚类算法_一文读懂K-means聚类算法
1.引言 什么是聚类?我们通常说,机器学习任务可以分为两类,一类是监督学习,一类是无监督学习.监督学习:训练集有明确标签,监督学习就是寻找问题(又称输入.特征.自变量)与标签(又称输出.目标.因变量) ...
- simple k means
//选择初始的k个质点 for (int j = initInstances.numInstances() - 1; j >= 0; j--) { instIndex = RandomO.nex ...
- k means聚类算法_K-Means 聚类算法 20210108
说到聚类,应先理解聚类和分类的区别 聚类和分类最大的不同在于:分类的目标是事先已知的,而聚类则不一样,聚类事先不知道目标变量是什么,类别没有像分类那样被预先定义出来. K-Means 聚类算法有很多种 ...
最新文章
- python官网怎么下载安装-Python怎么下载安装
- VR是一场“大骗局”, 另一种声音
- 【重构】重构概要--六大重构模块
- 云上高并发系统改造最佳实践
- LVM---逻辑盘卷管理
- 如何利用ide进行跟踪调试_使用调试器进行事后跟踪
- 程序员真的只能干到35岁?——我的35岁危机度过之道!
- java 隐藏任务栏,在Java中隐藏Windows任务栏?
- python时间处理,datetime中的strftime/strptime
- JDK9的32位版本下载
- R语言使用table1包绘制(生成)三线表、使用单变量分列构建三线表、编写自定义三线表结构(将因子变量细粒度化重新构建三线图)
- secureCRT快捷粘贴操作
- 【报告分享】 2020中国女性梦幻职业白皮书-COSMO数字100 (附下载)
- MySQL||SQL_ERROR_INFO: “You can‘t specify target table ‘titles_test‘ for update in FROM clause“
- 修饰数码相机图像以便用于 CMYK 打印作业
- 代理ARP的作用和原理
- DeforGAN:用GAN实现星际争霸开全图外挂!
- CSS绘制气泡对话框样式(有边框)
- iOS开发中那些容易被我们忽略的代码,常用代码集合
- 2016百度之星总结帖
热门文章
- 前缀,中缀,后缀表达式求值
- PHP是4个进程还是五个,PHP多进程(4) :内部多进程
- mysql的面试2_mysql数据库面试题(2)
- avue-crud 使用_创建和使用CRUD存储过程
- Visual Studio Code(VS Code)与Git Source Control集成
- NODE安装N管理出错
- python3.6 与MYSQL的安装与连接
- underscorejs-min学习
- JSon_零基础_005_将po(bean)对象转换为JSon格式的对象字符串,返回给界面
- CF 55D Beautiful numbers 数位DP