43 votes

format de liaison scipy

J'ai écrit ma propre routine de clustering et j'aimerais produire un dendrogramme. Le moyen le plus simple de le faire serait d'utiliser la fonction dendrogramme scipy. Cependant, cela nécessite que l'entrée soit dans le même format que celui produit par la fonction de liaison scipy. Je ne trouve pas d'exemple de la façon dont la sortie de ceci est formatée. Je me demandais si quelqu'un pouvait m'éclairer.

10voto

Salik Syed Points 113

La documentation scipy est précise, comme l'a souligné dkar... mais il est un peu difficile de transformer les données renvoyées en quelque chose qui soit utilisable pour une analyse plus approfondie.

À mon avis, ils devraient inclure la possibilité de renvoyer les données dans une structure de données telle qu'une arborescence. Le code ci-dessous parcourra la matrice et créera un arbre :

 from scipy.cluster.hierarchy import linkage
import numpy as np

a = np.random.multivariate_normal([10, 0], [[3, 1], [1, 4]], size=[100,])
b = np.random.multivariate_normal([0, 20], [[3, 1], [1, 4]], size=[50,])
centers = np.concatenate((a, b),)

def create_tree(centers):
    clusters = {}
    to_merge = linkage(centers, method='single')
    for i, merge in enumerate(to_merge):
        if merge[0] <= len(to_merge):
            # if it is an original point read it from the centers array
            a = centers[int(merge[0]) - 1]
        else:
            # other wise read the cluster that has been created
            a = clusters[int(merge[0])]

        if merge[1] <= len(to_merge):
            b = centers[int(merge[1]) - 1]
        else:
            b = clusters[int(merge[1])]
        # the clusters are 1-indexed by scipy
        clusters[1 + i + len(to_merge)] = {
            'children' : [a, b]
        }
        # ^ you could optionally store other info here (e.g distances)
    return clusters

print create_tree(centers)

0voto

David Bernat Points 21

Voici un autre morceau de code qui remplit la même fonction. Cette version suit la distance (taille) de chaque cluster (node_id) et confirme le nombre de membres.

Cela utilise la fonction scipy link() qui est la même base que le clusterer Aggregator.

 from scipy.cluster.hierarchy import linkage
import copy
Z = linkage(data_x, 'ward')

n_points = data_x.shape[0]
clusters = [dict(node_id=i, left=i, right=i, members=[i], distance=0, log_distance=0, n_members=1) for i in range(n_points)]
for z_i in range(Z.shape[0]):
    row = Z[z_i]
    cluster = dict(node_id=z_i + n_points, left=int(row[0]), right=int(row[1]), members=[], log_distance=np.log(row[2]), distance=row[2], n_members=int(row[3]))
    cluster["members"].extend(copy.deepcopy(members[cluster["left"]]))
    cluster["members"].extend(copy.deepcopy(members[cluster["right"]]))
    clusters.append(cluster)

on_split = {c["node_id"]: [c["left"], c["right"]] for c in clusters}
up_merge = {c["left"]: {"into": c["node_id"], "with": c["right"]} for c in clusters}
up_merge.update({c["right"]: {"into": c["node_id"], "with": c["left"]} for c in clusters})

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X