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