LDA(Latent Dirichlet Allocation)是一种文档主题生成模型,也称为一个三层贝叶斯概率模型,包含词、主题和文档三层结构。所谓生成模型,就是说,我们认为一篇文章的每个词都是通过“以一定概率选择了某个主题,并从这个主题中以一定概率选择某个词语”这样一个过程得到。文档到主题服从多项式分布,主题到词服从多项式分布。
LDA是一种非监督机器学习技术,可以用来识别大规模文档集(document collection)或语料库(corpus)中潜藏的主题信息。它采用了词袋(bag of words)的方法,这种方法将每一篇文档视为一个词频向量,从而将文本信息转化为了易于建模的数字信息。但是词袋方法没有考虑词与词之间的顺序,这简化了问题的复杂性,同时也为模型的改进提供了契机。每一篇文档代表了一些主题所构成的一个概率分布,而每一个主题又代表了很多单词所构成的一个概率分布。
关键词:文档主题生成模型,无监督学习,概率模型,NLP
对于语料库中的每篇文档,LDA定义了如下生成过程(generativeprocess):
1.对每一篇文档,从主题分布中抽取一个主题;一行表示一篇文档;
2.从上述被抽到的主题所对应的单词分布中抽取一个单词;
3.重复上述过程直至遍历文档中的每一个单词。
语料库中的每一篇文档与T(通过反复试验等方法事先给定)个主题的一个多项分布 (multinomialdistribution)相对应,将该多项分布记为θ。每个主题又与词汇表(vocabulary)中的V个单词的一个多项分布相对应,将这个多项分布记为φ。
具体推导可以参考:一文详解LDA主题模型 - 知乎
数据
_1kb8k8sj 挺好挺好星期再评价大陆国行全新丰发货隔天收收拍开箱视频马上转移数提示定数转完新手机软件下好进去再抹前旧手机数 已利安全下车位友友入手游戏挺好毕竟官网平台便宜百块 安全下车力奥力都说14挤牙膏觉很好毕竟6sp跳 拼百亿补贴买开始还担心不翻新机次核发现正儿八新机官网门店便宜百良心卖家 很不错 拍清晰 不发热 电池系统流畅界面美观 色彩饱度不错查序列号正品未激活 安全下车 抱五十五十决定拼买百亿补贴省百全新没激活买放心三天收货卖家好力不资源机不高仿全新机 安全下车前小担心真没必10月2号下单3号发货5号收拆箱查询全新未激活外观完美无瑕疵河北南京发货天机时间长拍清晰系统流畅
代码
import jieba
import jieba.posseg as jp
from gensim import corpora, models
'''
来源
https://cloud.tencent.com/developer/article/1827121?from=15425
'''
# Global Dictionary
new_words = ['奥预赛', '折叠屏'] # 新词
stopwords = {' ', '再', '的', '们', '为', '时', ':'} # 停用词
synonyms = {'韩国': '南朝鲜', '传言': '流言'} # 同义词
words_nature = ('n', 'nr', 'ns', 'nt', 'eng', 'v', 'd') # 可用的词性
def add_new_words(): # 增加新词
for i in new_words:
jieba.add_word(i)
def remove_stopwords(ls): # 去除停用词
return [word for word in ls if word not in stopwords]
def replace_synonyms(ls): # 替换同义词
return [synonyms[i] if i in synonyms else i for i in ls]
with open('out_pdd_remove_stop_word.txt', 'r', encoding='UTF-8') as f:
documents = f.readlines()
documents = [c.strip() for c in documents]
'''
documents = [
'足协申请取消女足奥预赛韩国主场比赛 公平原则保障安全',
'芬森发声再回应传言:想念辽宁队友 为中国的球迷们祈福',
'电商围剿涉疫商家进行时:哄抬物价,就这么罚你',
'今晚视频直播华为新品发布会:全新折叠屏手机亮相']
'''
add_new_words()
words_ls = []
for text in documents:
words = replace_synonyms(remove_stopwords([w.word for w in jp.cut(text)]))
words_ls.append(words)
# 生成语料词典
dictionary = corpora.Dictionary(words_ls)
# 生成稀疏向量集
corpus = [dictionary.doc2bow(words) for words in words_ls]
# LDA模型,num_topics设置聚类数,即最终主题的数量
lda = models.ldamodel.LdaModel(corpus=corpus, id2word=dictionary, num_topics=4)
# 展示每个主题的前5的词语
for topic in lda.print_topics(num_words=5):
print(topic)
# 推断每个语料库中的主题类别
print('推断:')
for e, values in enumerate(lda.inference(corpus)[0]):
topic_val = 0
topic_id = 0
for tid, val in enumerate(values):
if val > topic_val:
topic_val = val
topic_id = tid
print(topic_id, '->', documents[e])
结果
(0, '0.033*"不" + 0.028*"全新" + 0.026*"好" + 0.023*"机" + 0.023*"卖家"')
(1, '0.033*"不错" + 0.025*"清晰" + 0.025*"未激活" + 0.024*"拍" + 0.023*"系统"')
(2, '0.026*"好" + 0.025*"安全" + 0.024*"下车" + 0.021*"挺" + 0.020*"_"')
(3, '0.032*"号" + 0.028*"发货" + 0.025*"下车" + 0.024*"安全" + 0.022*"好"')
推断:
2 -> _1kb8k8sj
0 -> 挺好挺好星期再评价大陆国行全新丰发货隔天收收拍开箱视频马上转移数提示定数转完新手机软件下好进去再抹前旧手机数 已利安全下车位友友入手游戏挺好毕竟官网平台便宜百块
2 -> 安全下车力奥力都说14挤牙膏觉很好毕竟6sp跳
0 -> 拼百亿补贴买开始还担心不翻新机次核发现正儿八新机官网门店便宜百良心卖家
1 -> 很不错 拍清晰 不发热 电池系统流畅界面美观 色彩饱度不错查序列号正品未激活 安全下车
0 -> 抱五十五十决定拼买百亿补贴省百全新没激活买放心三天收货卖家好力不资源机不高仿全新机
3 -> 安全下车前小担心真没必10月2号下单3号发货5号收拆箱查询全新未激活外观完美无瑕疵河北南京发货天机时间长拍清晰系统流畅