zoukankan      html  css  js  c++  java
  • python实现层次聚类

    python实现层次聚类 | 沙湖王

    python实现层次聚类

        昨晚到现在一直在研究层次聚类的问题。scipy包含了一些层次聚类的包和函数,但是它的文档实在太坑爹了,http://docs.scipy.org/doc/scipy/reference/cluster.hierarchy.html 这个就是scipy实现层次聚类的包。我感觉还没有完全弄明白它的意思。http://math.stanford.edu/~muellner/fastcluster.html fastcluster 则好多了,它提供的东西没有scipy多,但是它做层次聚类已经够了,而且它的速度也比scipy快,还和scipy是兼容的。http://www2.warwick.ac.uk/fac/sci/sbdtc/people/students/2010/jason_piper/code/ 这篇文章提到的例子就是fastcluster的使用。

     

       http://home.dei.polimi.it/matteucc/Clustering/tutorial_html/hierarchical.html 这篇文章是很好的层次聚类例子。文章中的

     
    BA
    FI
    MI
    NA
    RM
    TO
    BA
    0
    662
    877
    255
    412
    996
    FI
    662
    0
    295
    468
    268
    400
    MI
    877
    295
    0
    754
    564
    138
    NA
    255
    468
    754
    0
    219
    869
    RM
    412
    268
    564
    219
    0
    669
    TO
    996
    400
    138
    869
    669
    0
     

    这是一个距离矩阵。不管是scipy还是fastcluster,都有一个计算距离矩阵的步骤(也可以不用)。距离矩阵是冗余的,因为它是对称的。scipy里面的文档好多的关于数学上的英文,让我都搞糊涂了。distance = spatial.distance.pdist(data),这段代码里,data是一个矩阵,但不是距离矩阵,而是如http://www.shahuwang.com/?p=952 这篇文章中用到的数据形式,而最后算出来的distance只是一个数组,并不是矩阵,而且是一维数组,这是为什么呢?仔细看上面的那个矩阵,就知道我们只需要记录对角线上或者下面的一部分就可以了。废话不说,来看最简单的一个层次聚类实现(我现在主要将scipy的,fastcluster的使用几乎一样):

    1
    2
    from scipy.cluster.hierarchy import fclusterdata
    fclusterdata(matData,t=0.99,criterion='inconsistent',metric='euclidean',method='average',R=None)#这个不需要计算linkage就能直接出结果了

    这里用到的matData来自于:http://www.shahuwang.com/?p=952 用到的数据,是矩阵形式的。输出的结果如下:

    array([15, 19, 20, 26, 23, 10, 26, 23, 18, 21, 20, 22, 10, 20,  1, 18, 11,
            8,  4, 18, 21, 29, 25, 17, 18, 20, 24, 23,  3, 19, 12, 13, 15,  9,
           18, 25, 16, 28,  5, 17, 25, 17,  1, 15,  7,  4, 14,  6, 20,  2,  4,
            3,  9,  5,  2, 23,  1,  9, 25, 15, 23, 27, 16, 11, 22, 20, 12])

    结果的意思,就是说我的矩阵的第一个数据现在被分到了第15个类中,后面的也都是这个意思,自己再整理一下,就能输出美观直观的结果了。下面主要来讲一下fclusterdata里面的参数的意思:

    matData,这是要聚类的数据,t是一个阈值,小于1大于0,你可以根据输出结果来设置这个阈值。criterion,是一个标准,它主要是确定形成最后结果(如上面的那个array)需要满足什么条件,这个主要和 t 这个阈值进行合作。

    http://docs.scipy.org/doc/scipy/reference/generated/scipy.cluster.hierarchy.fcluster.html#scipy.cluster.hierarchy.fcluster 这里有比较详细的说明,不过貌似我这里就inconsistent能有比较好的结果。metric则是设置两个点之间的距离用什么方式计算,我这里的是欧几里得距离,详细可看维基百科的内容:http://en.wikipedia.org/wiki/Hierarchical_clustering  method则是计算两个簇直接满足什么条件就能合并。http://docs.scipy.org/doc/scipy/reference/generated/scipy.cluster.hierarchy.linkage.html#scipy.cluster.hierarchy.linkage 这里对method有详细的叙述。fclusterdata还有其他几个参数,我还没有搞明白,不过它们不提供的话,会有默认的。

    1
    2
    3
    4
    5
    6
    7
    8
    from scipy.cluster.hierarchy import linkage ,fcluster,fclusterdata
    import pandas as pd
    data = pd.read_csv('/home/rickey/文档/学习/数据挖掘与数据仓库/数据挖掘作业/三围数据',sep='t',index_col=0)
    matData = data.as_matrix()
    distance = spatial.distance.pdist(matData)
    linkresult = linkage(distance,method='average',metric='euclidean')
    fcluster(linkresult,t=0.99,criterion='inconsistent',depth=2,R=None,monocrit=None)#这个需要先计算linkage,再出结果
    dendrogram(linkresult,get_leaves=False,show_leaf_counts=False)#这个可以绘制出树形图

    这是更复杂一些的实现形式,主要有四个函数要注意,分别是pdist,linkage,fcluster,dendrogram。

    这段代码用的数据和前面那段是一样的,结果也是一样的。distance是一个距离数组(距离矩阵的一边角),之前已经说明了pdist的作用了。linkage返回的是一个4×(n-1)的矩阵。比如我的数据是67个,返回的则是一个4×66的矩阵。这个矩阵的意思,scipy文档上用的是这段话:“A 4 by (n-1) matrix Z is returned. At the i-th iteration, clusters with indices Z[i, 0] and Z[i, 1] are combined to form cluster n + i. A cluster with an index less than n corresponds to one of the n original observations. The distance between clusters Z[i, 0] and Z[i, 1] is given by Z[i, 2]. The fourth value Z[i, 3] represents the number of original observations in the newly formed cluster.”

    英语不济,不是很看得明白。大概是说Z[i,0],Z[i,1]是组成n+i簇的之类的吧。

    http://docs.scipy.org/doc/scipy/reference/generated/scipy.cluster.hierarchy.linkage.html#scipy.cluster.hierarchy.linkage linkage的用法还是要仔细看文档才行。

    fcluster这个函数,则是把linkage算出的结果,形成一个平面数组,形成最后的聚类结果呈现出来。里面的参数和fclusterdata里面的意思是一样的。

    fcluster的这段代码和fclusterdata的代码相比,多了一些,不过,好处就是能设置更多的参数。

    dendrogram的参数设置非常多,没有完全搞明白,不过它会输出一个字典,和一幅图。字典里面有四个key,而图则是树形图,如下:

    不过,我觉得这个图的用途不是很大,数据量一多,就什么都看不到了。

    scipy里面关于层次聚类的函数还有不少,我也没有搞懂,这里就不多说了。

  • 相关阅读:
    C#
    Jquery
    JavaScript
    JavaScript
    JavaScript
    JavaScript
    Html
    JavaScript
    (转)SC Create 创建一个Windows系统服务
    我的MyGeneration
  • 原文地址:https://www.cnblogs.com/lexus/p/2815785.html
Copyright © 2011-2022 走看看