【问题标题】:CSV of Distances to Triangular Distance Matrix in PythonPython中距离到三角距离矩阵的CSV
【发布时间】:2012-09-13 02:36:38
【问题描述】:

我有一个关键字之间相似性较大的 csv,我想将其转换为三角距离矩阵(因为它非常大并且稀疏会更好)以使用 scipy 执行层次聚类。我当前的数据 csv 看起来像:

a,  b, 1
b,  a, 1
c,  a, 2
a,  c, 2

我不知道该怎么做,也找不到任何简单的 Python 集群教程。

感谢您的帮助!

【问题讨论】:

    标签: python matrix bigdata hierarchical-clustering


    【解决方案1】:

    这个问题分为两部分:

    • 如何将这种格式的 CSV 中的距离加载到(可能是稀疏的)三角距离矩阵中?

    • 给定一个三角距离矩阵,如何用 scipy 进行层次聚类?

    如何加载数据:我认为scipy.cluster.hierarchy 不适用于稀疏数据,所以让我们将其密集化。我也打算把它做成完整的方阵,然后取 scipy 想要的上三角形,出于懒惰;如果你更聪明,你可以直接索引到压缩版本。

    from collections import defaultdict
    import csv
    import functools
    import itertools
    import numpy as np
    
    # name_to_id associates a name with an integer 0, 1, ...
    name_to_id = defaultdict(functools.partial(next, itertools.count()))
    
    with open('file.csv') as f:
        reader = csv.reader(f)
    
        # do one pass over the file to get all the IDs so we know how 
        # large to make the matrix, then another to fill in the data.
        # this takes more time but uses less memory than loading everything
        # in in one pass, because we don't know how large the matrix is; you
        # can skip this if you do know the number of elements from elsewhere.
        for name_a, name_b, dist in reader:
            idx_a = name_to_id[name_a]
            idx_b = name_to_id[name_b]
    
        # make the (square) distances matrix
        # this should really be triangular, but the formula for 
        # indexing into that is escaping me at the moment
        n_elem = len(name_to_id)
        dists = np.zeros((n_elem, n_elem))
    
        # go back to the start of the file and read in the actual data
        f.seek(0)
        for name_a, name_b, dist in reader:
            idx_a = name_to_id[name_a]
            idx_b = name_to_id[name_b]
            dists[(idx_a, idx_b) if idx_a < idx_b else (idx_b, idx_a)] = dist
    
    condensed = dists[np.triu_indices(n_elem, 1)]
    

    然后调用例如scipy.cluster.hierarchy.linkagecondensed。要将索引映射回名称,您可以使用类似

    id_to_name = dict((id, name) for name, id in name_to_id.iteritems())
    

    【讨论】:

    • 谢谢!我的数据非常大(大约 50,000 个关键字/对象),因此出于内存原因,我希望制作一个下三角矩阵。
    • 现在我只是想知道在给定距离的情况下如何从病房聚类中获取聚类分配。
    • 你认为我可以将距离的稀疏矩阵转换为压缩距离矩阵吗?
    • 我已经发布了一个相关问题,如果您认为相关,我很想听听您的意见:stackoverflow.com/questions/12400301/…
    • 我有大约 120,000 个对象,我想知道是否有可能创建一个距离对象以在 python 中进行聚类。
    猜你喜欢
    • 2011-08-08
    • 1970-01-01
    • 2016-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多