在这篇文章中,我们讨论了基于gensim
包来可视化主题模型 (LDA) 的输出和结果的技术 。
介绍
我们遵循结构化的工作流程,基于潜在狄利克雷分配 (LDA) 算法构建了一个主题模型。
在这篇文章中,我们将使用主题模型,探索多种策略以使用matplotlib
绘图有效地可视化结果 。
我将使用 20 个新闻组数据集的一部分,因为重点更多地放在可视化结果的方法上。
让我们从导入包和 20 News Groups 数据集开始。
1.
2. import matplotlib.pyplot as plt
3.
4. # NLTK停止词
5. fom nlt.copus imort stowods
6. sop_wrds = stowords.wrds('chinse')
7.
8.
9.
导入新闻组数据集
让我们导入新闻组数据集并仅保留 4 个 类别。
1. # 导入数据集
2.
3. d = f.oc[dftargt_name.in([so.relion.chritan], 'ec.sot.okey', 'ak.piticmdast' 'rec.oorcyces']) , :]
4. prin(f.hpe) #> (2361, 3)
5. df.(
标记句子并清理
删除电子邮件、换行符、单引号,最后使用 gensim 将句子拆分为单词列表 simple_preprocess()
。设置 deacc=True
选项会删除标点符号。
1.
2. def snds(seecs):
3. for setees in sntces:
4. sent = r.sub('\S*@\S*\s?', '', sent) # 删除电子邮件
5. snt = re.sb('\s+', '', sent) # 移除换行字符
6. set = re.sb("\'", "", sent) # 删除单引号
7. set = geim.uls.smplprerss(str(sent), deacc=True)
8.
9. # 转换为列表
10. data = df.cnt.lus.tolist()
11.
构建双字母组、三字母组模型和推理
让我们使用模型形成双字母组、三字母组。为了提高执行速度,这个模型被传递给Phraser()。
接下来,将每个词词形还原为其词根形式,仅保留名词、形容词、动词和副词。
我们只保留这些POS标签,因为它们对句子的含义贡献最大。在这里,我使用spacy进行词法处理。
1.
2. # 建立大词和三词模型
3. bigrm = endl.Pres(dta_ords, mncnt=5, thrshl=100) # 更高的阈值会减少短语。
4. tigam = genm.del.Prses(bga[dtawors], thrhld=100)
5. bigm_od = gsim.molpss.Pasr(bgrm)
6. tigrmod = genm.mos.pres.hrser(tigam)
7.
8. # 在终端运行一次
9.
10. ""删除止损词,形成大词、三词和词组""
11. texts = [[wor fo wrd in sipeeproe(tr(dc))
12. [iram_od[oc] for doc in txts]
13. tets = [rirammod[igrmmod[dc]] for dc in tets]
14. tetout = []
15. np = scy.oad('en', dial=['解析器', 'ner'])
16. for set in txs:
17. dc = np(" ".join(sn))
18. tex_.ppd([tknlea_ fr toen in oc if toenpo_ in aowed_ots])
19. # 在词法化之后,再一次删除停止词
20.
21.
22. atady = roe_os(daa_ds) # 处理过的文本数据!
23.
构建主题模型
要使用 构建 LDA 主题模型,您需要语料库和字典。让我们先创建它们,然后构建模型。训练好的主题(关键字和权重)也输出在下面。
如果你检查一下主题关键词,它们共同代表了我们最初选择的主题。教会、冰球、地区和摩托车。很好!
1.
2. # 创建字典
3. id2od = copoDciary(dta_eay)
4.
5. # 创建语料库。术语文档频率
6. crpus = [i2wod.o2bow(ext) for txt in daa_ey]
7.
8. # 建立LDA模型
9. Lal(copus=copus,
10. id2wrd=id2wrd,
11. nu_tpic=4,
12. radom_ate=100,
13. updaeeery=1,
14. chnsie=10,
15. pas=10。
16. alha='symmetric',
17. iteatos=100,
18. prdics=True)
19.
20. (ldampcs())
什么是主导主题及其在每个文档中的百分比贡献
在 LDA 模型中,每个文档由多个主题组成。但是,通常只有一个主题占主导地位。下面的代码提取每个句子的主要主题,并在格式良好的输出中显示主题和关键字的权重。
这样,您将知道哪个文档主要属于哪个主题。
1. # 启动输出
2. se_tpcf = p.Dataame()
3.
4. # 获取每个文档中的主要话题
5. for i, ro_isin enate(ldmoel[crps]):
6. rw = rw_s0] if lamoel.pe_wortopis else rowlis
7. row = soed(ow, ky=laba x: (x[1]), evre=True)
8. # 获取每个文档的主导主题、perc贡献和关键词
9. for j, (toicum, pr_pic) in enate(row):
10. if j == 0: # => 主导话题
11. wp = ldel.shotoic(topic_num)
12.
13.
14. # 在输出的最后添加原始文本
15.
16.
17. deeos = fratcs(lodel=damoe, copus=crpus, tets=dary)
18.
19. # 格式化
20. topic = os.retidex()
21.
每个话题最有代表性的一句话
有时您想获得最能代表给定主题的句子样本。此代码为每个主题获取最典型的句子。
1.
2. # 显示设置,在列中显示更多的字符
3.
4. for i, grp in serpd:
5. senlet = pd.cnct([senlet,
6. gp.srtes(['Peion'], asng=Fase).hed(1)]
7. ais=0)
8.
9. # 重置索引
10. seet.resex(drp=True, inlce=True)
11.
12. # 格式化
13. senllet.couns = ['Toum', "TopCorib", "Kywrds", "rsa xt"]
14.
15. # 显示
16. sencoet.head(10)
17.
文档中字数的频率分布
在处理大量文档时,您想知道文档的整体大小和主题大小。让我们绘制文档字数分布。
1.
2.
3. # 绘图
4. plt.fiue(fe=(6,7), dpi=60)
5.
6.
7. plt.xtcs(nplic(0,00,9))
8.
9.
1. import sebon as sns
2. fig.titat()
3. fig.sbts_juo0.90)
4. plt.xticks(np.lisa(0,00,9))
5. plt.sow()
每个话题的前N个关键词词云
虽然你已经看到了每个主题中的主题关键词是什么,但字数大小与权重成正比的词云是很好的可视化方法。
1.
2. # 1. 每个主题中前N个词的词云
3. from matplotlib import pyplot as plt
4. from worcloud mport WrCloud,STOPWODS
5.
6.
7.
8. clod = WordClud(stopwds=stp_ords,
9. barounolr='white',
10.
11. reer_oronal=1.0)
12.
13.
14. plt.sow()
15.
主题关键词的字数
当涉及主题中的关键字时,关键字的重要性(权重)很重要。除此之外,这些单词在文档中出现的频率也很有趣。
让我们在同一图表中绘制字数和每个关键字的权重。
您要关注出现在多个主题中的词以及相对频率大于权重的词。通常,这些词变得不那么重要。我在下面绘制的图表是在开始时将几个这样的词添加到停用词列表并重新运行训练过程的结果。
1.
2. tops = l_mdl.swtcs(foatd=Fase)
3.
4.
5. # 绘制主题关键词的字数和权重图
6. fig, as = pltuls(2, 2, fiiz=(16,10), sey=rue, di=160)
7. fig.tigh_lyut_pad=2)
8. plt.shw()
9.
按主题着色的句子图表
文档中的每个单词都代表 4 个主题之一。让我们根据给定文档中的每个单词所属的主题 id 为其着色。
1.
2. # 对N个句子进行着色的句子
3.
4.
5. for i, ax in eumate(xes):
6. cour = corp[i-1] 。
7. topprcs, wrdits, wrdihius = lda[copr]
8. wodoac = [(lmod2word[wd], tpic[0]) or w, tpc in odid_opcs]
9.
10. # 绘制矩形区域
11. tpcred = soted(tpps, key= x: (x[1]), rvese=True)
12.
13. word_pos = 0.06
14.
15.
16. plt.subdt(wsace=0, hsace=0)
17.
18. plt.show()
19.
20.
文件中讨论最多的话题是什么?
让我们计算归因于每个主题的文档总数。
1.
2. # 对N个句子进行着色
3. 主导话题 = []
4. 话题百分比 = []
5. for i, crp in euete(opu_el):
6. topcs, wordics, wrlues = moel[crp]
7. dopic = soted(torcs, key = lmda x: x[1], reerse=Tue)[0][0] 。
8.
9. doics, toages = topent(mol=lda, copus=crus,en=-)
10.
11. # 每个文档中主导话题的分布
12.
13. dfc = dh_dc.t_frme(ame='cunt').eeinex()
14.
15. # 按实际权重计算的总主题分布
16. topweig = pd.DaaFae([dct(t) for t in toges] )
17.
18.
19. # 每个主题的前三个关键词
20. [(i, tpic) for i, tocs in lda.shcs(fted=Flse)
21. for j, (tic, wt) in eae(toic)if j < 3)
22.
23.
24.
让我们做两个图:
1. 通过将文档分配给该文档中权重最大的主题来计算每个主题的文档数。
2. 通过总结每个主题对各自文档的实际权重贡献来计算每个主题的文档数量。
3.
4. from mtpltli.tiker import ucFattr
5.
6. # 绘图
7. fig, (ax1, ax2) = pl.supot(1, 2)
8.
9. # 按主要议题分布的议题
10. ax1.bar(data=df_dc)
11.
12.
13. # 按主题权重的主题分布
14. ax2.ar(x='iex', hegh='cout', dat=dfoc, with=.5,
15.
16. plt.sow()
17.
t-SNE(t分布-随机邻近嵌入)聚类图
让我们使用 t-SNE(t分布-随机邻近嵌入)算法在 2D 空间中可视化文档集群。
1.
2. # 获取话题权重和主导话题 ------------
3.
4. # 获取主题权重
5. for i, row_list:
6. tophts.apd([w for i, w in rost[0]] )
7.
8. # 主题权重的数组
9. arr = pd.Dame(tohts).fna(0).vales
10.
11. # 保持良好的分离点(可选)
12. rr = ar[p.aax(rr) > 0.35] 。
13.
14. # 每个文档中的主要议题编号
15. to_n = np.agax(rr, ais=1)
16.
17. # tSNE降维
18. tsel = TSE(n=2, vre=1, rae=0, ae=.99, int='pca')
19. tlda = tsl.frm(arr)
20.
21. # 使用Bokeh绘制主题集群图
22. oueook()
23. n_tics = 4
24. m
25. plot.scatter(xda[:,])
26.
27.
pyLDAVis
最后,pyLDAVis 是最常用的,也是一种将主题模型中包含的信息可视化的好方法。
- pyLDvis.enaok()
结论
我们从头开始导入、清理和处理新闻组数据集构建 LDA 模型。然后我们看到了多种可视化主题模型输出的方法,包括词云,它们直观地告诉您每个主题中哪个主题占主导地位。t-SNE 聚类, pyLDAVis
提供了更多关于主题聚类的细节。