手把手教你学会LDA话题模型可视化pyLDAvis库

手把手教你学会LDA话题模型可视化pyLDAvis库


作者 | 大邓

来源 | 数据森麟大邓和他的Python


pyLDAvis是话题模型交互式可视化库,最初是在R语言社区的Carson Sievert和Kenny Shirley开发的。他们俩的努力使得话题可视化成为可能,现在pyLDAvis可以通过python特别是jupyter notebook来分析并可视化话题模型。如果你对pyLDAvis的运行原理感兴趣,建议你阅读这篇论文。


LDAvis: A method for visualizing and interpreting topics 

https://nlp.stanford.edu/events/illvi2014/papers/sievert-illvi2014.pdf


pyLDAvis安装




pip install pyldavis


一、pyLDAvis使用方法


导入模型语法


pyLDA需要先导入模型,支持的模型的来源有三种:


  • sklearn的lda模型

  • gensim的lda模型

  • graphlab的lda模型


导入的语法




import pyLDAvis

data = pyLDAvis.sklearn.prepare(sklearn_lda, sklearn_dtm, vectorizer)
#data = pyLDAvis.gensim.prepare(gensim_lda, gensim_dtm, dictionary)
#data = pyLDAvis.graphlab.prepare(topic_model, docs)


参数解读:


  • sklearnlda/gensimlda: 计算好的话题模型

  • sklearndtm/gensimdtm: 文档词频矩阵

  • vectorizer/dictionary: 词语空间

  • topic_model: graphlab生成的话题模型

  • docs: 语料集


graphlab我们没有学习,之后的课程可能会讲到。gensim和sklearn我们都接触过,而且昨天我们分享的教程是gensim方式生成话题模型,今天我们主要是看看sklearn方式生成的话题模型的可视化。其实不管哪一种模型生成方式,使用方法基本类似。


可视化语法



pyLDAvis.displace(data) 在notebookoutput cell中显示

pyLDAvis.show(data)  在浏览器中心打开一个界面


二、实战


我们做pyLDAvis话题模型可视化,步骤分为:


  • 数据读取

  • 预处理

  • 生成文档词频矩阵

  • 生成LDA模型

  • pyLDAvis可视化


数据读取


昨天我分享的内容作为话题分析实际上略微有些牵强,因为对褚时健先生讨论其实主要是他的不认输精神,本质上话题之间界限很模糊。今天我专门从知乎上采集了大学生创业、学术圈两种数据源。



import pandas as pd

df = pd.read_json('data.json', lines=True)
#删除content字段重复的数据
df.drop_duplicates(subset='content',inplace=True)  
#内容存储在content列
df['content'].head()


运行



我们假设现在数据在采集或者保存过程中,丢失了话题类别的标注。但是我们知道数据大概有四类,按照话题数等于2去做话题分析,理论上应该能区分开。整个 df['content'] 作为我们研究的语料库,语料库中的每一行数据是一个文档。




#随机的从content列中抽取5个文档
df['content'].sample(5)



运行



1204    <p>清华计算机博士在读。</p><p>更新:</p><p>沃德天呐我居然也有百赞的的回答了...
324     国家奖学金八千,与奖学金不可兼得,如有助学金则助学金降档;<br>新鸿基等奖学金性质助学金五...
2049    <p>几年前,学院的副院长和正院长。一个喜欢搞女学生出了名,一个喜欢搞男学生出了名。</p>...
1099    <p>利益相关,匿名;</p><p>爆一个学术圈 的 禽兽大佬王</p><h2>王红星</h...
3       <p><b>
史上最全兼职汇总来袭!!</b></p><p><b>深入分析17种兼职的优缺点网...
Name: content, dtype: object


预处理


数据预处理是文本分析的开始,也是最重要最费功夫的地方。上面的数据我们看到有很多html标签,在这部分我们将剔除非中文字符,只保留中文。而且要保证进入语料库中的文本是长文本(比如在这里我们只要长度大于20的文本保留到语料库中)。



[\u4e00-\u9fa5]  是匹配汉字的正则表达式
[^\u4e00-\u9fa5] 是匹配非汉字的内容


将非汉字替换为""



df['content'] = df['content'].str.replace("[^\u4e00-\u9fa5]""")
df['content'].head(10)


运行




0     统一回复了一些知友的问题请拉到文章底部大学赚真的非常简单不吹不作绝对每个人都能做到前提是你去...
1     补充统一回答知友评论和私信的问题请拉到本文底部本文多图毕业了**个月呢盘算着要不要过个百天纪...
2     岁末年终以此回顾大学的艰苦岁月也为余下的半年不到时光开个新头十年间所赚的钱一万不止光学费和生...
3     史上最全兼职汇总来袭深入分析种兼职的优缺点网络骗术超级干货高能预警先介绍自己年二本市场营销专...
4     为什么只赚一万块只赚一万块学费生活费是有了那谈恋爱的花销你考虑没有还有学生时代的时间最是充沛...
9     一直关注知乎很久了第一次答题小紧张本人大三在读中国传媒大学信息工程学院数字媒体技术专业女汉子...
14    首先说一下我的情况我在读研期间赚了万是我的第一桶金在大学没赚多少钱主要靠奖学金养活哈哈因为大...
19    大学四年挣了有来万元吧没花多少时间基本是靠技术挣钱的背景介绍本人是级本科生专业为计算机科学与...
24    这是更新的内容原文在下面一觉醒来发现知乎已炸好多私信啊你问我滋不滋瓷啊呸你问我要卖不卖我当然...
29    看到这个话题我的兴趣就来了因为佛大毕业一年读书那会赚了左右做到现在累积都有了说说我赚的第一个...

Name: content, dtype: object


语料库中可能因为剔除非中文后,内容已经非常简短,为防止短文本进入语料库,我这里设置长度大于10的才能进入语料库中。




def length_bigger_than_10(text):
if len(text)>=10:
return True
else:
return False

#新建length列
df['length'] = df.agg({'content': length_bigger_than_10})
#根据length列来保留长度大于10的文本,并将其放入新的dataframe中
newdf = df[df['length']==True]


生成文档词频矩阵


做文本分析,尤其是涉及到sklearn机器学习。我们需要将中文文本数据整理成sklearn能懂的形式,因为sklearn最初只是为西方语言设计的,而西方文本中的单词是以空格间隔,而中文是所有的字词没有空格间隔。所以我们需要设计一个文本清洗函数:


  • 先分词

  • 剔除无意义词语和长度小于2的词语

  • 之后用空格间隔词语




import nltk
import jieba

#停止词
stopwords = nltk.corpus.stopwords.words('chinese')

def clean_text(text):
    wordlist = jieba.lcut(text) 
#去除停用词和长度小于2的词语
    wordlist = [w for w in wordlist if w not in stopwords and len(w)>2]
#将中文数据组织成类似西方于洋那样,词语之间以空格间隔
    document =  " ".join(wordlist)
return document

#使用dataframe.agg对content列实行clean_text方法
newdf['content'] = newdf.agg({'content': clean_text})
corpus = newdf['content']
corpus.head()


运行



0    请拉到 非常简单 不吹不作 毒文先 两万左右 说真的 干什么 好好学习 没什么 几十年 好好...
1    请拉到 盘算着 纪念日 拼了命 成功率 生活费 双学位 有利于 奖学金 歪打正着 体力活 零...
2    十年间 生活费 沾沾自喜 洋洋得意 喜众君 懵懵懂懂 一个月 生活费 勉勉强强 十几年 零零...
3    深入分析 优缺点 市场营销 尽量避免 具体操作 马赛克 马赛克 深入分析 优缺点 适用范围 ...
4    一万块 一万块 生活费 谈恋爱 寒暑假 年轻人 雄心壮志 两万块 银行卡 第一笔 第二笔 有...
Name: content, dtype: object


创建LDA话题模型


在这里我们使用sklearn生成LDA话题模型,一般做LDA时我们都有对研究数据有大致的了解。像我知道数据包含两类(大学生创业、学术圈),所以这里我们将话题数设置为n_components=2




import pyLDAvis
import pyLDAvis.sklearn
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.decomposition import LatentDirichletAllocation

vectorizer = CountVectorizer()
doc_term_matrix = vectorizer.fit_transform(corpus)
lda_model = LatentDirichletAllocation(n_components=2, random_state=888)
lda_model.fit(doc_term_matrix)


运行




LatentDirichletAllocation(batch_size=128, doc_topic_prior=None,
             evaluate_every=-1, learning_decay=0.7,
             learning_method='batch', learning_offset=10.0,
             max_doc_update_iter=100, max_iter=10, mean_change_tol=0.001,
             n_components=2, n_jobs=None, n_topics=None, perp_tol=0.1,
             random_state=888, topic_word_prior=None,
             total_samples=1000000.0, verbose=0)


pyLDAvis可视化


最后,我们使用pyLDAvis库进行话题的可视化。该库可以交互式的显示不同话题,及每个话题的相关词语。


导入模型方法



pyLDAvis.sklearn.prepare(lda_modeldoc_term_matrixvectorize


可视化方法




pyLDAvis.displace(data) 在notebookoutput cell中显示
pyLDAvis.show(data)  在浏览器中心打开一个界面


执行下方可视化代码




import pyLDAvis
import pyLDAvis.gensim

data = pyLDAvis.sklearn.prepare(lda_model, doc_term_matrix, vectorizer)
#让可视化可以在notebook内显示
pyLDAvis.display(data)


手把手教你学会LDA话题模型可视化pyLDAvis库


pyLDAvis可以进行参数微调,在上面的动态图我调整了lambda参数,词语的权重就发生了变化。综合图中的特征词分布来看,话题1是学术圈话题,话题2是大学生创业。


(本文为AI科技大本营转载文章,转载请联系原作者)


手把手教你学会LDA话题模型可视化pyLDAvis库


推荐阅读:

                      手把手教你学会LDA话题模型可视化pyLDAvis库


Python大本营“号内搜”功能全新升级

搜索功能更强大,请在公众号菜单栏体验