赞
踩
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
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')
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')
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。