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