• 聚类算法:凝聚层次聚类


    凝聚层次聚类

       所谓凝聚的,指的是该算法初始时,将每个点作为一个簇,每一步合并两个最接近的簇。另外即使到最后,对于噪音点或是离群点也往往还是各占一簇的,除非过度合并。对于这里的“最接近”,有下面三种定义。我在实现是使用了MIN,该方法在合并时,只要依次取当前最近的点对,如果这个点对当前不在一个簇中,将所在的两个簇合并就行:

        (1)单链(MIN):定义簇的邻近度为不同两个簇的两个最近的点之间的距离。

        (2)全链(MAX):定义簇的邻近度为不同两个簇的两个最远的点之间的距离。

        (3)组平均:定义簇的邻近度为取自两个不同簇的所有点对邻近度的平均值。

    根据该算法,实现如下代码。开始时计算每个点对的距离,并按距离降序依次合并。另外为了防止过度合并,定义的退出条件是90%的簇被合并,即当前簇数是初始簇数的10%:

    实现代码如下:

    [python] view plain copy
     
    1. # scoding=utf-8  
    2. # Agglomerative Hierarchical Clustering(AHC)  
    3. import pylab as pl  
    4. from operator import itemgetter  
    5. from collections import OrderedDict,Counter  
    6.    
    7. points = [[int(eachpoint.split('#')[0]), int(eachpoint.split('#')[1])] for eachpoint in open("points","r")]  
    8.    
    9. # 初始时每个点指派为单独一簇  
    10. groups = [idx for idx in range(len(points))]  
    11.    
    12. # 计算每个点对之间的距离  
    13. disP2P = {}  
    14. for idx1,point1 in enumerate(points):  
    15.     for idx2,point2 in enumerate(points):  
    16.         if (idx1 < idx2):  
    17.             distance = pow(abs(point1[0]-point2[0]),2) + pow(abs(point1[1]-point2[1]),2)  
    18.             disP2P[str(idx1)+"#"+str(idx2)] = distance  
    19.    
    20. # 按距离降序将各个点对排序  
    21. disP2P = OrderedDict(sorted(disP2P.iteritems(), key=itemgetter(1), reverse=True))  
    22.    
    23. # 当前有的簇个数  
    24. groupNum = len(groups)  
    25.    
    26. # 过分合并会带入噪音点的影响,当簇数减为finalGroupNum时,停止合并  
    27. finalGroupNum = int(groupNum*0.1)  
    28.    
    29. while groupNum > finalGroupNum:  
    30.     # 选取下一个距离最近的点对  
    31.     twopoins,distance = disP2P.popitem()  
    32.     pointA = int(twopoins.split('#')[0])  
    33.     pointB = int(twopoins.split('#')[1])  
    34.        
    35.     pointAGroup = groups[pointA]  
    36.     pointBGroup = groups[pointB]  
    37.        
    38.     # 当前距离最近两点若不在同一簇中,将点B所在的簇中的所有点合并到点A所在的簇中,此时当前簇数减1  
    39.     if(pointAGroup != pointBGroup):  
    40.         for idx in range(len(groups)):  
    41.             if groups[idx] == pointBGroup:  
    42.                 groups[idx] = pointAGroup  
    43.         groupNum -= 1  
    44.    
    45. # 选取规模最大的3个簇,其他簇归为噪音点  
    46. wantGroupNum = 3  
    47. finalGroup = Counter(groups).most_common(wantGroupNum)  
    48. finalGroup = [onecount[0] for onecount in finalGroup]  
    49.    
    50. dropPoints = [points[idx] for idx in range(len(points)) if groups[idx] not in finalGroup]  
    51.    
    52. # 打印规模最大的3个簇中的点  
    53. group1 = [points[idx] for idx in xrange(len(points)) if groups[idx]==finalGroup[0]]  
    54. group2 = [points[idx] for idx in xrange(len(points)) if groups[idx]==finalGroup[1]]  
    55. group3 = [points[idx] for idx in xrange(len(points)) if groups[idx]==finalGroup[2]]  
    56. pl.plot([eachpoint[0] for eachpoint in group1], [eachpoint[1] for eachpoint in group1], 'or')  
    57. pl.plot([eachpoint[0] for eachpoint in group2], [eachpoint[1] for eachpoint in group2], 'oy')  
    58. pl.plot([eachpoint[0] for eachpoint in group3], [eachpoint[1] for eachpoint in group3], 'og')     
    59.    
    60. # 打印噪音点,黑色  
    61. pl.plot([eachpoint[0] for eachpoint in dropPoints], [eachpoint[1] for eachpoint in dropPoints], 'ok')     
    62.    
    63. pl.show()  

    另外我们可以看出凝聚的层次聚类并没有类似基本K均值的全局目标函数,没有局部极小问题或是很难选择初始点的问题。合并的操作往往是最终的,一旦合并两个簇之后就不会撤销。当然其计算存储的代价是昂贵的。

  • 相关阅读:
    PHP核心代码库中的APC缓存说明123
    php5函数库
    javaweb 在netbeans 上的部署问题
    数据结构二叉树的递归与非递归遍历之java,javascript,php实现可编译(1)java
    实验五 Java网络编程及安全
    实验三 敏捷开发和XP实验
    实验二 Java面向对象程序设计
    实验一 Java开发环境的熟悉
    at&t 命令集合
    chkconfig命令
  • 原文地址:https://www.cnblogs.com/gswang/p/7506643.html
Copyright © 2020-2023  润新知