致敬褚先生:pyLDAvis可视化不认输的一生
3月5日,我最敬佩的企业家褚时健去世。相信我们每个人都听过褚老的事迹,在学习话题模型可视化前,我们感受下褚老先生不认输的传奇一生
14岁父亲去世 31岁被打成右派,农场改造 51岁奋斗18年打造出红塔山,为国家创税991亿 71岁锒铛入狱,连累唯一的女儿狱中自杀 74岁老夫妻俩承包2400亩荒地种植橙子 87岁身价过亿 91岁,仙逝
今天我想分析下文青最集中的知乎是怎么看待褚老精神的。数据采集方式详见
爬虫实战:抓取知乎问题 ,文章末尾会提供本文的原始数据和jupyter notebook下载方式。本文使用LDA话题模型看看关于褚老一生都有哪些话题
读取数据
首先我们读取知乎问题数据,我存储的字段比较多,我们先看看dataframe中有哪些字段
import pandas as pd
df = pd.read_json('data.json', lines=True)
df.columns
运行
'admin_closed_comment',
'annotation_action',
'answer_collapse_reason',
...
'content',
...
'voteup_count'
在我们的分析中,我们只分析 content 这一列的数据
#只看content列前5行
df['content'].head()
运行
0 <p>褚时健给中国企业家们诠释了什么叫百折不挠,什么叫“看成败人生豪迈,只不过是从头再来”。...
1 <p>走向巅峰无人比肩而立 ,</p><p>跌入低谷独自抚慰伤痛。</p><p>王石借巴顿的...
2 <p>褚时健,被誉为“企业家中的企业家”,他的一生大起大落,堪称真正的传奇:51岁,他建立了...
3 <p><b>光环下的褚时健也是云南改革开放的缩影,云南40年:巅峰、衰退、奋起直追...</...
4 <p>「世界上只有一种真正的英雄主义,就是认清了生活的真相后还依然热爱它」</p><p>——...
Name: content, dtype: object
数据预处理
数据预处理是文本分析的开始,也是最重要最费功夫的地方。在这部分我们将会剔除掉标点符号和停止词,只保留中文。 [\u4e00-\u9fa5]
是匹配汉字的正则表达式, 而 [^\u4e00-\u9fa5]
是匹配非汉字的内容。
#将非汉字替换为""
df['content'] = df['content'].str.replace("[^\u4e00-\u9fa5]", "")
df['content'].head()
运行
0 褚时健给中国企业家们诠释了什么叫百折不挠什么叫看成败人生豪迈只不过是从头再来褚时健在中国商界...
1 走向巅峰无人比肩而立跌入低谷独自抚慰伤痛王石借巴顿的话评价褚老衡量一个人成功的标志不是看他登...
2 褚时健被誉为企业家中的企业家他的一生大起大落堪称真正的传奇岁他建立了红塔山烟草集团这一商业帝...
3 光环下的褚时健也是云南改革开放的缩影云南年巅峰衰退奋起直追从玉龙雪山到大理洱海再到丽江小镇甚...
4 世界上只有一种真正的英雄主义就是认清了生活的真相后还依然热爱它罗曼罗兰约翰克里斯朵夫老爷子无...
Name: content, dtype: object
词云图
接下来使用pyecharts库看看原始数据中词频较高(前100)的词语,将其可视化展示出来
from pyecharts import WordCloud
def word_freqs(documents, max_words = 100):
#默认返回前100个高频词
words = []
[words.extend(jieba.lcut(doc)) for doc in documents]
fdist = FreqDist(words)
words_df = pd.DataFrame({'word': list(fdist.keys()),
'freq':list(fdist.values())})
return words_df['word'][:max_words], words_df['freq'][:max_words]
words, freqs = word_freqs(df['content'])
wordcloud = WordCloud(width=1300, height=620)
wordcloud.add("", words, freqs, word_size_range=[20, 100])
#wordcloud.render()
wordcloud
从上面的图片中我们发现较大的词语都是无意义的词语(或有的词语长度为1),所以我们应该使用停止词,并且只保留词语长度大于2的词语。
我们使用pandas中的df.agg方法对content列实行数据清洗操作。操作函数的功能:
分词
去除停用词和长度小于2的词语
import nltk
import jieba
#停止词
stopwords = nltk.corpus.stopwords.words('chinese')
def clean_text(text):
wordlist = jieba.lcut(text)
document = [w for w in wordlist if w not in stopwords and len(w)>2]
return document
df['content'] = df.agg({'content': clean_text})
df['content'].head()
运行
0 [褚时健, 企业家, 百折不挠, 只不过, 从头再来, 褚时健, 褚时健, 重振旗鼓, 亿万...
1 [比肩而立, 反弹力, 企业家]
2 [褚时健, 被誉为, 企业家, 企业家, 大起大落, 红塔山, 一无所有, 第二次, 云南省...
3 [褚时健, 改革开放, 奋起直追, 玉龙雪山, 过桥米线, 总有诉, 离不开, 褚时健, 无...
4 [英雄主义, 罗曼罗兰, 克里斯, 老爷子, 无论如何]
Name: content, dtype: object
创建LDA话题模型
创建语料库的词典空间(将文本数据按照该词语空间可以映射成相应的数字,方便机器进行学习),之后生成文档-词频矩阵(document-term-matrix)。
from gensim import corpora
import gensim
corpus = df['content']
dictionary = corpora.Dictionary(corpus)
doc_term_matrix = [dictionary.doc2bow(doc) for doc in corpus]
现在我们使用gensim.models.ldamodel.LdaModel模块来生成本语料的lda话题模型。我们大家都知道褚时健人生故事有两个话题,一个是入狱前企业家,另一个话题是70岁高龄二次创业,所以这里我们将话题数设置为num_topics=2
LDA = gensim.models.ldamodel.LdaModel
lda_model = LDA(corpus=doc_term_matrix,
id2word=dictionary,
num_topics=2, #话题数
random_state=200)
lda_model.print_topics()
运行
[(0,
'0.171*"褚时健" + 0.022*"卷烟厂" + 0.018*"企业家" + 0.015*"红塔山" + 0.013*"马静芬" + 0.012*"哀牢山" + 0.010*"年月日" + 0.009*"保外就医" + 0.009*"红塔集团" + 0.008*"乔布斯"'),
(1,
'0.146*"褚时健" + 0.021*"卷烟厂" + 0.017*"企业家" + 0.012*"年月日" + 0.011*"马静芬" + 0.011*"红塔山" + 0.007*"保外就医" + 0.007*"哀牢山" + 0.006*"云南省" + 0.005*"董事长"')]
从上面的分析结果看,每个话题中的每个词语都分配了相应的权重,我们可以粗略的定义话题0说的是褚时健V型人生的左半边(卷烟厂),话题1显示的是V型人生的右半边(二次创业)。
主题可视化
最后,我们使用 pyLDAvis库
进行话题的可视化。该库可以交互式的显示不同话题,及每个话题的相关词语。
import pyLDAvis
import pyLDAvis.gensim
#让可视化可以在notebook中显示
pyLDAvis.enable_notebook()
vis = pyLDAvis.gensim.prepare(lda_model, doc_term_matrix, dictionary)
pyLDAvis.show(vis)
等待大概几分钟,浏览器中会弹出一个LDAvis的页面。我们可以动态可视化的查看每一种话题,并能进行话题的微调。下面是我录屏,大家可以简单查看
致敬褚时健先生
往期文章
【工具篇】如何用Google Colab高效的学习Python
在微信后台回复 不认输的人生 ,即可获得本项目代码
你看到这里,你懂得