2016-06-27 1 views
6

En utilisant gensim, je veux calculer la similitude dans une liste de documents. Cette librairie est excellente pour gérer les quantités de données que j'ai. Les documents sont tous réduits à des horodatages et j'ai une fonction time_similarity pour les comparer. gensim cependant, utilise la similitude de cosinus.gensim: mesure de similarité personnalisée

Je me demande si quelqu'un l'a déjà fait auparavant ou a une solution différente.

Répondre

1

Il est possible de le faire en héritant de l'interface SimilarityABC. Je n'ai trouvé aucune documentation pour cela mais il semble que cela ait déjà été fait pour définir Word Mover Distance similarity. Voici une façon générique de le faire. Vous pouvez probablement le rendre plus efficace en vous spécialisant sur la mesure de similarité qui vous intéresse.

import numpy 
from gensim import interfaces 

class CustomSimilarity(interfaces.SimilarityABC): 

    def __init__(self, corpus, custom_similarity, num_best=None, chunksize=256): 
     self.corpus = corpus 
     self.custom_similarity = custom_similarity 
     self.num_best = num_best 
     self.chunksize = chunksize 
     self.normalize = False 

    def get_similarities(self, query): 
     """ 
     **Do not use this function directly; use the self[query] syntax instead.** 
     """ 
     if isinstance(query, numpy.ndarray): 
      # Convert document indexes to actual documents. 
      query = [self.corpus[i] for i in query] 
     if not isinstance(query[0], list): 
      query = [query] 
     n_queries = len(query) 
     result = [] 
     for qidx in range(n_queries): 
      qresult = [self.custom_similarity(document, query[qidx]) for document in self.corpus] 
      qresult = numpy.array(qresult) 
      result.append(qresult) 
     if len(result) == 1: 
      # Only one query. 
      result = result[0] 
     else: 
      result = numpy.array(result) 
     return result 

Pour mettre en œuvre une similitude personnalisée:

def overlap_sim(doc1, doc2): 
    # similarity defined by the number of common words 
    return len(set(doc1) & set(doc2)) 
corpus = [['cat', 'dog'], ['cat', 'bird'], ['dog']] 
cs = CustomSimilarity(corpus, overlap_sim, num_best=2) 
print(cs[['bird', 'cat', 'frog']]) 

Ce sorties [(1, 2.0), (0, 1.0)].

+1

Votre réponse est utile, mais a un problème. C'est la variante MatrixSimilarity. Pour le mettre à l'échelle, il devrait être basé sur la classe Similarity ou SparseMatrixSimilarity (sinon: MemoryError). – Simon