[NLP]LDA主題模型的python實現


在做主題聚類時,主要經過以下幾個步驟:

1、數據清洗:因為我是基於新浪微博來做主題的,所以需要先清洗掉數據中的各種表情符號(emoji等),以及多余的符號,清洗后再去重,會發現數據量少很多。

2、分詞:這里我使用的是jieba分詞,並使用了專用的詞典(user_dict.txt),同時網上下載了stopwords.txt

3、lda模型訓練:這里經過了建立詞典、轉換文本為索引並計數、計算tf-idf值、訓練lda模型等步驟,具體代碼如下所述(轉載自博客:https://www.jianshu.com/p/9918cd4d09c1,親測有效):

# -*- coding:utf-8 -*-
"
Created on Mon Aug 19 14:56:19 2019
@author: Luxuriant
"

import numpy as np
from gensim import corpora, models, similarities
from pprint import pprint
import time

# import logging
# logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)

def load_stopword():
    '''
    加載停用詞表
    :return: 返回停用詞的列表
    '''
    f_stop = open('stopwords.txt', encoding='utf-8')
    sw = [line.strip() for line in f_stop]
    f_stop.close()
    return sw

if __name__ == '__main__':

    print('1.初始化停止詞列表 ------')
    # 開始的時間
    t_start = time.time()
    # 加載停用詞表
    stop_words = load_stopword()

    print('2.開始讀入語料數據 ------ ')
    # 讀入語料庫
    f = open('鄉賢形象文本-cutfile.txt', encoding='utf-8')
    # 語料庫分詞並去停用詞
    texts = [[word for word in line.strip().lower().split() if word not in stop_words] for line in f]

    print('讀入語料數據完成,用時%.3f秒' % (time.time() - t_start))
    f.close()
    M = len(texts)
    print('文本數目:%d個' % M)

    print('3.正在建立詞典 ------')
    # 建立字典
    dictionary = corpora.Dictionary(texts)
    V = len(dictionary)

    print('4.正在計算文本向量 ------')
    # 轉換文本數據為索引,並計數
    corpus = [dictionary.doc2bow(text) for text in texts]

    print('5.正在計算文檔TF-IDF ------')
    t_start = time.time()
    # 計算tf-idf值
    corpus_tfidf = models.TfidfModel(corpus)[corpus]
    print('建立文檔TF-IDF完成,用時%.3f秒' % (time.time() - t_start))

    print('6.LDA模型擬合推斷 ------')
    # 訓練模型
    num_topics = 30
    t_start = time.time()
    lda = models.LdaModel(corpus_tfidf, num_topics=num_topics, id2word=dictionary,
                      alpha=0.01, eta=0.01, minimum_probability=0.001,
                      update_every=1, chunksize=100, passes=1)
    print('LDA模型完成,訓練時間為\t%.3f秒' % (time.time() - t_start))

    # 隨機打印某10個文檔的主題
    num_show_topic = 10  # 每個文檔顯示前幾個主題
    print('7.結果:10個文檔的主題分布:--')
    doc_topics = lda.get_document_topics(corpus_tfidf)  # 所有文檔的主題分布
    idx = np.arange(M)
    np.random.shuffle(idx)
    idx = idx[:10]
    for i in idx:
        topic = np.array(doc_topics[i])
        topic_distribute = np.array(topic[:, 1])
        # print topic_distribute
        topic_idx = topic_distribute.argsort()[:-num_show_topic - 1:-1]
        print('第%d個文檔的前%d個主題:' % (i, num_show_topic)), topic_idx
        print(topic_distribute[topic_idx])

    num_show_term = 10  # 每個主題顯示幾個詞
    print('8.結果:每個主題的詞分布:--')
    for topic_id in range(num_topics):
        print('主題#%d:\t' % topic_id)
        term_distribute_all = lda.get_topic_terms(topicid=topic_id)
        term_distribute = term_distribute_all[:num_show_term]
        term_distribute = np.array(term_distribute)
        term_id = term_distribute[:, 0].astype(np.int)
        print('詞:\t', )
        for t in term_id:
            print(dictionary.id2token[t], )
        print('\n概率:\t', term_distribute[:, 1])

 部分效果圖如下:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM