Как напечатать модель темы lda и облако слов каждой из тем
from nltk.tokenize import RegexpTokenizer
from stop_words import get_stop_words
from gensim import corpora, models
import gensim
import os
from os import path
from time import sleep
import matplotlib.pyplot as plt
import random
from wordcloud import WordCloud, STOPWORDS
tokenizer = RegexpTokenizer(r'\w+')
en_stop = set(get_stop_words('en'))
with open(os.path.join('c:\users\kaila\jobdescription.txt')) as f:
Reader = f.read()
Reader = Reader.replace("will", " ")
Reader = Reader.replace("please", " ")
texts = unicode(Reader, errors='replace')
tdm = []
raw = texts.lower()
tokens = tokenizer.tokenize(raw)
stopped_tokens = [i for i in tokens if not i in en_stop]
tdm.append(stopped_tokens)
dictionary = corpora.Dictionary(tdm)
corpus = [dictionary.doc2bow(i) for i in tdm]
sleep(3)
ldamodel = gensim.models.ldamodel.LdaModel(corpus, num_topics=8, id2word = dictionary)
topics = ldamodel.print_topics(num_topics=8, num_words=200)
for i in topics:
print(i)
wordcloud = WordCloud().generate(i)
plt.imshow(wordcloud)
plt.axis("off")
plt.show()
Проблема с облаком слова. Я не могу получить облако слов для каждой из 8 тем. Я хотел бы вывод, который дает 8 облаков слов для 8 тем. Если кто-то может помочь мне в этом вопросе, это будет здорово.
2 ответа
Предполагая, что вы обучили модель Gensim LDA, вы можете просто создать облако слов с помощью следующего кода
# lda is assumed to be the variable holding the LdaModel object
import matplotlib.pyplot as plt
for t in range(lda.num_topics):
plt.figure()
plt.imshow(WordCloud().fit_words(lda.show_topic(t, 200)))
plt.axis("off")
plt.title("Topic #" + str(t))
plt.show()
Я выделю несколько ошибок в вашем коде, чтобы вы могли лучше следовать тому, что я написал выше.
WordCloud().generate(something)
ожидает что-то, чтобы быть необработанным текстом. Он будет размечать его, ставить строчные буквы и удалять стоп-слова, а затем вычислять облако слов. Вам нужны размеры слов, чтобы соответствовать их вероятности в теме (я полагаю).
lda.print_topics(8, 200)
возвращает текстовое представление тем, как в prob1*"token1" + prob2*"token2" + ...
тебе нужен lda.show_topic(topic, num_words)
получить слово с соответствующей вероятностью в виде кортежей. Тогда вам нужно WordCloud().fit_words()
генерировать слово облако.
Следующий код - это ваш код с приведенной выше визуализацией. Я также хотел бы отметить, что вы выводите темы из одного документа, что очень редко и, вероятно, не то, что вы хотели.
from nltk.tokenize import RegexpTokenizer
from stop_words import get_stop_words
from gensim import corpora, models
import gensim
import os
from os import path
from time import sleep
import matplotlib.pyplot as plt
import random
from wordcloud import WordCloud, STOPWORDS
tokenizer = RegexpTokenizer(r'\w+')
en_stop = set(get_stop_words('en'))
with open(os.path.join('c:\users\kaila\jobdescription.txt')) as f:
Reader = f.read()
Reader = Reader.replace("will", " ")
Reader = Reader.replace("please", " ")
texts = unicode(Reader, errors='replace')
tdm = []
raw = texts.lower()
tokens = tokenizer.tokenize(raw)
stopped_tokens = [i for i in tokens if not i in en_stop]
tdm.append(stopped_tokens)
dictionary = corpora.Dictionary(tdm)
corpus = [dictionary.doc2bow(i) for i in tdm]
ldamodel = gensim.models.ldamodel.LdaModel(corpus, num_topics=8, id2word = dictionary)
for t in range(ldamodel.num_topics):
plt.figure()
plt.imshow(WordCloud().fit_words(ldamodel.show_topic(t, 200)))
plt.axis("off")
plt.title("Topic #" + str(t))
plt.show()
Хотя из другой библиотеки вы можете увидеть визуализации тем с соответствующим кодом для получения результата (отказ от ответственности: я являюсь одним из авторов этой библиотеки).
Для меня сработало следующее: во-первых, создайте модель lda и определите кластеры / темы, как обсуждалось в разделе Кластеризация тем. Убедитесь, что минимальная_проблемность равна 0. Затем определите корпус LDA, используя lda_corpus = lda[corpus]
Теперь идентифицируйте документы по данным, относящимся к каждой теме, в виде списка, в приведенном ниже примере есть две темы. DF мои необработанные данные, которые имеют текст столбца
cluster1 = [j for i,j in zip(lda_corpus,df.texts) if i[0][1] > .2]
cluster2 = [j for i,j in zip(lda_corpus,df.texts) if i[1][1] > .2]
Получите Облако слов для каждого кластера. Вы можете включить как можно больше стоп-слов. Обязательно очистите данные в кластере, например, удалите стоп-слова, основы и т. Д. Я пропускаю эти шаги, чтобы в каждом кластере были очищенные тексты / документы.
wordcloud = WordCloud(relative_scaling = 1.0, stopwords=("xxx", 'yyy').generate(' '. join(cluster1))
Наконец, составьте облако слов, используя matplotlib
plt.imshow(wordcloud)