web-dev-qa-db-fra.com

Distribution des sujets: comment voir quel document appartient à quel sujet après avoir exécuté LDA en python

Je peux exécuter le code LDA à partir de gensim et obtenir le top 10 des sujets avec leurs mots-clés respectifs.

J'aimerais maintenant aller un peu plus loin pour voir à quel point l'algo de la LDA est précis en consultant le document qu'ils classent dans chaque sujet. Est-ce possible dans les gensim LDA?

En gros, je voudrais faire quelque chose comme ça, mais en python et en utilisant le gensim.

LDA avec topicmodels, comment voir à quels sujets appartiennent différents documents?

19
jxn

En utilisant les probabilités des rubriques, vous pouvez essayer de définir un seuil et de l’utiliser comme référence pour la mise en cluster, mais je suis sûr qu’il existe de meilleurs moyens de procéder à la mise en cluster que cette méthode «hacky».

from gensim import corpora, models, similarities
from itertools import chain

""" DEMO """
documents = ["Human machine interface for lab abc computer applications",
             "A survey of user opinion of computer system response time",
             "The EPS user interface management system",
             "System and human system engineering testing of EPS",
             "Relation of user perceived response time to error measurement",
             "The generation of random binary unordered trees",
             "The intersection graph of paths in trees",
             "Graph minors IV Widths of trees and well quasi ordering",
             "Graph minors A survey"]

# remove common words and tokenize
stoplist = set('for a of the and to in'.split())
texts = [[Word for Word in document.lower().split() if Word not in stoplist]
         for document in documents]

# remove words that appear only once
all_tokens = sum(texts, [])
tokens_once = set(Word for Word in set(all_tokens) if all_tokens.count(Word) == 1)
texts = [[Word for Word in text if Word not in tokens_once] for text in texts]

# Create Dictionary.
id2Word = corpora.Dictionary(texts)
# Creates the Bag of Word corpus.
mm = [id2Word.doc2bow(text) for text in texts]

# Trains the LDA models.
lda = models.ldamodel.LdaModel(corpus=mm, id2Word=id2Word, num_topics=3, \
                               update_every=1, chunksize=10000, passes=1)

# Prints the topics.
for top in lda.print_topics():
  print top
print

# Assigns the topics to the documents in corpus
lda_corpus = lda[mm]

# Find the threshold, let's set the threshold to be 1/#clusters,
# To prove that the threshold is sane, we average the sum of all probabilities:
scores = list(chain(*[[score for topic_id,score in topic] \
                      for topic in [doc for doc in lda_corpus]]))
threshold = sum(scores)/len(scores)
print threshold
print

cluster1 = [j for i,j in Zip(lda_corpus,documents) if i[0][1] > threshold]
cluster2 = [j for i,j in Zip(lda_corpus,documents) if i[1][1] > threshold]
cluster3 = [j for i,j in Zip(lda_corpus,documents) if i[2][1] > threshold]

print cluster1
print cluster2
print cluster3

[out]:

0.131*trees + 0.121*graph + 0.119*system + 0.115*user + 0.098*survey + 0.082*interface + 0.080*eps + 0.064*minors + 0.056*response + 0.056*computer
0.171*time + 0.171*user + 0.170*response + 0.082*survey + 0.080*computer + 0.079*system + 0.050*trees + 0.042*graph + 0.040*minors + 0.040*human
0.155*system + 0.150*human + 0.110*graph + 0.107*minors + 0.094*trees + 0.090*eps + 0.088*computer + 0.087*interface + 0.040*survey + 0.028*user

0.333333333333

['The EPS user interface management system', 'The generation of random binary unordered trees', 'The intersection graph of paths in trees', 'Graph minors A survey']
['A survey of user opinion of computer system response time', 'Relation of user perceived response time to error measurement']
['Human machine interface for lab abc computer applications', 'System and human system engineering testing of EPS', 'Graph minors IV Widths of trees and well quasi ordering']

Juste pour que ce soit plus clair:

# Find the threshold, let's set the threshold to be 1/#clusters,
# To prove that the threshold is sane, we average the sum of all probabilities:
scores = []
for doc in lda_corpus
    for topic in doc:
        for topic_id, score in topic:
            scores.append(score)
threshold = sum(scores)/len(scores)

Le code ci-dessus est la somme du score de tous les mots et de toutes les rubriques de tous les documents. Normalisez ensuite la somme par le nombre de scores.

24
alvas

Si vous voulez utiliser le truc de

cluster1 = [j for i,j in Zip(lda_corpus,documents) if i[0][1] > threshold]
cluster2 = [j for i,j in Zip(lda_corpus,documents) if i[1][1] > threshold]
cluster3 = [j for i,j in Zip(lda_corpus,documents) if i[2][1] > threshold]

dans la réponse précédente de alvas, assurez-vous de définir minimum_probability = 0 dans LdaModel

gensim.models.ldamodel.LdaModel(corpus,
            num_topics=num_topics, id2Word = dictionary,
            passes=2, minimum_probability=0)

Sinon, la dimension de lda_corpus et des documents risque de ne pas concorder car gensim supprimera tout corpus avec une probabilité inférieure à minimum_probability.

Une autre façon de regrouper des documents en sujets consiste à attribuer des sujets en fonction de la probabilité maximale.

    lda_corpus = [max(prob,key=lambda y:y[1])
                    for prob in lda[mm] ]
    playlists = [[] for i in xrange(topic_num])]
    for i, x in enumerate(lda_corpus):
        playlists[x[0]].append(documents[i])

Note lda[mm] est en gros une liste de listes ou une matrice 2D. Le nombre de lignes est le nombre de documents et le nombre de colonnes est le nombre de sujets. Chaque élément de la matrice est un tuple de la forme (3,0.82) par exemple. Ici 3 fait référence à l'index du sujet et 0.82 la probabilité correspondante d'être de ce sujet. Par défaut, minimum_probability=0.01 et tout tuple avec une probabilité inférieure à 0,01 est omis dans lda[mm]. Vous pouvez le définir sur 1/# sujets si vous utilisez la méthode de regroupement avec probabilité maximale. 

8
nos

lda_corpus [i] [j] sont de la forme [(0, t1), (0, t2) ..., (0, t10), .... (n, t10)] où le premier terme désigne le document index et le 2ème terme indique la probabilité du sujet dans ce document particulier.

0
ayushi