机器学习算法(十二):聚类(2)层次聚类 Hierarchical Clustering

目录

1 层次聚类

1.1 层次聚类的原理

1.2 两个组合数据点间的距离:

2 自底向上的合并算法

2.1 AGNES算法 (AGglomerative NESting)

2.1.1 原理

2.1.2 实例

2.1.3 优缺点

2.2 BIRCH(Balanced Iterative Reducing and Clustering using Hierarchies)

2.2.1 聚类特征CF

2.2.2 聚类特征树CF Tree的生成 

2.2.3 BIRCH算法

2.2.4 BIRCH算法小结 

2.2.5 python实现

2.3 CURE(Clustering Using Representative)算法

2.3.1 CURE算法简介

2.3.2 CURE算法流程

 2.3.3 CURE算法优点

2.4 Chameleon变色龙算法

 3 自顶向下的分裂算法

3.1 Hierarchical K-means算法

3.2(DIANA算法 (DIvisive ANALysis))

4 层次聚类的优缺点

1 层次聚类

1.1 层次聚类的原理

        层次聚类(Hierarchical Clustering)是聚类算法的一种,通过计算不同类别数据点间的相似度来创建一棵有层次的嵌套聚类树。在聚类树中,不同类别的原始数据点是树的最低层,树的顶层是一个聚类的根节点。创建聚类树有自下而上合并和自上而下分裂两种方法。

        作为一家公司的人力资源部经理,你可以把所有的雇员组织成较大的簇,如主管、经理和职员;然后你可以进一步划分为较小的簇,例如,职员簇可以进一步划分为子簇:高级职员,一般职员和实习人员。所有的这些簇形成了层次结构,可以很容易地对各层次上的数据进行汇总或者特征化。

        如何划分才是合适的呢?

        论数据集应该聚类成多少个簇,通常是在讨论我们在什么尺度上关注这个数据集。层次聚类算法相比划分聚类算法的优点之一是可以在不同的尺度上(层次)展示数据集的聚类情况。

        基于层次的聚类算法(Hierarchical Clustering)可以是凝聚的(Agglomerative)或者分裂的(Divisive),取决于层次的划分是“自底向上”还是“自顶向下”。

  • 自顶向下: 它把所有对象至于一个簇中开始,该簇是层次结构的根。然后,它把根上的簇划分为多个较小的子簇,并且递归地把这次簇划分成更小的簇,直到满足终止条件。常见的自顶向下的算法有K-means层次聚类算法。
  • 自底向上:把数据集中的每个对象最为一个簇开始,迭代地把簇合并成为更大的簇,直到最终形成一个大簇,或者满足某个终止条件。基于自底向上算法有凝聚算法BIRCH算法CURE算法变色龙算法等。

        Hierarchical methods中比较新的算法有BIRCH(Balanced Iterative Reducingand Clustering Using Hierarchies利用层次方法的平衡迭代规约和聚类)主要是在数据量很大的时候使用,而且数据类型是numerical。首先利用树的结构对对象集进行划分,然后再利用其它聚类方法对这些聚类进行优化;ROCK(A Hierarchical ClusteringAlgorithm for Categorical Attributes)主要用在categorical的数据类型上;Chameleon(A Hierarchical Clustering AlgorithmUsing Dynamic Modeling)里用到的linkage是kNN(k-nearest-neighbor)算法,并以此构建一个graph,Chameleon的聚类效果被认为非常强大,比BIRCH好用,但运算复杂度很高,O(n^2)。

1.2 两个组合数据点间的距离:

         计算两个组合数据点间距离的方法有三种,分别为Single LinkageComplete LinkageAverage Linkage。在开始计算之前,我们先来介绍下这三种计算方法以及各自的优缺点。

  • Single Linkage:方法是将两个组合数据点中距离最近的两个数据点间的距离作为这两个组合数据点的距离。这种方法容易受到极端值的影响,容易产生长条状的簇。两个很相似的组合数据点可能由于其中的某个极端的数据点距离较近而组合在一起。

  • Complete Linkage:Complete Linkage的计算方法与Single Linkage相反,将两个组合数据点中距离最远的两个数据点间的距离作为这两个组合数据点的距离。Complete Linkage的问题也与Single Linkage相反,采用该距离计算方式得到的聚类比较紧凑。两个不相似的组合数据点可能由于其中的极端值距离较远而无法组合在一起(?)

  • Average Linkage:Average Linkage的计算方法是计算两个组合数据点中的每个数据点与其他所有数据点的距离。将所有距离的均值作为两个组合数据点间的距离。这种方法计算量比较大,但结果比前两种方法更合理,可以有效地排除噪点的影响。

       最常用的,就是average-linkage,即计算两个cluster各自数据点的两两距离的平均值。类似的还有single-linkage/complete-linkage,选择两个cluster中距离最短/最长的一对数据点的距离作为类的距离。个人经验complete-linkage基本没用 ,single-linkage通过关注局域连接,可以得到一些形状奇特的cluster,但是因为太过极 端,所以效果也不是太好。

2 自底向上的合并算法

2.1 AGNES算法 (AGglomerative NESting)

2.1.1 原理

        层次聚类的合并算法通过计算两类数据点间的相似性,对所有数据点中最为相似的两个数据点进行组合,并反复迭代这一过程。简单的说层次聚类的合并算法是通过计算每一个类别的数据点与所有数据点之间的距离来确定它们之间的相似性,距离越小,相似度越高。并将距离最近的两个数据点或类别进行组合,生成聚类树。

         

        相似度的计算:

         层次聚类可以使用欧式距离来计算不同类别数据点间的距离(相似度)。

              

2.1.2 实例

        数据点如下:

               

        分别计算欧式距离值(矩阵):

             

        将数据点B与数据点C进行组合后,重新计算各类别数据点间的距离矩阵。数据点间的距离计算方式与之前的方法一样。这里需要说明的是组合数据点(B,C)其他数据点间的计算方法。当我们计算(B,C)到A的距离时,需要分别计算B到AC到A的距离均值。

              

        经过计算数据点D到数据点E的距离在所有的距离值中最小,为1.20。这表示在当前的所有数据点中(包含组合数据点),D和E的相似度最高。因此我们将数据点D和数据点E进行组合。并再次计算其他数据点间的距离,如下表所示。

            

        后面的工作就是不断的重复计算数据点与数据点,数据点与组合数据点间的距离。这个步骤应该由程序来完成。这里由于数据量较小,我们手工计算并列出每一步的距离计算和数据点组合的结果。

        我们使用Average Linkage计算组合数据点间的距离。下面是计算组合数据点(A,F)到(B,C)的距离,这里分别计算了(A,F)和(B,C)两两间距离的均值。

           

        树状图:

          

        由上图可知,给定不同的距离,可以得到不同的分类,比如,23,则分为两类,中国和其他国家或地区;17,则可分成三类,中国单独一类,菲律宾和日本一类,其余国家或地区为一类。

2.1.3 优缺点

        Agglomerative聚类算法:

  • 优点:优点是能够根据需要在不同的尺度上展示对应的聚类结果,
  • 缺点:缺点同Hierarchical K-means算法一样,一旦两个距离相近的点被划分到不同的簇,之后也不再可能被聚类到同一个簇,即无法撤销先前步骤的工作。另外,Agglomerative性能较低,并且因为聚类层次信息需要存储在内存中,内存消耗大,不适用于大量级的数据聚类,下面介绍一种针对大数据量级的聚类算法BIRCH。

2.2 BIRCH(Balanced Iterative Reducing and Clustering using Hierarchies)

        BIRCH(Balanced Iterative Reducing and Clustering using Hierarchies)是一个综合的层次聚类算法 (平衡迭代削减聚类法)。它用到了聚类特征(Clustering Feature, CF)聚类特征树(CF Tree)两个概念,用于概括聚类描述。聚类特征树概括了聚类的有用信息,并且占用空间较元数据集合小得多,可以存放在内存中,从而可以提高算法在大型数据集合上的聚类速度及可伸缩性。

        BIRCH算法是在凝聚分裂算法之后发展起来的。它克服了凝聚聚类算法一些存在的劣势。 
        BIRCH算法比较适合于数据量大,类别数K也比较多的情况。它运行速度很快,只需要单遍扫描数据集就能进行有效的聚类。 这得益于它采用的一个特殊的树结构,CF-树。 

        该算法笼统的说,执行流程可分为两步: 

  1. BIRCH扫描数据库,建立一棵存放于内存的CF-树,它可以被看作数据的多层压缩,试图保留数据的内在聚类结构; 
  2. BIRCH采用某个选定的聚类算法对CF树的叶节点进行聚类,把稀疏的簇当作离群点删除,而把更稠密的簇合并为更大的簇。

        其中,最关键的就是CF-树的构造。可以说,只要构造好了CF-树,BIRCH算法也就完成了。因此,我们重点讲一下CF-树如何构造。

        初识聚类特征树:BIRCH算法利用了一个树结构来帮助我们快速的聚类,这个数结构类似于平衡B+树,一般将它称之为聚类特征树(Clustering Feature Tree,简称CF Tree)。这颗树的每一个节点是由若干个聚类特征(Clustering Feature,简称CF)组成。从下图我们可以看看聚类特征树是什么样子的:每个节点包括叶子节点都有若干个CF,而内部节点的CF有指向孩子节点的指针,所有的叶子节点用一个双向链表链接起来。            
         

        有了聚类特征树的概念,我们再对聚类特征树和其中节点的聚类特征CF做进一步的讲解。

2.2.1 聚类特征CF

        在聚类特征树中,一个聚类特征CF是这样定义的:每一个CF是一个三元组,可以用(N,LS,SS)表示。其中N代表了这个CF中拥有的样本点的数量,这个好理解;LS代表了这个CF中拥有的样本点各特征维度的和向量,SS代表了这个CF中拥有的样本点各特征维度的平方和。举个例子如下图,在CF Tree中的某一个节点的某一个CF中,有下面5个样本(3,4)、(2,6)、 (4,5)、 (4,7)、 (3,8)。则它对应的N=5; LS=(3+2+4+4+3,4+6+5+7+8)=(16,30);

        CF有一个很好的性质,就是满足线性关系,也就是CF1+CF2=(N1+N2,LS1+LS2,SS1+SS2)。这个性质从定义也很好理解。如果把这个性质放在CF Tree上,也就是说,在CF Tree中,对于每个父节点中的CF节点,它的(N,LS,SS)三元组的值等于这个CF节点所指向的所有子节点的三元组之和。如下图所示 。
        

        从上图中可以看出,根节点的CF1的三元组的值,可以从它指向的6个子节点(CF7 - CF12)的值相加得到。这样我们在更新CF Tree的时候,可以很高效。

2.2.2 聚类特征树CF Tree的生成 

        对于CF Tree,我们一般有几个重要参数,第一个参数是每个内部节点最大CF数B,第二个参数是每个叶子节点最大CF数L,第三个参数是针对叶子节点中某个CF中的样本点来说的,它是叶节点每个CF的最大样本半径阈值T,也就是说,在这个CF中的所有样本点一定要在半径小于T的一个超球体内。对于上图中的CF Tree,限定了B=6, L=5, 也就是说内部节点最多有6个CF,而叶子节点最多有5个CF。  

相关定义:

(1)质心,代表这个簇的中心:

          

 (2)簇半径,簇中所有点到质心的平均距离:

           

(3)簇直径,簇中所有数据点之间的平均距离:

           

        下面我们看看怎么生成CF Tree。我们先定义好CF Tree的参数: 即内部节点的最大CF数B叶子节点的最大CF数L叶节点每个CF的最大样本半径阈值T

        在最开始的时候,CF Tree是空的,没有任何样本,我们从训练集读入第一个样本点,将它放入一个新的CF三元组A,这个三元组的N=1,将这个新的CF放入根节点,此时的CF Tree如下图: 
            

        现在我们继续读入第二个样本点,我们发现这个样本点和第一个样本点A,在半径为T的超球体范围内,也就是说,他们属于一个CF,我们将第二个点也加入CF A,此时需要更新A的三元组的值。此时A的三元组中N=2。此时的CF Tree如下图:

           

        此时来了第三个节点,结果我们发现这个节点不能融入刚才前面的节点形成的超球体内,也就是说,我们需要一个新的CF三元组B,来容纳这个新的值。此时根节点有两个CF三元组A和B,此时的CF Tree如下图:   

            

当来到第四个样本点的时候,我们发现和B在半径小于T的超球体,这样更新后的CF Tree如下图: 
     

        那个什么时候CF Tree的节点需要分裂呢?假设我们现在的CF Tree 如下图, 叶子节点LN1有三个CF, LN2和LN3各有两个CF。我们的叶子节点的最大CF数L=3。此时一个新的样本点来了,我们发现它离LN1节点最近,因此开始判断它是否在sc1,sc2,sc3这3个CF对应的超球体之内,但是很不幸,它不在,因此它需要建立一个新的CF,即sc8来容纳它。问题是我们的L=3,也就是说LN1的CF个数已经达到最大值了,不能再创建新的CF了,怎么办?此时就要将LN1叶子节点一分为二了。 
          

        我们将LN1里所有CF元组中,找到两个最远的CF做这两个新叶子节点的种子CF,然后将LN1节点里所有CF sc1, sc2, sc3,以及新样本点的新元组sc8划分到两个新的叶子节点上。将LN1节点划分后的CF Tree如下图: 

           

        如果我们的内部节点的最大CF数B=3,则此时叶子节点一分为二会导致根 节点的最大CF数超了,也就是说,我们的根节点现在也要分裂,分裂的方法和叶子节点分裂一样,分裂后的CF Tree如下图:  

        有了上面这一系列的图,总结下CF Tree的插入: 

  1. 从根节点向下寻找和新样本距离最近的叶子节点和叶子节点里最近的CF节点 
  2. 如果新样本加入后,这个CF节点对应的超球体半径仍然满足小于阈值T,则更新路径上所有的CF三元组,插入结束。否则转入3
  3. 如果当前叶子节点的CF节点个数小于阈值L,则创建一个新的CF节点,放入新样本,将新的CF节点放入这个叶子节点,更新路径上所有的CF三元组,插入结束。否则转入4。 
  4. 将当前叶子节点划分为两个新叶子节点,选择旧叶子节点中所有CF元组里超球体距离最远的两个CF元组,分别作为两个新叶子节点的第一个CF节点。将其他元组和新样本元组按照距离远近原则放入对应的叶子节点。依次向上检查父节点是否也要分裂,如果需要按和叶子节点分裂方式相同。

2.2.3 BIRCH算法

        其实将所有的训练集样本建立了CF Tree,一个基本的BIRCH算法就完成了,对应的输出就是若干个CF节点,每个节点里的样本点就是一个聚类的簇。也就是说BIRCH算法的主要过程,就是建立CF Tree的过程。

        当然,真实的BIRCH算法除了建立CF Tree来聚类,其实还有一些可选的算法步骤的,现在我们就来看看 BIRCH算法的流程。

1) 将所有的样本依次读入,在内存中建立一颗CF Tree, 建立的方法参考上一节。

2)(可选)将第一步建立的CF Tree进行筛选,去除一些异常CF节点,这些节点一般里面的样本点很少。对于一些超球体距离非常近的元组进行合并。

3)(可选)利用其它的一些聚类算法比如K-Means对所有的CF元组进行聚类,得到一颗比较好的CF Tree。这一步的主要目的是消除由于样本读入顺序导致的不合理的树结构,以及一些由于节点CF个数限制导致的树结构分裂。

4)(可选)利用第三步生成的CF Tree的所有CF节点的质心,作为初始质心点,对所有的样本点按距离远近进行聚类。这样进一步减少了由于CF Tree的一些限制导致的聚类不合理的情况。

        从上面可以看出,BIRCH算法的关键就是步骤1,也就是CF Tree的生成,其他步骤都是为了优化最后的聚类结果。

2.2.4 BIRCH算法小结 

         BIRCH算法可以不用输入类别数K值,这点和K-Means,Mini Batch K-Means不同。如果不输入K值,则最后的CF元组的组数即为最终的K,否则会按照输入的K值对CF元组按距离大小进行合并。

        一般来说,BIRCH算法适用于样本量较大的情况,这点和Mini Batch K-Means类似,但是BIRCH适用于类别数比较大的情况,而Mini Batch K-Means一般用于类别数适中或者较少的时候。BIRCH除了聚类还可以额外做一些异常点检测(通常如果我们聚类后发现某些聚类簇的数据样本量比其他簇少很多,而且这个簇里数据的特征均值分布之类的值和其他簇也差异很大,这些簇里的样本点大部分时候都是异常点。数据初步按类别规约的预处理。但是如果数据特征的维度非常大,比如大于20,则BIRCH不太适合,此时Mini Batch K-Means的表现较好。

        对于调参,BIRCH要比K-Means,Mini Batch K-Means复杂,因为它需要对CF Tree的几个关键的参数进行调参,这几个参数对CF Tree的最终形式影响很大。

  最后总结下BIRCH算法的优缺点:

  BIRCH算法的主要优点有:

  1) 节约内存,所有的样本都在磁盘上,CF Tree仅仅存了CF节点和对应的指针,CF-树只存储原始数据的特征信息,并不需要存储原始数据信息,内存开销上更优;。

  2) 聚类速度快,只需要一遍扫描训练集就可以建立CF Tree,CF Tree的增删改都很快,而Agglomerative算法在每次迭代都需要遍历一遍数据。

  3) 可以识别噪音点,还可以对数据集进行初步分类的预处理

       4) 适合大规模数据集,线性效率;层次聚类算法的复杂度为 OT(n2);优化后的BIRCH算法构建聚类特征树(CF-Tree)的时间复杂度为O(n) ;

       5) 支持对流数据的聚类,BIRCH一开始并不需要所有的数据;

  BIRCH算法的主要缺点有:

  1) 由于CF Tree对每个节点的CF个数有限制,导致聚类的结果可能和真实的类别分布不同。

  2) 对高维特征的数据聚类效果不好。此时可以选择Mini Batch K-Means

  3) 如果数据集的分布簇不是类似于超球体,或者说不是凸的,则聚类效果不好。

2.2.5 python实现


from sklearn import metrics
import matplotlib.pyplot as plt
from sklearn.cluster import Birch
from sklearn.datasets._samples_generator import make_blobs


# step 1 生成数据
# make_blobs() 是 sklearn.datasets中的一个函数,主要是产生聚类数据集
X, y = make_blobs(n_samples=1000, n_features=2, centers=[[-1, -1], [0, 0], [1, 1], [2, 2]], cluster_std=[0.4, 0.3, 0.4, 0.3])
plt.scatter(X[:, 0], X[:, 1], marker="o")
plt.show()

# step 2 聚类
y_pred = Birch(n_clusters=None).fit_predict(X)
plt.scatter(X[:, 0], X[:, 1], c=y_pred)
plt.show()
print("calinski_harabasz_score: ", metrics.calinski_harabasz_score(X, y_pred))
# 对于K个聚类,Calinski-Harabaz的分数S被定义为组间离散与组内离散的比率,该分值越大说明聚类效果越好。
# python Calinski-Harabasz指数评价K-means聚类模型: https://blog.csdn.net/becatjd/article/details/105922418

# step 3 聚类,事先决定类的个数
y_pred = Birch(n_clusters=4).fit_predict(X)
plt.scatter(X[:, 0], X[:, 1], c=y_pred)
plt.show()
print("calinski_harabasz_score: ", metrics.calinski_harabasz_score(X, y_pred))

2.3 CURE(Clustering Using Representative)算法

2.3.1 CURE算法简介

        很多聚类算法只擅长处理球形或者相似大小的聚类。另外有些聚类算法对孤立点比较敏感
        CURE算法解决了上述两个问题,选择基于质心和基于代表对象之间的中间策略,即选择空间中固定数目的具有代表性的点,而不是单个中心或对象来代表一个簇。

        CURE(Clustering Using Representatives)是一种针对大型数据库的高效的聚类算法。基于划分的传统的聚类算法得到的是球状的,相等大小的聚类,对异常数据比较脆弱。CURE采用了用多个点代表一个簇的方法,可以较好的处理以上问题。并且在处理大数据量的时候采用了随机取样,分区的方法,来提高其效率,使得其可以高效的处理大量数据。

        CURE算法(使用代表点的聚类法):是一种凝聚算法(AGNES)。该算法先把每个数据点看成一类,然后再以一个特定的收缩因子向簇中心“收缩”它们,即合并距离最近的类直至类个数为所要求的个数为止。但是和AGNES算法的区别是:取消了使用所有点或用中心点+距离来表示一个类,而是从每个类中抽取固定数量、分布较好的点作为此类的代表点,并将这些代表点(一般10个)乘以一个适当的收缩因子(一般设置0.2~0.7之间),使它们更加靠近类中心点。代表点的收缩特性可以调整模型可以匹配那些非球形的场景,而且收缩因子的使用可以减少噪音对聚类的影响。

        代表点 不是原来的点,而是那些需要重新计算的点。

        针对大型数据库,CURE采用随机取样划分两种方法组合:一个随机样本首先被划分,每个划分被部分聚类。

        我们先看一下基于划分聚类算法的缺陷:

         如上图所示,基于划分的聚类算法比如Hierarchical K-means聚类算法,不能够很好地区分尺寸差距大的簇,原因是K-means算法基于“质心”加一定“半径”对数据进行划分,导致最后聚类的簇近似“圆形”。

        再看一下其他聚类算法在聚类结果上可能存在的问题:

  • (b)图使用的是基于“平均连锁”或者基于“质心”的簇间距离计算方式得到的聚类结果,可以看出,聚类结果同基于划分的聚类算法相似、最后聚类的结果呈“圆形”,不能够准确地识别条形的数据;
  • (c)图使用的是基于“单连锁”的簇间距离计算策略,由“单连锁”的定义可知,对于(c)图中最左边两个由一条细线相连的两个簇,会被聚类成一个簇,这也不是我们想要的。

        CURE(Clustering Using Representative)采用了一种新型的层次聚类算法,这种算法介于“单链”和“组平均”之间,他克服了这两种层次聚类算法的不足之处。

  • Single Linkage 单链:方法是将两个组合数据点中距离最近的两个数据点间的距离作为这两个组合数据点的距离。这种方法容易受到极端值的影响。两个很相似的组合数据点可能由于其中的某个极端的数据点距离较近而组合在一起。

  • Average Linkage 组平均:Average Linkage的计算方法是计算两个组合数据点中的每个数据点与其他所有数据点的距离。将所有距离的均值作为两个组合数据点间的距离。这种方法计算量比较大,但结果比Single LinkageComplete Linkage方法更合理。

        注:单链聚类(层次聚类方法中的一种):定义簇的邻近度为不同两个簇的两个最近的点之间的距离(最大相似度)。使用图的术语,如果我们从所有点作为单点簇开始,每次在点之间加上一条链条,最短的链先加,则这些链将点合成成簇。单链技术擅长于处理非椭圆形状的簇,但对噪声和离群点很敏感。(详细参考:http://blog.acmj1991.com/?p=1560)

        该算法采用簇中的多个代表点来表示一个簇,首先选择簇中距离质心最远的点做为第一个点,然后依次选择距离已选到的点最远的点,直到选到c个点为止(一般选择c≥10),这些点捕获了簇的形状和大小。然后将这些选取到的点根据参数α(0≤α≤1 )向该簇的质心收缩,距离质心越远的点(例如离群点)的收缩程度越大,因此CURE离群点是不太敏感的,这种方法可以有效的降低离群点带来的不利影响。

        CURE算法有如下优势:

  • 准确地识别任意形状的簇;
  • 准确地识别尺寸差距大的簇;
  • 很好地处理“噪点”

  在得到上述缩减后的代表点后,两个簇之间的距离就可以定义为这两个簇中距离最近的两个代表点之间的距离,距离的数学定义如下

                

        其中,簇u的代表点集合表示为u.repdist(⋅,⋅)可以采用 或其他距离度量方式。然后在CURE层次聚类算法的每一步中对距离最近的簇进行合并。可以看到,当α=0时每个代表点都缩减到了该簇的质心上,这相当于“组平均”层次聚类,而当α=1 时每个代表点不会缩减,因此相当于“单链”层次聚类
  CURE算法的空间复杂度数据集大小n呈线性关系,而时间复杂度高达,对于低维数据集该复杂度可以降低到,因此其时间复杂度不会高于“组平均”层次聚类。但是CURE依旧不能运行于大型数据集,因此与BIRCH中通过汇总的方式来处理该问题不同的是,CURE采用了两种技术来加速聚类,首先在数据集上进行采样,可以证明采用适当的最小随机采样大小可以足够精准的表示簇的几何信息,我们可以采用“切尔霍夫界限”(Chernoff Bounds)来计算这个最小大小,其次,为了进一步提高聚类速度,CURE还将采样得到的点集进行分割,然后在分割后的子集上运行CURE层次聚类,在删除每个子集中的离群点后,再将每个子集中形成的簇进一步CURE层次聚类产生最终的聚类模型。
  在得到采样样本子集的聚类信息后,就可以对数据集中剩下的样本点进行划分,这里是跟据每个簇中的代表点进行划分的,而不是像BIRCH中使用簇质心进行划分,具体的方法是找到距离当前样本点最近的代表点,并将该样本点标记为该点所在的簇。

2.3.2 CURE算法流程

        CURE算法的基本流程可以表示为下图(图2),首先从原始数据集中随机抽取一部分样本点作为子集,再对该子集进行划分,在这些划分后的集合上运行CURE聚类算法得到每个集合的簇,并删除其中的离群点,然后对这些簇进一步进行CURE层次聚类,最后对磁盘中剩余的数据集样本点进行划分。 

           

                                                       图2 CURE算法流程

基本步骤:

  1. 对数据库抽样,得到一个样本;
  2. 将样本划分为 p 个分区,每个分区的规模为n/p。因为聚类首先在每个分区上进行,所以这样做可以起到加速算法的作用;
  3. 对每一分区,利用层次算法进行聚类。这提供了关于簇的组成的首次猜测。簇的数目为 n/pq,其中 q为某一常数;
  4. 删除异常点。利用两种不同的技术删除异常点。第一种技术是将增长缓慢的簇删除。当簇的数目低于某一阈值时,将仅含有一两个成员的簇删除。有可能较近的异常点会成为样本的一部分,而不能被第一种异常点删除技术识别出来。第二种技术是在聚类的最后阶段,将非常小的簇删除;
  5. 对局部的类进行聚类,落在每个新形成的类中的代表点根据用户定义的一个收缩因子收缩或向类中心移动。这些点代表和捕捉到了类的形状。
  6. 用相应的类标签来标记数据。

具体思想如下:

  1. CURE算法采用的是聚结层次聚类。在最开始的时候,每一个对象就是一个独立的类,然后从最相似的对象开始进行合并。
  2. 为了处理大数据集,采用了随机抽样分割 (Partitioning)手段。采用抽样的方法可以降低数据 量,提高算法的效率。在样本大小选择合适的情况下, 一 般能够得到比较好的聚类结果。另外,CURE算法还引入了分割手段,即将样本分割为几个部分,然后针对各个部分中的对象分别进行局部聚类,形成子类。再针对子类进行聚类,形成新的类。
  3. 传统的算法常常采用一个对象来代表一个类,而CURE算法由分散的若干对象,在按收缩因子移向其所在类的中心之后来代表该类。由于CURE算法采用多个对象来代表一个类,并通过收缩因子来调节类的形状,因此能够处理非球形的对象分布。
  4. 分两个阶段消除异常值的影响。CURE算法采用的是聚结层次聚类。在最开始的时候,每一个对象就是一个独立的类,然后从最相似的对象开始进行合并。 由于异常值同其它对象的距离更大,所以其所在 的类中对象数目的增大就会非常缓慢,甚至不增长。 第一个阶段的工作,是将聚类过程中增长非常缓慢的类作为异常值除去。第二个阶段的工作(聚类基本结束的时候)是将数目明显少的类作为异常值除去。
  5. 由于CURE算法采用多个对象来代表一个类,因此可以采用更合理的非样本对象分配策略。在完成对样本的聚类之后,各个类中只包含有样本对象,还需要将非样本对象按一定策略分配到相应的类中。
  6. 根据CURE算法提出者的研究成果,在该算法中收缩因子的取值在0.2-0.7之间能取得较好的聚类效果,而代表点数c一般选择大于10的数时,都能找到正确的聚类。

        收缩系数α的取值不同,聚类结果也相应不同。当α趋于0时,所有的“代表点”都汇聚到质心,算法退化为基于“质心”的聚类;当α趋于1时,“代表点”完全没有收缩,算法退化为基于“全连接”的聚类,因此α值需要要根据数据特征灵活选取,才能得到更好的聚类结果:

 2.3.3 CURE算法优点

  • 可以适应非球形的几何形状 将一个簇用多个代表点来表示,使得类的外延可以向非球形的形状扩展,从而可调整类的形状以表达非球形的类。
  • 对孤立点的处理更加健壮收缩因子降低了噪声对聚类的影响,从而使CURE对孤立点的处理更加健壮。
  • 能识别非球形和大小变化较大的簇。
  • 对大型数据库有良好的伸缩性。
  • 复杂性O(n),n是对象数目,所以适合大型数据聚类。

2.4 Chameleon变色龙算法

1.kNN图算法,参数k=1,2,3,4… 。以k为1为例,一次处理每一个点,每个点找一个最近的邻居链接起来,得到一个kNN图。

 2.整体算法步骤为:

1) 创建kNN图;

2) 使用最大流算法或者最小割算法,将kNN图分隔成小图;

3) 将小簇进行和并,合并条件是RC*RI大于某个值,RC和RI的一个基本思想是,点之间的链接越多,这些点越可能连接成一个簇,C表示一个簇,是点的集合,|C|是集合的大小,即点的个数,EC(A,B)表示两个簇之间的边的数量。

 3 自顶向下的分裂算法

3.1 Hierarchical K-means算法

        Hierarchical K-means算法是“自顶向下”的层次聚类算法,用到了基于划分的聚类算法那K-means,算法思路如下:

  1. 首先,把原始数据集放到一个簇C,这个簇形成了层次结构的最顶层;
  2. 使用K-means算法把簇C划分成指定的K个子簇C_i,i = 1,2,…,k,形成一个新的层;
  3. 对于步骤2所生成的K个簇,递归使用K-means算法划分成更小的子簇,直到每个簇不能再划分(只包含一个数据对象)或者满足设定的终止条件。

如下图,展示了一组数据进行了二次K-means算法的过程:

        Hierarchical K-means算法一个很大的问题是,一旦两个点在最开始被划分到了不同的簇,即使这两个点距离很近,在后面的过程中也不会被聚类到一起。

 

         对于以上的例子,红色椭圆框中的对象聚类成一个簇可能是更优的聚类结果,但是由于橙色对象和绿色对象在第一次K-means就被划分到不同的簇,之后也不再可能被聚类到同一个簇。

3.2(DIANA算法 (DIvisive ANALysis)

        分裂的层次聚类:DIANA算法 (DIvisive ANALysis)==>采用自顶向下的策略。首先将所有对象置于一个簇中,然后按照某种既定的规则逐渐细分为越来越小的簇(比如最大的欧式距离),直到达到某个终结条件(簇数目或者簇距离达到阈值);

算法性能:

        缺点是已做的分裂操作不能撤销,类之间不能交换对象。如果在某步没有选择好分裂点,可能会导致低质量的聚类结果。大数据集不太适用。

DIANA算法(目前只实现了二分类)_jungle8884的博客-CSDN博客_diana算法

DIANA算法 - 北极星! - 博客园

4 层次聚类的优缺点

  • 优点:1,距离和规则的相似度容易定义,限制少;2,不需要预先制定聚类数;3,可以发现类的层次关系;4,可以聚类成其它形状
  • 缺点:1,计算复杂度太高,因为要每次都要计算多个cluster内所有数据点的两两距离;2,奇异值也能产生很大影响;3,算法很可能聚类成链状;4,由于层次聚类使用的是贪心算法,得到的显然只是局域最优,不一定就是全局最优,这可以通过加入随机效应解决。

CURE算法详解:CURE算法详解 - 程序员大本营

CURE算法详解_Ἥλιος-CSDN博客_cure算法

层次聚类 DBSCAN聚类算法

09 聚类算法 - 层次聚类 - CF-Tree、BIRCH、CURE - 简书

BIRCH:使用聚类特征树(CF-树)的多阶段聚类算法:BIRCH:使用聚类特征树(CF-树)的多阶段聚类算法_HelloWorld-CSDN博客_cf树

聚类算法(4)--Hierarchical clustering层次聚类_Andy_shenzl的博客-CSDN博客

DBSCAN聚类算法——机器学习(理论+图解+python代码)_huacha__的博客-CSDN博客_dbscan聚类算法

聚类算法(三)——基于密度的聚类算法(以 DBSCAN 为例)_dengheCSDN的博客-CSDN博客

聚类算法:聚类算法_liqiuguo的博客-CSDN博客

  • 6
    点赞
  • 75
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值