【问题标题】:Clustering structural 3D data聚类结构 3D 数据
【发布时间】:2014-04-19 11:57:46
【问题描述】:

假设我有许多对象(类似于蛋白质,但不完全是),每个对象都由 n 个 3D 坐标的向量表示。这些物体中的每一个都指向空间的某个地方。可以通过使用Kabsch Algorithm 对齐它们并计算对齐坐标的均方根偏差来计算它们的相似度。

我的问题是,以提取人口最多的集群(即大多数结构所属的集群)的方式对大量这些结构进行聚类的推荐方法是什么。另外,有没有办法在python中做到这一点。举例来说,这里有一组平凡的非聚类结构(每个都由四个顶点的坐标表示):

然后是所需的聚类(使用两个聚类):

我尝试将所有结构与参考结构(即第一个结构)对齐,然后使用 Pycluster.kcluster 对参考和对齐坐标之间的距离执行 k-means,但这似乎有点笨拙和效果不太好。每个集群中的结构最终不会彼此非常相似。理想情况下,这种聚类不会在差异向量上进行,而是在实际结构本身上进行,但结构具有 (n,3) 维而不是 k-means 聚类所需的 (n,)。

我尝试的另一个选项是scipy.clustering.hierarchical。这似乎工作得很好,但我无法确定哪个集群人口最多,因为人们总是可以通过移动到树的下一个分支来找到人口更多的集群。

任何关于不同(已在 python 中实现)聚类算法的想法或建议或想法将不胜感激。

【问题讨论】:

    标签: python cluster-analysis


    【解决方案1】:

    为了对我自己的问题进行介绍性回答,我建议可以使用形状中每个点之间的距离列表作为执行聚类的指标。

    让我们创建一些形状:

    shapes = np.array([[[1,4],[4,2],[11,2],[14,0]],
              [[4,5],[4,2],[11,2],[13,0]],
              [[1,3],[4,2],[11,2],[14,1.5]],
              [[3,5],[4,2],[10,7],[7,9]],
              [[5,5],[4,2],[10,7],[6,6]]])
    
    def random_rotation():
        theta = 3 * np.pi * np.random.random()
        rotMatrix = numpy.array([[np.cos(theta), -np.sin(theta)], 
                                 [np.sin(theta),  np.cos(theta)]])
        return rotMatrix
    
    new_shapes = []
    for s in shapes:
        rr = random_rotation()
        new_shapes += [[list(rr.dot(p)) + [0] for p in s]]
    new_shapes = np.array(new_shapes)
    
    for i, s in enumerate(new_shapes):
        plot(s[:,0], s[:,1], color='black')
        text(np.mean(s[:,0]), np.mean(s[:,1]), str(i), fontsize=14)
    

    然后我们创建一些辅助函数并创建一个数组,其中包含每个形状的所有顶点间距离 (darray)。

    import itertools as it
    
    def vec_distance(v1, v2):
        '''
        The distance between two vectors.
        '''
        diff = v2 - v1
        return math.sqrt(sum(diff * diff))
    
    def distances(s):
        '''
        Compute the distance array for a shape s.
        '''
        ds = [vec_distance(p1, p2) for p1,p2 in it.combinations(s, r=2)]
    
        return np.array(ds)
    
    
    # create an array of inter-shape distances for each shape
    darray = np.array([distances(s) for s in new_shapes])
    

    使用Pycluster 将它们分成两个集群。

    import Pycluster as pc
    
    clust = pc.kcluster(darray,2)
    print clust
    

    看到我们最终在第一个集群中有三个条目,在另一个集群中有两个。

    (array([0, 0, 0, 1, 1], dtype=int32), 4.576996142441375, 1)
    

    但是它们对应于哪些形状呢?

    import brewer2mpl
    
    dark2 = brewer2mpl.get_map('Dark2', 'qualitative', 4).mpl_colors
    
    for i,(s,c) in enumerate(zip(new_shapes, clust[0])):
        plot(s[:,0], s[:,1], color=dark2[c])
        text(np.mean(s[:,0]), np.mean(s[:,1]), str(i), fontsize=14)
    

    看起来不错!问题是随着形状变大,距离数组相对于顶点的数量以二次时间增长。我找到了一个presentation,它描述了这个问题并提出了一些解决方案(比如我认为是一种降维形式的 SVD)来加速它。

    我暂时不会接受我的回答,因为我对如何解决这个简单问题的任何其他想法或想法感兴趣。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-03-15
      • 1970-01-01
      • 2012-09-11
      • 2018-08-14
      • 2013-01-14
      • 1970-01-01
      • 2010-10-10
      • 1970-01-01
      相关资源
      最近更新 更多