当前位置:   article > 正文

lda模型实战篇

lda模型实战

lda简介(理论部分见lda模型理论篇)

1、lda是一种无监督的贝叶斯模型:
P(词 | 文档)=P(词 | 主题)P(主题 | 文档)
同一主题下,某个词出现的概率,以及同一文档下,某个主题出现的概率,两个概率的乘积,可以得到某篇文档出现某个词的概率。
2、lda用来推测文档的主题分布。它可以将文档集中每篇文档的主题以概率分布的形式给出,从而通过分析一些文档抽取出它们的主题分布后,便可以根据主题分布进行主题聚类或文本分类。
3、lda 采用词袋模型。所谓词袋模型,是将一篇文档,我们仅考虑一个词汇是否出现,而不考虑其出现的顺序。在词袋模型中,“我喜欢你”和“你喜欢我”是等价的。理论上不适用tfidf,但也可以尝试,与词袋模型相反的一个模型是n-gram,word2vec等考虑了词汇出现的先后顺序
4、但在一定可以解决一词多义及一义多次
一个词可以出现在多个主题中:一词多义
多个词会出现在同一主题中:一义多次

首先进行分词

# -*- coding:utf-8 -*-
# @time  : 11:20
# @Author:xxma
import jieba
import jieba.analyse as ana
import re
def cn(text):
    '''
    剔除特殊字符及数字,只保留中文
    :param text:
    :return:
    '''
    str = re.findall(u"[\u4e00-\u9fa5]+", text)
    return str

# 加载停用词
with open(r'E:\xxma\文本分析\停用词.txt', 'r', encoding='utf-8') as f:
    stopwords = [s.strip() for s in f.readlines()]

def jiebacut(text):
    """
    使用普通分词,sklearn中lda模型的输入,词以逗号分隔
    :param text: 原始文本
    :return:切分后的词,且用空格分隔
    """
    text=str(cn(text)).replace(' ','')
    # jieba.load_userdict(r'dict.txt') #加载自定义词典,本次不设置
    words = [w for w in jieba.lcut(text) if w not in stopwords]  # 剔除停用词
    # print(words,len(words))
    words = [w for w in words if len(words) > 2] #剔除短文本
    return ' '.join(words)


def ldajiebacut(text):
    """
    使用普通分词,gensim中lda模型的输入,词以逗号分隔
    :param text: 原始文本
    :return:切分后的词,且用空格分隔
    """
    text=str(cn(text)).replace(' ','')
    # jieba.load_userdict(r'dict.txt') #加载自定义词典,本次不设置
    words = [w for w in jieba.lcut(text) if w not in stopwords]  # 剔除停用词
    # print(words,len(words))
    words = [w for w in words if len(words) > 2] #剔除短文本
    return words
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

sklearn中的lda实战

import pandas as pd
import numpy as np
from sklearn.feature_extraction.text import CountVectorizer, TfidfVectorizer
from sklearn.decomposition import LatentDirichletAllocation
from 文本分析.分词 import jiebacut, tfidfcut

# 加载数据
df = pd.read_csv(r'contentLDA.txt').drop_duplicates()
# df = df.iloc[0:1000,:]
# 分词
df['cut'] = df['content'].apply(jiebacut)
df['len'] = df['cut'].apply(len)
df = df[df['len'] > 0].reset_index(drop=True)

# 使用词频生成词向量
Vectorizer = CountVectorizer()
vector = Vectorizer.fit_transform(df['cut'])
# 使用tfidf生成词向量
Vectorizer_tfidf = TfidfVectorizer()
vector_tfidf = Vectorizer_tfidf.fit_transform(df['cut'])

# lda主题模型,需要调参
# 在实际的应用中,我们需要对K,α,η进行调参。如果是"online"算法,则可能需要对"online"算法的一些参数做调整。
lda = LatentDirichletAllocation(n_components=2,  # 设置主题个数
                                max_iter=1000,
                                doc_topic_prior=0.01,
                                learning_method='online',  # 将训练样本分批用于更新主题词分布,对内存要求低,但速度较慢
                                verbose=False,
                                random_state=0)  # 是否显示迭代过程
result = lda.fit_transform(vector_tfidf)

# 提取主题对应的词
topic_words = []
def print_top_words(model, feature_names, n_top_words):
    # 打印每个主题下权重较高的term
    for topic_idx, topic in enumerate(model.components_):
        # print("Topic #%d:" % topic_idx)
        words = " ".join([feature_names[i]for i in topic.argsort()[:-n_top_words - 1:-1]])
        # print(words)
        topic_words.append(words)
    return topic_words
    # 打印主题-词语分布矩阵
    # print(model.components_)


n_top_words = 10
tf_feature_names = Vectorizer_tfidf.get_feature_names()
topic_detail = print_top_words(lda, tf_feature_names, n_top_words)

# 获取每个文档的主题
df_result = pd.DataFrame(result)
df_result['max'] = df_result.max(axis=1)
df_result['max_index'] = np.argmax(result,axis=1)
df_result['topic_words'] = df_result['max_index'].apply(lambda x:topic_detail[x])

# 数据保存
df_result = df_result[['max','max_index','topic_words']]
df = pd.DataFrame(df['content'])
df_save = df.join(df_result)
df_save.to_csv(r'contentLDA_sklearn_result.csv',sep='\t',index=False)

# 保存模型,以便后期调用
# joblib.dump(lda,'sklearn_lda.pkl')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63

gensim中lda实战

import pandas as pd
import warnings
warnings.filterwarnings('ignore')  # 警告扰人,手动封存
from 文本分析.分词 import jiebacut, tfidfcut, ldajiebacut
from gensim import corpora, models

# 加载数据
df = pd.read_csv(r'contentLDA.txt', sep='\t')
# 分词
df['cut'] = df['content'].apply(ldajiebacut)
df['len'] = df['cut'].apply(len)
df = df[df['len'] > 0].reset_index(drop=True)

# 词向量
dictionary = corpora.Dictionary(df['cut'])  # 建立词典
corpus = [dictionary.doc2bow(text) for text in df['cut']]  # 计算文本向量
# tfidf
tfidf_model = models.TfidfModel(corpus)
corpus_tfidf = tfidf_model[corpus]

# lda模型训练(自定义参数:主题个数num_topics,遍历次数passes)
topics_num = 2
ldamodel = models.ldamodel.LdaModel(corpus_tfidf
                                    , id2word=dictionary
                                    , num_topics=topics_num
                                    , passes=200
                                    , iterations=1000
                                    , alpha=0.01
                                    ,random_state=0)

# 获取主题对应的词
topics_num_list = []
for i in range(topics_num):
    topics = ldamodel.print_topic(topicno=i)
    topics_num_list.append(topics)
# print(topics_num_list)

# 获取文档对应的主题及对应的词
corpus_lda = ldamodel[corpus_tfidf]
topic_id_list = []
topic_pro_list = []
for doc in corpus_lda:
    # print(doc)
    topic_id = doc[0][0]
    topic_pro = doc[0][1]
    topic_id_list.append(topic_id)
    topic_pro_list.append(topic_pro)

df['topic']=topic_id_list
df['topic_pro']=topic_pro_list
df['topic_words'] = df['topic'].apply(lambda x:topics_num_list[x])

# 保存结果数据
df = df[['content','topic','topic_pro','topic_words']]
df.to_csv(r'contentLDA_gensim_result.csv',sep='\t',index=False,encoding='utf-8')

# 保存模型
# ldamodel.save('gensim_lda.pkl')

# 调用保存好的LDA模型
# lda = models.ldamodel.LdaModel.load('lda.model')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Li_阴宅/article/detail/928209
推荐阅读
相关标签
  

闽ICP备14008679号