Tri inversé et argsort en python

j'essaie d'écrire une fonction en Python (toujours un noob!) qui renvoie les indices et les scores des documents commandés par les produits internes de leurs scores tfidf. La procédure est la suivante:

  • calculer le vecteur des produits intérieurs entre les COD idx et tous les autres documents
  • Trier par ordre décroissant
  • retourner les "scores" et les indices de la deuxième à la fin (c.-à-d. pas lui-même)

le code que j'ai en ce moment est:

import h5py
import numpy as np

def get_related(tfidf, idx) :
    ''' return the top documents '''

    # calculate inner product   
    v = np.inner(tfidf, tfidf[idx].transpose())

    # sort
    vs = np.sort(v.toarray(), axis=0)[::-1]
    scores = vs[1:,]

    # sort indices
    vi = np.argsort(v.toarray(), axis=0)[::-1]
    idxs = vi[1:,] 

    return (scores, idxs)

tfidf est un sparse matrix of type '<type 'numpy.float64'>'.

cela semble inefficace, car le tri est effectué deux fois (sort()argsort()), et les résultats doivent ensuite être inversé.

  • peut-on le faire plus efficacement?
  • peut - on le faire sans convertir la matrice clairsemée en utilisant <!--6?
14
demandé sur Fred Foo 2011-12-09 16:12:07

1 réponses

je ne pense pas qu'il y a un réel besoin de sauter le toarray. v array sera seulement n_docs long, qui est éclipsé par la taille de la n_docs×n_terms matrice TF-idf dans la pratique. De plus, elle sera assez dense puisque tout terme partagé par deux documents leur donnera une similitude non nulle. Les représentations de matrice éparses ne payent que lorsque la matrice que vous stockez est très clairsemé (j'ai vu > 80% des chiffres pour Matlab et de supposer que Scipy sera similaire, bien que je n'ai pas de chiffre exact).

on peut sauter la double sorte en faisant

v = v.toarray()
vi = np.argsort(v, axis=0)[::-1]
vs = v[vi]

Btw. votre utilisation de np.inner sur les matrices creuses n'est pas d'aller travailler avec les dernières versions de NumPy; la manière la plus sûre de prendre intérieure d'un produit de deux matrices creuses est

v = (tfidf * tfidf[idx, :]).transpose()
9
répondu Fred Foo 2012-09-28 08:22:31