2012-09-13 1 views
2

J'ai un grand csv de similitudes entre les mots-clés que je voudrais convertir en une matrice de distance triangulaire (parce qu'il est très grand et clairsemée serait encore mieux) pour effectuer la classification hiérarchique en utilisant scipy. Mon csv de données en cours ressemble à:CSV des distances à la matrice de distance triangulaire en Python

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

Je ne sais pas comment faire cela et je ne peux pas trouver des tutoriels faciles pour le regroupement en python.

Merci pour toute aide!

Répondre

2

Il y a deux parties à cette question:

  • Comment vous chargez des distances d'un fichier CSV de ce format dans un (peut-être clairsemée) matrice triangulaire à distance? Étant donné une matrice de distance triangulaire, comment faites-vous la classification hiérarchique avec Scipy?

Comment charger les données: Je ne pense pas que scipy.cluster.hierarchy œuvres données sont rares, alors faisons-dense. Je vais aussi le faire dans la matrice carrée complète et ensuite prendre le triangle supérieur que scipy veut, par paresse; vous pourriez indexer directement dans la version compressée si vous étiez plus intelligent.

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)] 

Puis appelez par ex. scipy.cluster.hierarchy.linkage avec condensed. Pour mapper des index aux noms, vous pouvez utiliser quelque chose comme

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

Merci! Mes données sont très volumineuses (environ 50 000 mots-clés/objets) donc j'espérais faire une matrice triangulaire inférieure pour des raisons de mémoire. – rfoley

+0

Maintenant, je me demandais comment obtenir des affectations de cluster à partir du clustering ward étant donné les distances condensées. – rfoley

+0

Pensez-vous que je pourrais convertir une matrice clairsemée des distances en une matrice de distances condensées? – rfoley

Questions connexes