转自: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}

算法优缺点

优点:

  1. 与k-means算法相比,DBSCAN不需要指定簇的具体数目。   
  2. DBSCAN能够形成任意形状的簇。  
  3. DBSCAN能够对噪声进行过滤,没有属于任何簇的样本点被认为是噪声。

缺点:

  1. DBSCAN不能很好地处理高维数据,在计算密度时的计算量很大。
  2. DBSCAN不很好地反应数据集的密度变化。

写在最后

该文档的总结一开始是由刘金凤师姐完成的,之后我又在其中增加了一部分内容,部分内容出自《机器学习》(周志华)。

k-means及变种相关推荐

  1. OpenCV的k - means聚类 -对图片进行颜色量化

    OpenCV的k - means聚类 目标 学习使用cv2.kmeans()数据聚类函数OpenCV 理解参数 输入参数 样品:它应该的np.float32数据类型,每个特性应该被放在一个单独的列. ...

  2. OpenCV官方文档 理解k - means聚类

    理解k - means聚类 目标 在这一章中,我们将了解k - means聚类的概念,它是如何工作等. 理论 我们将这个处理是常用的一个例子. t恤尺寸问题 考虑一个公司要发布一个新模型的t恤. 显然 ...

  3. kmeans改进 matlab,基于距离函数的改进k―means 算法

    摘要:聚类算法在自然科学和和社会科学中都有很普遍的应用,而K-means算法是聚类算法中经典的划分方法之一.但如果数据集内相邻的簇之间离散度相差较大,或者是属性分布区间相差较大,则算法的聚类效果十分有 ...

  4. 文献记录(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 ...

  5. K means 图片压缩

    k-means的基本原理较为清晰,这里不多赘述,本次博客主要通过基础的k means算法进行图像的压缩处理. 原理分析 在彩色图像中,每个像素的大小为3字节(RGB),可以表示的颜色总数为256 * ...

  6. 为了联盟还是为了部落 | K means

    1. 问题 人类有个很有趣的现象,一群人在一起,过一段时间就会自发的形成一个个的小团体.好像我们很擅长寻找和自己气质接近的同类.其实不只是人类,数据也有类似情况,这就是聚类(Clustering)的意 ...

  7. k均值聚类算法(K Means)及其实战案例

    算法说明 K均值聚类算法其实就是根据距离来看属性,近朱者赤近墨者黑.其中K表示要聚类的数量,就是说样本要被划分成几个类别.而均值则是因为需要求得每个类别的中心点,比如一维样本的中心点一般就是求这些样本 ...

  8. k means聚类算法_一文读懂K-means聚类算法

    1.引言 什么是聚类?我们通常说,机器学习任务可以分为两类,一类是监督学习,一类是无监督学习.监督学习:训练集有明确标签,监督学习就是寻找问题(又称输入.特征.自变量)与标签(又称输出.目标.因变量) ...

  9. simple k means

    //选择初始的k个质点 for (int j = initInstances.numInstances() - 1; j >= 0; j--) { instIndex = RandomO.nex ...

  10. k means聚类算法_K-Means 聚类算法 20210108

    说到聚类,应先理解聚类和分类的区别 聚类和分类最大的不同在于:分类的目标是事先已知的,而聚类则不一样,聚类事先不知道目标变量是什么,类别没有像分类那样被预先定义出来. K-Means 聚类算法有很多种 ...

最新文章

  1. python官网怎么下载安装-Python怎么下载安装
  2. VR是一场“大骗局”, 另一种声音
  3. 【重构】重构概要--六大重构模块
  4. 云上高并发系统改造最佳实践
  5. LVM---逻辑盘卷管理
  6. 如何利用ide进行跟踪调试_使用调试器进行事后跟踪
  7. 程序员真的只能干到35岁?——我的35岁危机度过之道!
  8. java 隐藏任务栏,在Java中隐藏Windows任务栏?
  9. python时间处理,datetime中的strftime/strptime
  10. JDK9的32位版本下载
  11. R语言使用table1包绘制(生成)三线表、使用单变量分列构建三线表、编写自定义三线表结构(将因子变量细粒度化重新构建三线图)
  12. secureCRT快捷粘贴操作
  13. 【报告分享】 2020中国女性梦幻职业白皮书-COSMO数字100 (附下载)
  14. MySQL||SQL_ERROR_INFO: “You can‘t specify target table ‘titles_test‘ for update in FROM clause“
  15. 修饰数码相机图像以便用于 CMYK 打印作业
  16. 代理ARP的作用和原理
  17. DeforGAN:用GAN实现星际争霸开全图外挂!
  18. CSS绘制气泡对话框样式(有边框)
  19. iOS开发中那些容易被我们忽略的代码,常用代码集合
  20. 2016百度之星总结帖

热门文章

  1. 前缀,中缀,后缀表达式求值
  2. PHP是4个进程还是五个,PHP多进程(4) :内部多进程
  3. mysql的面试2_mysql数据库面试题(2)
  4. avue-crud 使用_创建和使用CRUD存储过程
  5. Visual Studio Code(VS Code)与Git Source Control集成
  6. NODE安装N管理出错
  7. python3.6 与MYSQL的安装与连接
  8. underscorejs-min学习
  9. JSon_零基础_005_将po(bean)对象转换为JSon格式的对象字符串,返回给界面
  10. CF 55D Beautiful numbers 数位DP