http://www.cnblogs.com/wentingtu/archive/2012/01/04/2311533.html
基本工作原理
给定要聚类的N的对象以及N*N的距离矩阵(或者是相似性矩阵), 层次式聚类方法的基本步骤(参看S.C. Johnson in 1967)如下:
1. 将每个对象归为一类, 共得到N类, 每类仅包含一个对象. 类与类之间的距离就是它们所包含的对象之间的距离.
2. 找到最接近的两个类并合并成一类, 于是总的类数少了一个.
3. 重新计算新的类与所有旧类之间的距离.
4. 重复第2步和第3步, 直到最后合并成一个类为止(此类包含了N个对象).
根据步骤3的不同, 可将层次式聚类方法分为几类: single-linkage, complete-linkage 以及 average-linkage 聚类方法等.
single-linkage 聚类法(也称 connectedness 或 minimum 方法):
类间距离等于两类对象之间的最小距离,若用相似度衡量,则是各类中的任一对象与另一类中任一对象的最大相似度。
complete-linkage 聚类法 (也称 diameter 或 maximum 方法):
组间距离等于两组对象之间的最大距离。
average-linkage 聚类法:
组间距离等于两组对象之间的平均距离。
average-link 聚类的一个变种是R. D'Andrade (1978) 的UCLUS方法, 它使用的是median距离, 在受异常数据对象的影响方面, 它要比平均距离表现更佳一些.
这种层次聚类称为“凝聚"法,由于它迭代合并所有分类。也有一种“划分”层次聚类法,与“凝聚”相反,它先将所有对象放在同一类中,并不断划分成更小的类,划分法一般很少使用。
http://www.analytictech.com/networks/hiclus.htm http://home.dei.polimi.it/matteucc/Clustering/tutorial_html/hierarchical.html 这两个网页特别值得一看。讲的非常好。这些天研究了一下层次聚类,偶尔发现了这个网址。下面是其他网页的一些关于层次聚类的内容。参考一下 层次聚类方法是不可逆的,也就是说,当通过凝聚式的方法将两组合并后,无法通过分裂式的办法再将其分离到之前的状态,反之亦然。另外,层次聚类过程中调查者必须决定聚类在什么时候停止,以得到某个数量的分类。最后,必须记住,在不必要的情况下应该小心使用层次聚类方法。最好用于有潜在层次结构的数据上。 凝聚式方法是层次聚类中被广泛使用的方法。过程中,会产生一系列的分划:最初的是n个单成员的类,最后的划分是一个包含全部个体的单个类。凝聚式聚类有很多方法,但基本的操作是相似的,在每一步中,将距离最近的类或者个体融合成一个类。方法之间的差异只是由不同的个体和组之间,或组与组之间的距离的计算方法而带来的。下面介绍一些常用的方法。 单连锁(single linkage),又称最近邻(nearest neighbour)方法。这个方法使用数据的相似度矩阵或距离矩阵,定义类间距离为两类之间数据的最小距离。这个方法不考虑类结构。可能产生散乱的分类,特别是在大数据集的情况下。因为它可以产生chaining现象,当两类之间出现中间点的时候,这两类很有可能会被这个方法合成一类。单连锁也可以用于分裂式聚类,用来分开最近邻距离最远的两组。
全连锁(complete linkage),又称最远邻(furthest neightbour)方法。同样从相似度矩阵或距离矩阵出发,但定义距离为两类之间数据的最大距离。同样不考虑到类的结构。倾向于找到一些紧凑的分类。 (组)平均连锁(group average linkage),又称为 UPGMA(Unweighted Pair-Group Methodusing the Average approach)。跟前两个方法一样,从相似度矩阵或距离矩阵出发,但定义距离为类间数据两两距离的平均值。这个方法倾向于合并差异小的两个类。(距离)介于单连锁和全连锁之间。它考虑到了类的结构,产生的分类具有相对的鲁棒性。
Ward′s method,又称离差平方和法(error sum of squares criterion)。这个方法倾向于在每一步使组内的离差平方和的增量最小。所谓的离差平方和定义为
E=sum_{m=1}^{g} E_{m} 其他的方法包括,加权的平均值连锁(WPGMA),相似于平均值连锁,但是在计算类间距的时候给距离加上了相当于类中成员个数倒数的权重。平方和法(sum of squares)是类似于Ward′s method的方法,但是它基于每个类的平方和而不是聚合的类的平方和的增值。
Lance和William给出了一个灵活的方法,定义了一个递归公式。公式中的参数变化对应前面常间的那些方法。这个公式给出类k和由类i类j合成的类(ij)之间的距离为: d_{k(ij)}=alpha_{i}d_{ki}+alpha_{j}d_{kj}+ eta*d_{ij}+gamma|d_{ki}-d_{kj}|
经验研究表明,当数据中潜在的类的成员数相似时,Ward′s method表现良好,但在成员数不同时表现不好,此时质心法或全连锁可以给出满意的结果。在聚类的稳定性方面,全连锁要强于单连锁,后者对数据中出现例外时的敏感度较高。在应用到实际问题上时,质心法和中值连锁由于产生的分类不符合层次体系所以被抛弃,而Ward′s method,全连锁,和平均值连锁值得推荐。没有一种方法是特别出色的,且这些方法都会给出不同的分类结果。有两点得记住,单连锁拥有很好的数学性质,易于编程,但是结果不佳;Ward′s method效果不错但是会产生不必要的球形的类。
分裂式方法跟凝聚式方法的方向相反,从一个整类出发,一步一步细化。由于每一步时对一个k元素的类,需要考虑2^{k}-1种分划情况,所以运算量非常大,而显得不实用。但是对于二进制数据来说,一些简化方法使得分裂式方法变得可行。比如单元分裂方法(monothetic divisive methods)在每一步基于一个变量进行划分,而多元方法(polythetic methods)则使用全部的变量。分裂式方法的有点在于研究者可以把注意力集中在数据的结构上面。
C=pnlog{n}-sum_{k=1}^{p}[f_klog{f_k}-(n-f_k)log(n-f_k)] 另外的标准则是变量之间的关联性。选择关联性最大的那个变量进行划分。关联性的计算是这样的:对于两个变量V_i和V_j,计同时为1时的频度为a,同时为零时为d,i为1而j为0时为c,i为0而j为1时为b,可以通过P68公式4.6-4.10来计算。单元方法有以下好处:1,对于新的成员容易聚类;2.可以解决数据缺失的问题,比如用关联性最高的那个变量来代替;3.每一步分类基于哪些变量都是可见的。但是缺点是如果数据中有不常见的变量,可能会使该数据归到错误的类中。
应用层次聚类方法时,需要考虑到以下几点:1,聚类过程的图像化表示;2 ,树状图的比较;3,方法的数学性质;4,分划的选择;5,计算算法。下面将分别讨论这几点。
1,树状图和其他树图(如无根树)。在树状图里,节点代表一个类,而茎长 (或高度)则代表(一般是两个)合并的类之间的距离。如果试图在树图中表现聚类的顺序,可以不需要将茎延伸至零高度线。茎上没有表明其他数学性质的树又称为无权或有序树。节点上的名字称为标记(label),内节点一般不标。用来代表内节点的类成员称为标本(exemplar),或中心点(centrotype)。通常定义这个成员为类成员中拥有最大类内相似性(或最小的类内相异性)。Medoid是一种特别的例子,它定义为拥有最小类内绝对值距离的成员。要记住的是因为树状图可以有2^{n-1}种表示,如何优化树状图的样子是个需要考虑的问题。
2,树图间的比较和衡量其失真度。常常用来做树图比对或树图与邻近度矩阵比对的方法是,cophenetic correlation和Goodman and Kruskal′s gamma 。
前者利用cophenetic矩阵,矩阵元是两个样本被归为一类时,所在节点在树图中的高度。cophenetic correlation是对应的cophenetic矩阵之间的积乘相关性(相关系数--R:cor)。一般可以将矩阵展成向量再计算。
(S_{+}-S_{-})/(S_{+}-S_{-})
3,层级法的数学性质。首先是ultrametic性质,比较简单的描述是,对于任意三个点间的三个距离,其中最大的两个值相等。不符合这个性质的层级方法会在树状图里出现翻转。翻转并不一定带来坏处,比如调查者的目的不是完整的层级结构而是某个特定的划分,而且它可以提示那个地方没有清晰的结构。质心法和中值法都会产生翻转。这会给层级聚类的结果的解释带来麻烦。空间保守性质,单连锁会产生空间压缩(space contraction),全连锁会产生空间膨胀( space dilation),而像平均值连锁则符合空间保守(space conservation)。空间保守性质简言之就是说,到合并的类的距离介于到原先各组分的距离之间。 Fisher和Van Ness提出了一些容许性性质。比如(k-group)well-structured admissibility或称clump admissibility,是跟空间保守性及ultrametric性质相关的。Mirkin定义它为,存在一种分类,其中所有的类内距离都小于所有的类间距离。其他的性质包括,凸容许性(convex admissibility),是说如果样本可以在欧几里得空间里表示,则各个分划的凸包没有交集;点比例容许性(point proportional admissibility),是说复制样本点不会改变分划的边界; 单调容许性(monotone admissibility),指对邻近度矩阵做单调变换不会改变聚类。各种层级聚类方法的性质见P63 Table4.2。 4,分划的选择。如果调查者关心的不是层级结构,而是想得到一个分类,那么就必须决定分类的数量。非正式的方法是从树状图入手,在某个特定的“高度 ”切割树状图得到分组。而正式的方法包括下一章讨论的优化方法,和专门基于层级聚类性质的方法。后者包括: upper tail rule,基于树状图中不同融合级别的相对大小,具体的说,就是在选择第一个满足下面这个条件的分组j: 5,层级算法。层级算法不同于层级方法,对于一种层级聚类方法,可以使用多种算法来得到相同的结果。一种全局算法是直接优化算法(direct optimizing algorithms),比如吝啬树(parsimonious tree),找一个层级树中级数最少的。在邻近度矩阵中有数据缺失时这种算法比较有用。另外像前面提到的Lance和 Williams的递归公式也可以用于算法,但其计算复杂度是n^2log(n),在它上面作的改进像最小支撑树拥有n^2的计算时间。其他一些可以使用最近邻方法凝聚的聚类方法都可以相当于大约n^2。Zahn发展了一些基于最小支撑树(minimum spanning tree)的图论聚类算法,这种方法适用于单连锁的情况。其他一些在计算时需要考虑的问题包括:非特异性,在单连锁和其他一些聚类方法中当非特异的情况出现时,比如有两对分组之间的距离都最小时,决定选择谁进行合并;如何引入案例权重(case weight),比如在前面点比例容许性中提到的关于数据集中出现重复样本时的解决方法,举例来说,在网页关键词的自动监控上就会引入案例权重(词的出现次数)
每个聚类都是由N条事务聚合而成,事务是一个K元向量TD = {T1,T2,……,Tn}组成。 CF是一个结构,其中保存了三组信息:{N,S,SS},其中,N保存了本聚类是由多少条事务聚合而成;S是向量,是本聚类中所有事务的向量和,SS是一个数,是本类中所有事务各个分量的平方和。则:CF1 + CF2 = {N1+N2,S1+S2,SS1+SS2}。当每个CF中只有一条事务时,这个性质也成立,因此可以把一条事务当成一个CF,则此CF中{N=1,S={TD},SS = TD2}(向量平方的意思是指每个分量平方相加)。 两个CF的距离定义为其中心向量之间的欧式距离,其中核心向量v0= S/N。 一个CF的半径R定义为Sqrt(CF中所有向量到v0的距离的平方和 / n),推导得:R = Sqrt( (N×SS – S2) / N2)。 一棵CF树是一棵B叉树,其中B规定了此树每个非叶节点的子节点的最大数目。每个节点存有(1~B)个CF结构,非叶节点中对应于每个CF结构,还有指向子节点的指针, 父节点CF = ∑ (所有子节点的CF)。 CF树中,B约束指定最多的叉数,T约束指定CF中R半径的最大值,M约束指定叶节点CF最大个数。 聚类过程:依次将正常事务插入树中,当CF插入时,首先找到离自己最近的CF,如果不是叶节点,则找此CF对应的子结点,递归下降,到达叶节点时,如果离自己最近的CF的距离小于T,且本CF与当前CF合并后R<=T,则合并,否则作为新的叶节点插入,插入后如果违反了B约束,则此叶节点分裂。 分裂过程:找到CF1、CF2,满足Distance(CF1, CF2)>任何其它Distance,则生成两个节点,分别将CF1、CF2插入,对于其它所有CF,如果离CF1近则插入CF1所属节点,否则插入CF2所属节点,删除原节点,插入新生成的两个节点。由于是递归过程,因此每插入一个节点都会自动检查插入路径上的所有节点是否满足约束并分裂。 当叶节点中CF总数>M时,放宽一点T约束,重建CF树,重建的过程只是清空CF树后在新的T的约束下将原树的CF叶节点依次插入一遍,如果仍然违反了M约束,则此过程继续,直到满足为止。 预测过程:新来一个CF,则递归查找,找到离自己最近的一个CF,如果两个CF距离 一个层次的聚类方法将数据对象组成一棵聚类的树。根据层次分解是自底向上的还是自顶向下形成的,层次的聚类方法可以进一步分为凝聚的(agglomerative)和分裂的(divisive)层次聚类。 (1)凝聚的层次聚类:这种自底向上的策略首先将每个对象作为单独的一个簇,然后和并这些原子簇为越来越大的簇,直到所有的对像都在一个簇中,或者达到某个终止条件。 (2)分裂的层次聚类:这种自顶向下的策略与凝聚的层次聚类相反,它首先将所有的对象置于一个簇中。然后逐渐细分为越来越小的簇,直到每个对象在单独的一个簇中,或者达到一个终止条件,例如打到了某个希望的簇数目后者两个簇之间的距离超过了某个阀值。 例2 图2-3描述了一个凝聚的层次聚类方法AGNES(Agglomerative NESting)和一个分裂的层次聚类方法DIANA(Divisive Analysis)在一个包含五个对象的数据集合{a,b,c,d,e}上的处理过程。最初,AGNES将每个对象作为一个簇,然后这些簇根据某些准则一步步合并。例如,如果簇C1中的一个对象和簇 C2中的一个对象之间的距离使所有属于不同簇的对象间欧式距离最小的,C1和C2可能被合并。其每个簇可以被簇中所有对象代表,两个簇间的相似度由两个不同簇中距离最近的数据点对的相似度来确定。聚类的合并过程反复进行直到所有对象最终合并为一个簇。 在DIANA方法处理过程中,所有的对象都放在一个簇中。根据一些原则(如簇中最邻近的对象的最大欧氏距离),将该簇分裂。簇的分裂过程反复进行,直到最终每个新的簇只包含一个对象。 层次聚类方法尽管简单,但经常会遇到合并或分裂点选择的困难。这样的选择是非常关键的,因为一旦一组对象(合并或分裂)完成,它就不能被撤销,下一步的处理将在新完成的簇上进行。这个严格规定是有用的,由于不用担心组合数目的不同选择,计算代价会比较小。但是,已做的处理不能被撤消,聚类之间也不能交换对象。如果在某一步没有很好的选择合并或分裂的决定,可能会导致低质量的聚类结果。而且,这种聚类不具有很好的可伸缩性。因为合并或分裂的决定需要检查和估算大量的对象或结果。 改进层次方法的聚类质量的一个有希望的方向是将层次聚类和其他聚类技术集成。有两种方法可以改进层次聚类的结果: (i) 在每层划分中,仔细分析对象间的“联接”,例如CURE和Chameleon中的做法。 (ii)综合层次凝聚和迭代的重定位方法。首先用自底向上的层次算法,然后用迭代的重定位来改进结果。例如BIRCH中的方法。 1. 初始时共有N个类,每个类由一个对象类成。令顺序号m = 0, L(m) = 0. |
MATLAB提供了两种方法进行聚类分析:
一种是利用 clusterdata函数对样本数据进行一次聚类,其缺点为可供用户选择的面较窄,不能更改距离的计算方法;
另一种是分步聚类:(1)找到数据集合中变量两两之间的相似性和非相似性,用pdist函数计算变量之间的距离;(2)用 linkage函数定义变量之间的连接;(3)用 cophenetic函数评价聚类信息;(4)用cluster函数创建聚类。
1.Matlab中相关函数介绍
1.1 pdist函数
调用格式:Y=pdist(X,’metric’)
说明:用 ‘metric’指定的方法计算 X 数据矩阵中对象之间的距离。’
X:一个m×n的矩阵,它是由m个对象组成的数据集,每个对象的大小为n。
metric’取值如下:
‘euclidean’:欧氏距离(默认);‘seuclidean’:标准化欧氏距离;
‘mahalanobis’:马氏距离;‘cityblock’:布洛克距离;
‘minkowski’:明可夫斯基距离;‘cosine’:
‘correlation’: ‘hamming’:
‘jaccard’: ‘chebychev’:Chebychev距离。
1.2 squareform函数
调用格式:Z=squareform(Y,..)
说明: 强制将距离矩阵从上三角形式转化为方阵形式,或从方阵形式转化为上三角形式。
1.3 linkage函数
调用格式:Z=linkage(Y,’method’)
说 明:用‘method’参数指定的算法计算系统聚类树。
Y:pdist函数返回的距离向量;
method:可取值如下:
‘single’:最短距离法(默认); ‘complete’:最长距离法;
‘average’:未加权平均距离法; ‘weighted’: 加权平均法;
‘centroid’:质心距离法; ‘median’:加权质心距离法;
‘ward’:内平方距离法(最小方差算法)
返回:Z为一个包含聚类树信息的(m-1)×3的矩阵。
1.4 dendrogram函数
调用格式:[H,T,…]=dendrogram(Z,p,…)
说明:生成只有顶部p个节点的冰柱图(谱系图)。
1.5 cophenet函数
调用格式:c=cophenetic(Z,Y)
说明:利用pdist函数生成的Y和linkage函数生成的Z计算cophenet相关系数。
1.6 cluster 函数
调用格式:T=cluster(Z,…)
说明:根据linkage函数的输出Z 创建分类。
1.7 clusterdata函数
调用格式:T=clusterdata(X,…)
说明:根据数据创建分类。
T=clusterdata(X,cutoff)与下面的一组命令等价:
Y=pdist(X,’euclid’);
Z=linkage(Y,’single’);
T=cluster(Z,cutoff);