#目录:
一:下载第三方Python库
二:敲代码
三:优化
一:下载第三方库
真·手把手
①安装wordcloud,打开cmd
pip install wordcloud
安装结果如下图:
②安装matplotlib
和上面一样
pip install matplotlib
WordCloud 中英文词云绘制方法汇总
摘要: 当我们手中有一篇文档,比如书籍、小说、电影剧本,若想快速了解其主要内容是什么,那么可以通过绘制WordCloud 词云图,通过关键词(高频词)就可视化直观地展示出来,非常方便。本文主要介绍常见的英文和中文文本的词云图绘制,以及通过 DataFrame 数据框绘制 Frequency 频率词云图。
1. 英文词云
这里,我们先绘制英文文本的词云图,因为它相对简单一些,这里,以《海上钢琴师》这部电影的剧本为例。
首先,需要准备好电影剧本的文本文件(如下图):
接下来,我们绘制一个最简单的矩形词云图,代码如下(lesson_1.0.py):
import osfrom os import pathfrom wordcloud import WordCloudfrom matplotlib import pyplot as plt# 获取单前文件路径d = path.dirname(__file__) if "__file__" in locals() else os.getcwd()# 获取文本texttext = open(path.join(d, 'legend1900.txt')).read()# 生成词云wc = WordCloud(scale = 2, max_font_size = 100)wc.generate_from_text(text)# 显示图像plt.imshow(wc, interpolation = 'bilinear')plt.axis('off')plt.tight_layout()# 存储图像wc.to_file('1900_basic.png')# or# plt.savefig('1900_basic.png', dpi = 200)plt.show()
首先,通过 open() 方法读取文本文件,然后 WordCloud 方法设置了词云参数,generate_from_text() 生成该文本词云,然后显示和保存词云图,十几行代码就可以生成最简单的词云图。
通过上面的词云图,你可能会发现有几点问题:
可不可以随便更换背景,比如白色?
词云图是矩形,能不能换成其他形状或者自定义图片样式?
词云中最显眼的词汇 「ONE」,并没有实际含义,能不能去掉?
以上这些都是可以更改的,如果你想实现以上想法,那么需要先了解一下 WordCloud 的API 参数及它的一些方法。
这里,我们列出它的各项参数,并注释重要的几项:
想到一些比较,不想动手的,我直接就在这下面输入(还是建议:多敲!!!还可以练手速哦!):
wordcloud.WordCloud( font_path = None, #字体路径,英文不用设置路径,中文需要,否则无法正确显示图形 width = 400, #默认宽度 height = 200, #默认高度 margin = 2, #边缘 ranks_only = None, prefer_horizontal = 0.9, mask = None, #背景图形,如果想根据图片绘制,则需要设置 scale = 1, color_func = None, max_words = 200, #显示最多的词汇量 max_font_size = None,#最大字号 min_font_size = 4,#显示最小字号 stopwords = None, #停止词设置,修正词云图时需要设置 random_state = None, background_color = 'black',#背景颜色设置,可以为具体颜色,比如:white或者16进制数值。 font_step = 1, mode = 'RGB', relative_sacling = 'auto', regexp = None, collocations = True, colormap = 'viridis',#matplotlib色图,可以更改名称进而更改整体风格 normalize_plurals = True, contour_width = 0, contour_color = 'black', repeat = False )
了解各项参数后,我们就可以自定义想要的词云图了。比如更换一下背景颜色和整体风格,就可以修改以下几项(lesson_2.0.py)
colormap 名称网址:https://matplotlib.org/examples/color/colormaps_reference.html
接下来,我们提升一点难度,通过设置 StopWords 去掉没有实际意义的「ONE」,然后将词云图绘制在我们自定义的一张图片上。
代码实现如下:
# ============================# -*8 coding: utf-8 -*-# @Author: 黄家宝# @Corporation: AI悦创# @Version: 1.0 # @Function: 词云,新增功能:更改背景色,更换形式# @DateTime: 2019-06-12 16:05:22# ============================# <----------导入库------------>import osfrom os import pathimport numpy as npfrom wordcloud import WordCloud,STOPWORDS,ImageColorGeneratorfrom PIL import Imagefrom matplotlib import pyplot as plt# from scipy.misc import imreadfrom matplotlib.pyplot import imreadimport random
# <----------生成区------------>def wc_english(): # 获取单前文件路径 d = path.dirname(__file__) if "__file__" in locals() else os.getcwd()
# 获取文本text text = open(path.join(d, 'legend1900.txt')).read()
# 读取背景图片 background_Image = np.array(Image.open(path.join(d,"mask1900.jpg"))) # or # background_Image = imread(path.join(d, "mask1900.jpg"))
# 提取背景图片颜色 img_colors = ImageColorGenerator(background_Image)
# 设置英文停止单词 stopwords = set(STOPWORDS)
wc = WordCloud( margin = 2, #设置页面边缘 mask = background_Image, scale = 2, #缩放2倍 max_words = 200, #最多词数 min_font_size = 150, max_font_size = 150, stopwords = stopwords, random_state = 42, background_color = 'white', colormap = 'Blues' ) #生成词云 wc.generate_from_text(text) # 等价于 # wc.generate(text) # 根据图片色设置背景色 wc.recolor(color_func = img_colors) # 存储图像 wc.to_file('1900pro1.png') # 显示图像 plt.imshow(wc, interpolation = 'bilinear') plt.axis('off') plt.tight_layout() # or # plt.savefig('1900pro1.png', dpi = 200) plt.show()
# 主函数区
if __name__ == '__main__': wc_english()
Ps:如果from scipy.misc import imread报错;可用:from matplotlib.pyplot import imread代替。方法 imread 在 scipy.misc 需要分叉包 PIL 命名 Pillow。如果您在安装正确版本的PIL时遇到问题,请尝试使用 imread 在其他包中:from matplotlib.pyplot import imreadim = imread(image.png)读书 jpg 没有的图像 PIL 使用:
import cv2 as cvim = cv.imread(image.jpg)
首先,通过 open() 方法读取文本文件,Image.open() 方法读取了背景图片,np.array 方法将图片转换为矩阵。接着设置了词云自带的英文 StopWords 停止词,用来分割筛除文本中不需要的词汇,比如:a、an、the 这些。然后,在 wordcloud 方法中,设置词云的具体参数。generate_from_text() 方法生成该词云,recolor() 则是根据图片色彩绘制词云颜色,绘制效果如下:
接着,我们还是看到了显眼的「ONE」,下面我们将它去除掉,方法也很简单,几行代码搞定:
# 获取文本词排序,可调整 stopwords process_word = WordCloud.process_text(wc,text) sort = sorted(process_word.items(),key=lambda e:e[1],reverse=True) print(sort[:50]) # 获取文本词频最高的前50个词 # 结果 [('one', 60), ('ship', 47), ('nineteen Hundred', 43), ('know', 38),('music', 36), ...] stopwords = set(STOPWORDS) stopwords.add('one')
这里,我们可以对文本词频进行排序,通过输出看到 「ONE」词频最高,然后添加进 stopwords 中,就可以屏蔽该词从而不再显示。这种手动添加停止词的方法适用于词数量比较少的情况。
另外,我们还可以将词云图颜色显示为黑白渐变色,也只需修改几行代码即可:
def grey_color_func(word, font_size, position, orientation, random_state=None, **kwargs): return "hsl(0, 0%%, %d%%)" % random.randint(50, 100) # 随机设置hsl色值 wc.recolor(color_func=grey_color_func)
以上,就是英文词云图绘制的几种方法,下面我们介绍中文词云图的绘制。
2. 中文词云
相比于英文词云,中文在绘制词云图前,需要先切割词汇,这里推荐使用 jieba 包来切割分词。因为它可以说是最好的中文分词包了,GitHub 上拥有 160 K 的 Star 数。
安装好 jieba 包后,我们就可以对文本进行分词然后生成词云了。这里,选取吴军老师的著作《浪潮之巅》作为中文文本的案例,仍然采用图片形式的词云图。素材准备好后,接下来就可以开始中文词云图绘制。
首先,需要读取文本文件,相比于英文,这里要添加文本编码格式,否则会报错,添加几行检测代码即可:
text = open(path.join(d, 'langchao.txt'), 'rb').read()text_charInfo = chardet.dect(text)print(text_charInfo)#结果{'encoding': 'UTF-8-SIG', 'confidence': 1.0, 'language': ' '}text = open(path.join(d, r'langchao.txt'),encoding = 'UTF-8-SIG').read()
接着,对文本进行分词。jieba 分词有 3 种方式:精确模式、全模式和搜索引擎模式,它们之间的差别,可以用一个例子来体现。
比如,有这样的一句话:「"我来到北京清华大学"」,用 3 种模式进行分词,结果分别如下:
全模式: 我/ 来到/ 北京/ 清华/ 清华大学/ 华大/ 大学
精确模式: 我/ 来到/ 北京/ 清华大学
搜索引擎模式: 我/ 来/ 来到/ 北京/ 清华/ 大学/ 清华大学/
根据结果可知,我们应该选择「精确模式」来分词。关于 jieba 包的详细用法,可以参考 GitHub 仓库链接:
https://github.com/fxsjy/jieba
分词完成后,我们还需要设置 stopwords 停止词,由于 WordCloud 没有中文停止词,所以我们需要自行构造。这里可以采取两种方式来构造:
通过 stopwords.update() 方法手动添加
根据已有 stopwords 词库遍历文本筛除停止词
2.1. stopwords.update() 手动添加
这种方法和前面的英文停止词构造的方法是一样的,目的是在词云图中不显示 stopwords 就行了 。先不设置 stopwords,而是先对文本词频进行排序,然后将不需要的词语添加为 stopwords 即可。下面用代码实现:
可以看到,我们先输出文本词频最高的一些词汇后,发现:但是、一个、因此、没有等这些词都是不需要显示在词云图中的。因此,可以把这些词用列表的形式添加到 stopwords 中,然后再次绘制词云图就能得出比较理想的效果,完整代码如下
我们对比以下 stopwords 添加前后的效果就可以大致看出效果。
stopwords 添加之前:
stopwords 添加之后:
可以看到,stopwords.update() 这种方法需要手动去添加,比较麻烦一些,而且如果 stopwords 过多的话,添加就比较费时了。下面介绍第 2 种 自动去除 stopwords 的方法。
2.2. stopwords 库自动遍历删除
这种方法的思路也比较简单。主要分为 2 个步骤:
利用已有的中文 stopwords 词库,对原文本进行分词后,遍历词库去除停止词,然后生成新的文本文件。
根据新的文件绘制词云图,便不会再出现 stopwords,如果发现 stopwords 词库不全可以进行补充,然后再次生成词云图即可。
代码实现如下:
网上有很多中文 stopwords 词库资料,这里选取了一套包含近 2000 个词汇和标点符号的词库:stopwords_cn.txt,结构形式如下:
遍历该 stopwords 词库,删除停止词获得新的文本,然后利用第一种方法绘制词云图即可。
# 遍历 stopwords 生成中文词云图
import osfrom os import pathimport numpy as npfrom wordcloud import WordCloud, STOPWORDS, ImageColorGeneratorfrom PIL import Imagefrom matplotlib import pyplot as plt# from scipy.misc import imreadfrom matplotlib.pyplot import imreadimport randomimport chardetimport jieba
# 获取当前文件路径d = path.dirname(__file__) if "__file__" in locals() else os.getcwd()
# 对原文本分词def cut_words(): # 获取当前文件路径 d = path.dirname(__file__) if "__file__" in locals() else os.getcwd() text = open(path.join(d, r'langchao.txt'), encoding='UTF-8-SIG').read() text = jieba.cut(text, cut_all=False) content = '' for i in text: content += i content += " " return content
# 加载stopwordsdef load_stopwords(): filepath = path.join(d, r'stopwords_cn.txt') stopwords = [line.strip() for line in open( filepath, encoding='utf-8').readlines()] # print(stopwords) # ok return stopwords
# 去除原文stopwords,并生成新的文本def move_stopwwords(content, stopwords): content_after = '' for word in content: if word not in stopwords: if word != '\t'and'\n': content_after += word
content_after = content_after.replace(" ", " ").replace(" ", " ") # print(content_after) # 写入去停止词后生成的新文本 with open('langchao.txt', 'w', encoding='UTF-8-SIG') as f: f.write(content_after)
def wc_chinese(): text = open(path.join(d, 'langchao2.txt'), encoding='UTF-8-SIG').read() # 设置中文字体 font_path = 'C:\Windows\Fonts\SourceHanSansCN-Regular.otf' # 思源黑体 # 读取背景图片 background_Image = np.array(Image.open(path.join(d, "wave.png"))) # 提取背景图片颜色 img_colors = ImageColorGenerator(background_Image)
# 设置自定义词典 jieba.load_userdict("userdict.txt") jieba.add_word('英特尔') # 设置中文停止词 stopwords = set('')
wc = WordCloud( font_path=font_path, # 中文需设置路径 margin=2, # 页面边缘 mask=background_Image, scale=2, max_words=200, # 最多词个数 min_font_size=4, stopwords=stopwords, random_state=42, background_color='white', # 背景颜色 # background_color = '#C3481A', # 背景颜色 max_font_size=100,
) # 生成词云 wc.generate_from_text(text) # 等价于 # wc.generate(text)
# 获取文本词排序,可调整 stopwords process_word = WordCloud.process_text(wc, text) sort = sorted(process_word.items(), key=lambda e: e[1], reverse=True) print(sort[:50]) # 获取文本词频最高的前50个词
# 设置为背景色,若不想要背景图片颜色,就注释掉 wc.recolor(color_func=img_colors)
# 存储图像 wc.to_file('浪潮之巅2.png')
# 显示图像 plt.imshow(wc, interpolation='bilinear') plt.axis('off') plt.tight_layout() plt.show()
if __name__ == '__main__': content = cut_words() stopwords = load_stopwords() move_stopwwords(content, stopwords) wc_chinese()
首先输出一下文本词频最高的部分词汇,可以看到常见的停止词已经没有了。
最终绘制词云图,效果如下:
3. Frenquency 词云图
除了直接读入文本生成词云,还可以使用 DataFrame 或者 字典格式 的词频作为输入绘制词云。
下面,以一份 10 年「世界大学排名 TOP500 强」 数据为例,有 5001行 x 6 列,绘制各国 TOP 500 强大学数量词云图。
有两种格式可以直接生成频率词云图,第一种是 Series 生成。
第二种转换为 dict 字典生成。
这两种数据都可以快速生成词云图,代码实现如下:
结果如下:
可以看到,美国最为突出,其次是德国、英国、中国等,看来我们的大学距离世界顶尖水平还有很长的一段路。
文中代码和素材,可以在公众号后台回复:‘词云’获取!
下一篇文章,我们使用 Pyspider 框架爬取虎嗅网 5 万条新闻标题内容,绘制词云图。
我是AI悦创,依然不会定时给你们分享一些有趣好玩实用的东西,欢迎关注~
警察蜀黍!就是这个人!脑子简直有泡!还不赶紧关注一下!