精华内容
下载资源
问答
  • python的scipy层次聚类参数详解

    万次阅读 多人点赞 2018-01-17 09:30:53
    详解python中层次聚类的fcluster函数 调用实例: import scipy import scipy.cluster.hierarchy as sch from scipy.cluster.vq import vq,kmeans,whiten import numpy as np import matplotlib.pylab as plt ...

    详解python中层次聚类的fcluster函数

    调用实例:

    import scipy
    import scipy.cluster.hierarchy as sch
    from scipy.cluster.vq import vq,kmeans,whiten
    import numpy as np
    import matplotlib.pylab as plt
    
    points=scipy.randn(20,4)  
    
    #1. 层次聚类
    #生成点与点之间的距离矩阵,这里用的欧氏距离:
    disMat = sch.distance.pdist(points,'euclidean') 
    #进行层次聚类:
    Z=sch.linkage(disMat,method='average') 
    #将层级聚类结果以树状图表示出来并保存为plot_dendrogram.png
    P=sch.dendrogram(Z)
    plt.savefig('plot_dendrogram.png')
    #根据linkage matrix Z得到聚类结果:
    cluster= sch.fcluster(Z, t=1, 'inconsistent') 
    
    print "Original cluster by hierarchy clustering:\n",cluster

    参数列表如下:

    def fcluster(Z, t, criterion='inconsistent', depth=2, R=None, monocrit=None):

    Z代表了利用“关联函数”关联好的数据。
    比如上面的调用实例就是使用欧式距离来生成距离矩阵,并对矩阵的距离取平均
    这里可以使用不同的距离公式

    t这个参数是用来区分不同聚类的阈值,在不同的criterion条件下所设置的参数是不同的。
    比如当criterion为’inconsistent’时,t值应该在0-1之间波动,t越接近1代表两个数据之间的相关性越大,t越趋于0表明两个数据的相关性越小。这种相关性可以用来比较两个向量之间的相关性,可用于高维空间的聚类

    depth 代表了进行不一致性(‘inconsistent’)计算的时候的最大深度,对于其他的参数是没有意义的,默认为2

    criterion这个参数代表了判定条件,这里详细解释下各个参数的含义:
    1. 当criterion为’inconsistent’时,t值应该在0-1之间波动,t越接近1代表两个数据之间的相关性越大,t越趋于0表明两个数据的相关性越小。这种相关性可以用来比较两个向量之间的相关性,可用于高维空间的聚类
    2. 当criterion为’distance’时,t值代表了绝对的差值,如果小于这个差值,两个数据将会被合并,当大于这个差值,两个数据将会被分开。
    3. 当criterion为’maxclust’时,t代表了最大的聚类的个数,设置4则最大聚类数量为4类,当聚类满足4类的时候,迭代停止
    4. 当criterion为’monocrit’时,t的选择不是固定的,而是根据一个函数monocrit[j]来确定。例如例如,对最大平均距离的阈值在不一致矩阵r中计算阈值0.8,可以这样写,

    MR = maxRstat(Z, R, 3)
    cluster(Z, t=0.8, criterion='monocrit', monocrit=MR)
    1. 当criterion为’maxclust_monocrit’时,函数会在最大聚类数量为t的同时,将阈值t减小到最小的不一致性。
      调用实例如下:
    MI = maxinconsts(Z, R)
    cluster(Z, t=3, criterion='maxclust_monocrit', monocrit=MI)
    展开全文
  • 基于scipy层次聚类的python实现

    千次阅读 2017-09-19 22:42:59
    前段时间的项目中碰到一个分层聚类问题,任务是对语料库中的高频词汇进行分层聚类并刻画分类结果中...之后发现scipy下的cluster.hierarchy可以做层次聚类。开干!单词的描述用的是word2vec词向量,挺火的一个工具,...

    前段时间的项目中碰到一个分层聚类问题,任务是对语料库中的高频词汇进行分层聚类并刻画分类结果中的簇内的层次关系。第一想法是到网上去搜搜看看有没有什么好用的库。看了sklearn上的层次聚类的库函数,尼玛居然要我指定簇的个数,层次聚类的特点就是无需指定簇的个数嘛!逗我?之后发现scipy下的cluster.hierarchy可以做层次聚类。开干!单词的描述用的是word2vec词向量,挺火的一个工具,google开发的。我用的200维词向量,训练方法网上一大堆,训练的结果就是一个类似于词向量字典的东西,建立了单词与向量之间的映射关系。有了单词的表示,那么就可以刻画单词之间的相似性了。

    在分层聚类中,我们要考虑到相似性度量的参数,以及簇间距离的计算方式。采用余弦相似度作为参数,介于单连接和全连接之间的average作为簇间距离的计算方式。我先是得到了语料库中词频最高的5000个单词,转化为word2vec词向量之后,做分层聚类。

    代码如下:


    points = [self.Word2Vec[i] for i in mykeys[0:n]]#mykeys为得到的词频字典的键的列表

    Z = sch.linkage(points , method='average', metric='cosine')#得到对应的Z矩阵

    cluster = sch.fcluster(Z, t=1, criterion='inconsistent')#分层聚类结果

    cluster的结果是一个列表,里面有n个元素,对应原始观测点的聚类之后所属的簇的id。

    然后我仔细研究了Z矩阵的构成,它一共有n-1行,4列,第一列和第二列的值代表节点id,按照簇出现的顺序进行编号。然后第三列是这两个id之间的相似程度,或者说是距离,这里余弦相似度被转化为距离了,也就是1-cos(point1, point2)。第四列是按照当前行合并之后得到的节点id。这样以来,可以得到n个叶子结点id,n-1个内部节点id,一共2*n-1个节点id。现在我要把每个内部节点的子节点的信息保留下来,以便后续操作:

    原始的观测点的簇id就按照顺序来好了。

    从第一个内部节点开始,就要保存儿子节点的信息了,即保留左右儿子的id。

    # 按照bottom-up方式获取内部节点,存储了ClusterNode的信息,countdist,id,left,right
    #树的叶子节点列表
    nodelist = sch._order_cluster_tree(Z)
    
    #节点字典,键为节点id,值为对应的子节点的id列表。
    node_dict = {}
    # 保存叶子节点id,用做初始化。
    for item in xrange(n):
        node_dict[item] = item
    
    # 保存内部节点id
    # 把每个凝聚点的子节点的信息保留在字典中
    for item in nodelist:
        node_dict[item.id] = [node_dict[item.left.id], node_dict[item.right.id]]
    
    # 将字典中每个叶子节点变为列表形式,方便之后的处理
    for item in xrange(n):
        node_dict[item] = [item]
    
    # 获取各个簇的最近公共父节点
    cluster_node = sch.leaders(Z, cluster)

    在得到各个簇的最近公共父节点id之后我们就可以得到一种嵌套的列表,然后按照我的另一篇博文的方式就可以提取层次关系了。

    http://blog.csdn.net/u012260341/article/details/77989167


    这样就可以了么?后来一想,5000个单词是不是小了点。于是乎我加到了10000。满怀期待的等它出结果。结果,傻眼了,给我报了内存错误。那么就去看看啥错误咯,是numpy在申请列表的时候内存报错,想想,一次性载入这么多数据,不爆才怪呢。1w个单词,需要存储1w*9999/2个数据,python的列表表示很不开心,容纳不下。那怎么办,改源码?改源码还是需要勇气的。我选择了尊重源码。那这个问题就到此为止了么?不行,这样子没法交差啊!于是乎我想到了数学运算工具matlab。数学运算神器哦。我怕它再次内存报错,先产生了10000个随机数进行测试,哇,居然没报错,那我继续,加到20000,居然还没报错!我来劲了,直接上100000!这次报错了,说我没有足够的内存容纳30多G的数据。想想也是,我的电脑也才8G内存。matlab都没法处理这么大量的数据了。本来啊,分层聚类本来就不适合海量数据嘛。不过对20000个数据进行聚类的能力还是要有的。那么我就研究,python怎么调用matlab的库。原来是要装个mlab的库,用pip install mlab就好了。然后就是导入matlab的相应模块了。这里要注意,我之前内存报错的原因在于计算10000个点两两之间的余弦相似度,而我要得到的是一个Z的矩阵,它包含了点之间的距离等信息,因此我只需要调用matlab库得到Z就可以了,之后还是按照原来的方法即可。这种两阶段方法也是挺有意思的。谁让scipy没法一次性处理这么多数据嘛!

    导入mlab的相应模块

    from mlab.releases import latest_release as matlab

    假设要对points中的点进行分层聚类。
    points = [[1, 1], [1, 2], [1, 3], [1, 4], [1, 5], [1, 6]]

    然后直接调用matlab下的linkage函数就好了。这样就完成了20000个单词的分层聚类任务。

    #得到matlab下的Z
    Z_matlab = matlab.linkage(points, 'average', 'cosine')
    
    #matlab下的Z转换成scipy可用的Z
    Z = sch.from_mlab_linkage(Z_matlab)
    
    # 根据linkage matrix Z得到聚类结果:
    cluster = sch.fcluster(Z, t=1, criterion='inconsistent')

    总结:在这次分层聚类任务过程中,我阅读了大量库的源码,包括函数参数的意义,输入输出的过程,这个过程还是略有点痛苦,特别是后来报个MemoryError简直桑心透了。还好找到了解决方案,用matlab这个神器最终解决了我的问题。






    展开全文
  • I have a text corpus that contains 1000+ articles each in a separate ... I am trying to use Hierarchy Clustering using Scipy in python to produce clusters of related articles.This is the code I used...

    I have a text corpus that contains 1000+ articles each in a separate line. I am trying to use Hierarchy Clustering using Scipy in python to produce clusters of related articles.

    This is the code I used to do the clustering

    # Agglomerative Clustering

    import matplotlib.pyplot as plt

    import scipy.cluster.hierarchy as hac

    tree = hac.linkage(X.toarray(), method="complete",metric="euclidean")

    plt.clf()

    hac.dendrogram(tree)

    plt.show()

    and I got this plot

    t2qv5.png

    Then I cut off the tree at the third level with fcluster()

    from scipy.cluster.hierarchy import fcluster

    clustering = fcluster(tree,3,'maxclust')

    print(clustering)

    and I got this output:

    [2 2 2 ..., 2 2 2]

    My question is how can I find the top 10 frequent words in each cluster in order to suggest a topic for each cluster?

    解决方案

    You can do the following:

    Align your results (your clustering variable) with your input (the 1000+ articles).

    Using pandas library, you can use a groupby function with the cluster # as its key.

    Per group (using the get_group function), fill up a defaultdict of integers for every

    word you encounter.

    You can now sort the dictionary of word counts in descending order and get your desired number of most frequent words.

    Good luck with what you're doing and please do accept my answer if it's what you're looking for.

    展开全文
  • 基于scipy层次聚类探究

    千次阅读 2018-04-08 13:51:57
    在这样的背景下,我仔细研究了scipy下的层次聚类的API函数,并运用到了实际项目中。我们分两种情况来进行讨论:1、给定了距离矩阵,2、没给定距离矩阵1、给定了距离矩阵:我们可以基于距离矩阵...

    最近又要开始做聚类了,之前做过的层次聚类的方法是用sklearn下的聚类,但是存在一定的缺陷:库并没有给我们提供足够的函数去评价聚类效果,如果想要对层次聚类树自定义损失函数,那么我们就需要剖析整棵层次聚类树了。在这样的背景下,我仔细研究了scipy下的层次聚类的API函数,并运用到了实际项目中。

    我们分两种情况来进行讨论:1、给定了距离矩阵,2、没给定距离矩阵

    1、给定了距离矩阵:

    我们可以基于距离矩阵来计算。

    当然,在凝聚层次聚类的过程中,我们需要对簇间的距离进行刻画。在scipy中,linkage的method有很多种:single、average、complete、weighted、centroid、median、ward等,这个method表示的是linkage算法,即聚类的连接算法。比如single表示最近距离,在计算两个簇的距离的时候,选取两个簇中最近的两个观测点作为簇间距离。average表示的是平均距离,complete表示的是最远距离。

    此外还有一个参数metric,即计算两个观测点的距离,由于我们给定了距离矩阵,可以直接获得两个观测点的距离,但是,linkage函数并没有给我们提供类似于sklearn的precomputed选项,好在metric可以自定义,我们自定义metric。这里举个例子:

     # 计算距离矩阵中两行的距离

    def func(u, v):
        v_list = list(v)
        pos_v = v_list.index(0.0)
        return u[pos_v]

    这里的两个参数u和v,代表距离矩阵中的任意两行,那么要得到二者的距离,则需要找到相应的位置,如函数中所写。

    然后,我们再用linkage,使用average连接算法,func度量方式

    z = sch.linkage(data_square, method='average', metric=func)

    如此一来我们可以计算任意两个观测点的距离。同时,由于凝聚层次聚类会合并距离矩阵的凝聚点的行,因此,该函数还可以计算两个簇的距离,这里的簇被抽象成了观测点。

    然后我们再绘制聚类图谱,可以看聚类凝聚顺序。

    sch.dendrogram(z)
    plt.show()

    另外,由于我们要对整棵树进行剖析,我们需要对树的节点进行分析:

    tree_node = sch.to_tree(z, True)

    这个函数可以根据z矩阵得到树中的各个节点,返回一个列表。从叶子结点开始,然后再依次是凝聚点。次序和凝聚的次序是一致的,即先凝聚的点先放进节点列表中。假设有N个观测点,那么前N个点为观测节点,后面的N-1个点为凝聚点。

    node_list = tree_node[1][N:]

    可以以这种方式得到凝聚点。

    树中的节点的数据结构的组织形式为[id, left, right,dist,count]:节点id,左子树“指针”,右子树“指针”,凝聚时的高度,以该节点为根节点的子树的节点总数。对于叶子结点而言,left和right都为None,dist为0,count为0。

    之后,我们就可以自定义损失函数来对聚类质量进行评估了,当然我们评估聚类质量的目的是找到一个好的聚类参数譬如阈值或者聚类数目,无需人工预设。下面介绍几种方法:

    1、轮廓系数,思路是以轮廓系数为最优化目标,绘制阈值-轮廓系数曲线,取最大点对应的阈值。这个方法的结果取决于数据分布,数据分布太重要了!在一些情况下会产生过拟合,如果簇内有两个簇距离特别远,而这两个簇内部理应继续划分的,但是使用轮廓系数却只会得到两个簇,这严重影响了聚类质量。

    2、考虑簇内误差度量每个凝聚点的误差,思路是通过设定阈值,计算每次聚类的每个簇内的点到簇中心点的距离,然后求和,作为损失函数,采用“肘方法”或者失真函数的方法得到一个最优阈值。在这里,对于层次聚类而言,由于中心点不能直接计算,我们可以选择一个簇内的点代表中心点,满足它到簇内其他点的距离和最小。

    3、根据层次聚类的层次聚类树谱图来发现最优聚类个数,可以在凝聚点的距离差上面做文章。

    通过阈值的方式进行聚类的函数如下,d为设定的阈值,可以取各凝聚点对应的阈值,即dist

    labels_pred = sch.fcluster(z, t=d, criterion='distance')

    2、没有给定距离矩阵

    如果我们的数据是向量形式的,那么我们可以将数据直接以“样本数-特征数”矩阵的方式进行输入,也可以先转换为距离矩阵再进行给定距离矩阵情形下的操作。

    data_pdist = dist.pdist(data, metric="cosine") # 对于样本-数目矩阵,可以计算cosine相似度
    
    data_square = dist.squareform(data_pdist)  # 生成距离矩阵

    总的来说,层次聚类的方法取决于数据的形式:如果对于“样本数-特征数”矩阵形式的数据,那么无需距离矩阵的构造了。如果数据无法表示成“样本数-特征数”,譬如短文本的表示,我们可能没法或者很难使用一个向量来表达一个句子——因为单词的太多容易造成矩阵稀疏。那么我们可以构造一个距离矩阵,只需得到两两观测点的距离进而进行聚类分析。缺点是一旦数目很大,聚类算法的复杂度会很高,同时层次聚类要一次性将数据载入内存,数据量太大会报Memory Error,对于千万级的数据无能为力。

    展开全文
  • 使用scipy进行层次聚类和k-means聚类

    万次阅读 多人点赞 2015-12-09 22:40:02
    使用scipy库进行层次聚类和kmeans聚类
  • 今天,总结一下如何使用层次聚类算法里面的自定义距离度量 层次聚类上次已经总结过。 这次仅仅说明层次聚类的距离参数,这里的距离参数可以使用自定义函数。 我们进入该函数的文档页面 我们看到linkage的...
  • scipy模块是很强大,里面很多有用的函数,这里先花一点时间使用一下scipy模块中的层次聚类,下面是简单的使用: #!usr/bin/env python #encoding:utf-8 ''' __Author__:沂水寒城 功能:scipy测试使用 ''' ...
  • scipy cluster库简介 scipy.cluster是scipy下的一个做聚类的package, 共包含了两类聚类方法:1. 矢量量化(scipy.cluster.vq):支持... 层次聚类(scipy.cluster.hierarchy):支持hierarchical clustering 和 agglomerat...
  • 层次聚类理论知识 类从多减少的过程。 1、定义样本间的距离,类与类之间的距离 2、将每个样本当作一类,计算距离最近的两类,合并为新类 3、一点一点做,直到所有成为一类。 基本步骤...
  • 1)数据标准化 import scipy import scipy.cluster.hierarchy as sch from scipy.cluster.vq import vq,kmeans,whiten import numpy as np import matplotlib.pylab as plt ... 层次聚类 #生成点与点之...
  • I am trying to figure out how the output of scipy.cluster.hierarchy.dendrogram works... I thought I knew how it worked and I was able to use the output to reconstruct the dendrogram but it seems as if...
  • 文章目录python 实现层次聚类1. scipy实现2. sklearn实现 python 实现层次聚类 关于层次聚类的原理,可以参考博客: https://blog.csdn.net/pentiumCM/article/details/105675576 本博客主要讲解如何简单直接使用 ...
  • python机器学习包里面的cluster提供了很...经过查找,发现scipy.cluster.hierarchy.fclusterdata能够实现层次聚类。有关这个方法的介绍在:http://docs.scipy.org/doc/scipy/reference/generated/scipy.cluster.hie...
  • 这里,我们来解读一下scipy中给出的层次聚类scipy.cluster.hierarchy的示例: import numpy as np from scipy.cluster.hierarchy import dendrogram, linkage,fcluster from matplotlib import pyplot as plt X = [...
  • 层次聚类和Kmeans

    2020-12-21 20:56:12
    文章目录层次聚类层次聚类流程层次聚类优缺点Kmeans聚类Kmeans聚类流程K-Means的优缺点 层次聚类 层次聚类流程 (1) 计算两两样本之间的距离; (2) 将距离最小的两个类合并成一个新类; (3) 重新计算新类与所有类之间...
  • 层次聚类 原理 有一个讲得很清楚的博客:博客地址 主要用于:没有groundtruth,且不知道要分几类的情况 用scipy模块实现聚类 参考函数说明: pdist squareform linkage fcluster scipy.spatial.distance.pdist:...
  • This is a tutorial on how to use scipy's hierarchical clustering.One of the benefits of hierarchical clustering is that you 不用提前知道数据需要分成多少类(类别数量用k表示). Sadly, there doesn't ...
  • 使用Python 3和scipy作为Jupyter笔记本进行层次聚类练习

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,956
精华内容 782
关键字:

scipy层次聚类