После применения моделирования тем LDA от gensim, как получить документы с наибольшей вероятностью для каждой темы и сохранить их в CSV-файле? - PullRequest
2 голосов
/ 01 июня 2019

Я использовал gensim LDA Topic Modeling для получения связанных тем из корпуса. Теперь я хочу получить 20 лучших документов, представляющих каждую тему: документы, которые имеют наибольшую вероятность в теме. И я хочу сохранить их в CSV-файле в следующем формате: 4 столбца для идентификатора темы, слова темы, вероятность каждого слова в теме, 20 лучших документов для каждой темы.

Я пробовал get_document_topics, который, я думаю, является лучшим подходом для этой задачи:

all_topics = lda_model.get_document_topics (корпус, минимум_проблемости = 0.0, per_word_topics = False)

Но я не уверен, как получить 20 лучших документов, которые лучше всего представляют тему, и добавить их в файл CSV.

    data_words_nostops = remove_stopwords(processed_docs)
    # Create Dictionary
    id2word = corpora.Dictionary(data_words_nostops)
    # Create Corpus
    texts = data_words_nostops
    # Term Document Frequency
    corpus = [id2word.doc2bow(text) for text in texts]
    # Build LDA model
    lda_model = gensim.models.ldamodel.LdaModel(corpus=corpus,
                                               id2word=id2word,
                                               num_topics=20,
                                               random_state=100,
                                               update_every=1,
                                               chunksize=100,
                                               passes=10,
                                               alpha='auto',
                                               per_word_topics=True)

    pprint(lda_model.print_topics())
    #save csv
    fn = "topic_terms5.csv"
    if (os.path.isfile(fn)):
        m = "a"
    else:
        m = "w"

    num_topics=20
    # save topic, term, prob data in the file
    with open(fn, m, encoding="utf8", newline='') as csvfile:
        fieldnames = ["topic_id", "term", "prob"]
        writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
        if (m == "w"):
            writer.writeheader()

        for topic_id in range(num_topics):
            term_probs = lda_model.show_topic(topic_id, topn=6)
            for term, prob in term_probs:
                row = {}
                row['topic_id'] = topic_id
                row['prob'] = prob
                row['term'] = term
                writer.writerow(row)

Ожидаемый результат: CSV-файл в этом формате: 4 столбца для идентификатора темы, слова темы, вероятность каждого слова, 20 лучших документов для каждой темы.

1 Ответ

0 голосов
/ 29 июня 2019

Во-первых, каждый документ имеет вектор темы, список кортежей, который выглядит следующим образом:

[(0, 3.0161273e-05), (1, 3.0161273e-05), (2, 3.0161273e-05), (3, 3.0161273e-05), (4, 
3.0161273e-05), (5, 0.06556476), (6, 0.14744747), (7, 3.0161273e-05), (8, 3.0161273e- 
05), (9, 3.0161273e-05), (10, 3.0161273e-05), (11, 0.011416071), (12, 3.0161273e-05), 
(13, 3.0161273e-05), (14, 3.0161273e-05), (15, 0.057074558), (16, 3.0161273e-05), 
(17, 3.0161273e-05), (18, 3.0161273e-05), (19, 3.0161273e-05), (20, 0.7178939), (21, 
 3.0161273e-05), (22, 3.0161273e-05), (23, 3.0161273e-05), (24, 3.0161273e-05)]

Где, например, (0, 3.0161273e-05), 0 - это идентификатор темы, и3.0161273e-05 - вероятность.

Вам необходимо преобразовать эту структуру данных в форму, чтобы можно было сравнивать документы.

Here is what you can do: 

#Create a dictionary, with topic ID as the key, and the value is a list of tuples 
(docID, probability of this particular topic for the doc) 

topic_dict = {i: [] for i in range(20}  # Assuming you have 20 topics. 

#Loop over all the documents to group the probability of each topic

for docID in range(num_docs):
    topic_vector = lda_model[corpus[docID]]
    for topicID, prob in topic_vector:
        topic_dict[topicID].append(docID, prob)

Then, you can sort the dictionary to find the top 20 documents:

for topicID, doc_probs in topic_dict.items():
    doc_probs = sorted(probs, key = lambda x: x[1], reverse = True)
    docs_top_20 = [dp[0] for dp in doc_probs[:20]]  

Вы получаете тему по 20 документов для каждой темы.Вы можете собрать в список (это будет список списков) или словарь, так что они могут быть выведены.

...