贪婪的聚类算法速度提升

时间:2017-10-16 16:13:54

标签: python performance cluster-analysis

我试图在python中实现一个非常简单的贪婪聚类算法,但我很难对其进行优化以提高速度。该算法将采用距离矩阵,找到具有小于预定距离截止值的大多数分量的列,并将行索引(具有小于截止的分量)存储为群集的成员。集群的质心是列索引。然后从距离矩阵中移除每个成员索引的列和行(导致更小但仍然是正方形矩阵),并且算法迭代连续更小的距离矩阵,直到找到所有聚类。因为每次迭代都依赖于最后一次(形成一个新的距离矩阵,所以在簇之间没有重叠的成员),我想我无法避免python中的for循环缓慢。我已经尝试过numba(jit)加速它,但我认为它正在恢复到python模式,所以不会导致任何速度提升。以下是该算法的两种实现方式。第一个比后者慢。任何关于加速的建议都是最受欢迎的。我知道在scipy或sklearn中实现的其他聚类算法(例如DBSCAN,kmeans / medoids等),但我非常希望将当前的聚类算法用于我的应用程序。提前感谢任何建议。

方法1(较慢):

def cluster(distance_matrix, cutoff=1):
    indices = np.arange(0, len(distance_matrix))
    boolean_distance_matrix = distance_matrix <= cutoff
    centroids = []
    members = []
    while boolean_distance_matrix.any():
        centroid = np.argmax(np.sum(boolean_distance_matrix, axis=0))
        mem_indices = boolean_distance_matrix[:, centroid]
        mems = indices[mem_indices]
        boolean_distance_matrix[mems, :] = False
        boolean_distance_matrix[:, mems] = False
        centroids.append(centroid)
        members.append(mems)
    return members, centroids

方法2(更快,但对于大型矩阵仍然很慢):

它接受由sklearn的最近邻居实现形成的邻接(稀疏)矩阵作为输入。这是我能想到的最简单,最快速的方法来获得聚类的相关距离矩阵。我相信使用稀疏矩阵也可以加速聚类算法。

nbrs = NearestNeighbors(metric='euclidean', radius=1.5, 
algorithm='kd_tree')            
nbrs.fit(data)    
adjacency_matrix = nbrs.radius_neighbors_graph(data)   

def cluster(adjacency_matrix, gt=1):
    rows = adjacency_matrix.nonzero()[0]
    cols = adjacency_matrix.nonzero()[1]
    members = []
    member = np.ones(len(range(gt+1)))
    centroids = []
    appendc = centroids.append
    appendm = members.append
    while len(member) > gt:
        un, coun = np.unique(cols, return_counts=True)
        centroid = un[np.argmax(coun)]
        appendc(centroid)
        member = rows[cols == centroid]
        appendm(member)
        cols = cols[np.in1d(rows, member, invert=True)]
        rows = rows[np.in1d(rows, member, invert=True)]
    return members, centroids  

0 个答案:

没有答案