Python >> Tutoriel Python >  >> Python Tag >> Gensim

Python Gensim :comment calculer la similarité des documents à l'aide du modèle LDA ?

Cela dépend de la métrique de similarité que vous souhaitez utiliser.

La similarité cosinus est universellement utile et intégrée :

sim = gensim.matutils.cossim(vec_lda1, vec_lda2)

La distance Hellinger est utile pour la similarité entre les distributions de probabilité (telles que les sujets LDA) :

import numpy as np
dense1 = gensim.matutils.sparse2full(lda_vec1, lda.num_topics)
dense2 = gensim.matutils.sparse2full(lda_vec2, lda.num_topics)
sim = np.sqrt(0.5 * ((np.sqrt(dense1) - np.sqrt(dense2))**2).sum())

Je ne sais pas si cela vous aidera, mais j'ai réussi à obtenir de bons résultats sur la correspondance des documents et les similitudes lors de l'utilisation du document réel comme requête.

dictionary = corpora.Dictionary.load('dictionary.dict')
corpus = corpora.MmCorpus("corpus.mm")
lda = models.LdaModel.load("model.lda") #result from running online lda (training)

index = similarities.MatrixSimilarity(lda[corpus])
index.save("simIndex.index")

docname = "docs/the_doc.txt"
doc = open(docname, 'r').read()
vec_bow = dictionary.doc2bow(doc.lower().split())
vec_lda = lda[vec_bow]

sims = index[vec_lda]
sims = sorted(enumerate(sims), key=lambda item: -item[1])
print sims

Votre score de similarité entre tous les documents résidant dans le corpus et le document qui a été utilisé comme requête sera le deuxième index de chaque sim pour les sims.


Les réponses fournies sont bonnes, mais elles ne sont pas très adaptées aux débutants. Je veux commencer par former le modèle LDA et calculer la similarité cosinus.

Partie du modèle d'entraînement :

docs = ["latent Dirichlet allocation (LDA) is a generative statistical model", 
        "each document is a mixture of a small number of topics",
        "each document may be viewed as a mixture of various topics"]

# Convert document to tokens
docs = [doc.split() for doc in docs]

# A mapping from token to id in each document
from gensim.corpora import Dictionary
dictionary = Dictionary(docs)

# Representing the corpus as a bag of words
corpus = [dictionary.doc2bow(doc) for doc in docs]

# Training the model
model = LdaModel(corpus=corpus, id2word=dictionary, num_topics=10)

Pour extraire la probabilité attribuée à chaque thème d'un document, il existe généralement deux manières. Je fournis ici les deux :

# Some preprocessing for documents like the training the model
test_doc = ["LDA is an example of a topic model",
            "topic modelling refers to the task of identifying topics"]
test_doc = [doc.split() for doc in test_doc]
test_corpus = [dictionary.doc2bow(doc) for doc in test_doc]

# Method 1
from gensim.matutils import cossim
doc1 = model.get_document_topics(test_corpus[0], minimum_probability=0)
doc2 = model.get_document_topics(test_corpus[1], minimum_probability=0)
print(cossim(doc1, doc2))

# Method 2
doc1 = model[test_corpus[0]]
doc2 = model[test_corpus[1]]
print(cossim(doc1, doc2))

sortie :

#Method 1
0.8279631530869963

#Method 2
0.828066885140262

Comme vous pouvez le voir, les deux méthodes sont généralement les mêmes, la différence réside dans les probabilités renvoyées dans la 2ème méthode, parfois ne correspond pas à un, comme indiqué ici. Pour un grand corpus, le vecteur de possibilité peut être donné en passant l'ensemble corpus :

#Method 1
possibility_vector = model.get_document_topics(test_corpus, minimum_probability=0)
#Method 2
possiblity_vector = model[test_corpus]

REMARQUE : La somme des probabilités attribuées à chaque sujet dans un document peut devenir un peu supérieure à 1 ou, dans certains cas, un peu inférieure à 1. Cela est dû aux erreurs d'arrondi arithmétique à virgule flottante.