2016-06-27 35 views
6

przy użyciu gensim, chcę obliczyć podobieństwo w liście dokumentów. Ta biblioteka doskonale radzi sobie z ilością danych, które mam. Wszystkie dokumenty są zredukowane do sygnatur czasowych i mam funkcję time_similarity, aby je porównać. gensim używa jednak podobieństwa cosinus.gensim: niestandardowe podobieństwo

Zastanawiam się, czy ktoś wcześniej rozwiązał ten problem lub ma inne rozwiązanie.

Odpowiedz

1

Można to zrobić, dziedzicząc z interfejsu SimilarityABC. Nie znalazłem żadnej dokumentacji na ten temat, ale wygląda na to, że zostało to zrobione przed zdefiniowaniem Word Mover Distance similarity. Oto ogólny sposób, aby to zrobić. Prawdopodobnie sprawisz, że będzie bardziej wydajny, ponieważ specjalizuje się w podobieństwie, o które się troszczysz.

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 

Aby zaimplementować niestandardowy podobieństwa:

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

ten wyprowadza [(1, 2.0), (0, 1.0)].

+1

Twoja odpowiedź jest pomocna, ale ma problem. To jest wariant MatrixSimilarity. Aby skalować to, powinno być oparte na klasie Podobieństwo lub SparseMatrixSimilarity (inaczej: MemoryError). – Simon