一、词云图 (WordCloud)
词云图是数据分析中比较常见的一种可视化手段。词云图,也叫文字云,是对文本中出现频率较高的关键词予以视觉化的展现,出现越多的词,在词云图中展示越显眼。词云图过滤掉大量低频低质的文本信息,因此只要一眼扫过文本就可领略文章主旨。
例如👆上面这张图,看一眼就知道肯定是新华网的新闻。
那生成一张词云图的主要步骤有哪些?这里使用 Python 来实现,主要分三步:
需要一份待分析的文本数据。由于文本数据都是一段一段的,所以第一步要将这些句子或者段落划分成词,这个过程称之为分词,需要用到 Python 中的分词库 jieba。
分词之后,就需要根据分词结果生成词云,这个过程需要用到 wordcloud 库。
最后需要将生成的词云展现出来,用到比较熟悉的 matplotlib。
二、安装第三方库
首先是“结巴”中文分词 jieba 的安装。
$ pip3 install jieba
对于英文文本,word_cloud 可以直接对文本源生成词云图。但是对中文的支持没有那么给力,所以需要先使用 jieba 对中文文本进行分词,把文章变成词语,然后再生成词云图。例如:
import jieba
seg_list = jieba.cut("我来到北京清华大学", cut_all=True)
print("Full Mode: " + "/ ".join(seg_list)) # 全模式
# Full Mode: 我/ 来到/ 北京/ 清华/ 清华大学/ 华大/ 大学
seg_list = jieba.cut("我来到北京清华大学", cut_all=False)
print("Default Mode: " + "/ ".join(seg_list)) # 精确模式
# Default Mode: 我/ 来到/ 北京/ 清华大学
seg_list = jieba.cut("他来到了网易杭研大厦") # 默认是精确模式
print(", ".join(seg_list))
# 他, 来到, 了, 网易, 杭研, 大厦
seg_list = jieba.cut_for_search("小明硕士毕业于中国科学院计算所,后在日本京都大学深造") # 搜索引擎模式
print(", ".join(seg_list))
# 小明, 硕士, 毕业, 于, 中国, 科学, 学院, 科学院, 中国科学院, 计算, 计算所, ,, 后, 在, 日本, 京都, 大学, 日本京都大学, 深造
seg_list = jieba.analyse.textrank("我来到北京清华大学", topK=100, withWeight=True)
# [('来到', 1.0), ('北京', 0.9961264494011037)]
jieba.cut
分词:方法接受三个输入参数,sentence 需要分词的字符串;cut_all 用来控制是否采用全模式;HMM 用来控制是否使用 HMM 模型。
jieba.cut_for_search
分词:方法接受两个参数,sentence 需要分词的字符串;是否使用 HMM 模型。该方法适合用于搜索引擎构建倒排索引的分词,粒度比较细。
jieba.analyse.textrank
使用 TextRank 算法从句子中提取关键词。
然后安装 wordcloud 词云图库。
$ pip3 install wordcloud
如果执行上面命令后,显示 success,那么恭喜你,安装成功了。
我就遇到了 Failed building wheel for wordcloud
的错误。于是先安装 xcode-select, 再安装 wordcloud 即可(无需安装 Xcode)。
$ xcode-select --install
$ python3 -m pip install wordcloud
wordcloud 库把词云当作一个 WordCloud 对象,wordcloud.WordCloud() 代表一个文本对应的词云,可以根据文本中词语出现的频率等参数绘制词云,绘制词云的形状、尺寸和颜色。
三、生成云词图
1、首先导入文本数据并进行简单的文本处理
2、分词
3、设置遮罩
import jieba
from wordcloud import WordCloud
import matplotlib.pyplot as plt
from PIL import Image
import numpy as np
# 去掉换行符和空格
text = open("/Users/info.txt", encoding='utf8').read()
text = text.replace('\n', "").replace("\u3000", "")
# 分词,并滤除1个字
text_cut = [w for w in jieba.cut(text) if len(w) > 1]
# 将分好的词用某个符号分割开连成字符串
text_cut = ' '.join(text_cut)
# 用于去掉文本中类似于'啊'、'你','我'之类的词
stop_words = {'你', '我', '他', '啊', '的', '了'}
# 读取图片,设置遮罩
background = Image.open("/Users/Desktop/map.jpeg")
graph = np.array(background)
# 使用WordCloud生成词云
word_cloud = WordCloud(font_path="/Users/simhei.ttf", # 设置词云字体
background_color="white", # 词云图的背景颜色
mask=graph, # 设置遮罩
stopwords=stop_words) # 去掉的停词
word_cloud.generate(text_cut)
# 写到文件
# word_cloud.to_file('abc.png')
# 运用matplotlib展现结果
plt.subplots(figsize=(20, 8))
plt.imshow(word_cloud)
plt.axis("off")
plt.show()
注意:
1、默认字体不支持中文,如果需要显示中文,需要设置中文字体,否则会乱码。
2、设置遮罩时,会自动将图片非白色部分填充,且图片越清晰,运行速度越快
其中 WordCloud 是云词图最重要的对象,其主要参数描述如下:
参数 | 描述 |
---|---|
width | 词云对象生成图片的宽度,默认400像素 |
height | 词云对象生成图片的高度,默认200像素 |
min_font_size | 词云中字体的最小字号,默认4号 |
max_font_size | 词云中字体的最大字号,根据高度自动调节 |
font_step | 词云中字体字号的步进间隔,默认为1 |
font_path | 字体文件的路径,默认None |
max_words | 词云显示的最大单词数量,默认200 |
stop_words | 词云的排除词列表,即不显示的单词列表 |
mask | 词云形状,默认为长方形,需要引用imread()函数 |
background_color | 词云图片的背景颜色,默认为黑色 |
效果如下图:
四、再多一点
上小结是将文章中所有内容进行分词,输出了所有词,但很多时候,我们有进一步的需求。例如:
1、只需要前 100 个关键词就够了。
2、不需要五颜六色的词语,应与遮罩图片颜色一致。
100个关键词,我们在分词时使用 TextRank 算法从句子中提取关键词。
遮罩颜色可通过设置 WordCloud 的 color_func 属性。
from wordcloud import ImageColorGenerator
from PIL import Image
import numpy as np
# 提前前 100 个关键词和权重,如 [('来到', 1.0), ('北京', 0.996)]
result = jieba.analyse.textrank(text, topK=100, withWeight=True)
# 转为 dict
keywords = dict()
for i in result:
keywords[i[0]] = i[1]
print(keywords)
stop_words = {'你', '我', '他', '啊', '的', '了'}
background = Image.open("/Users/Desktop/logo.png")
graph = np.array(background)
image_colors = ImageColorGenerator(graph) # 从图片中提取颜色
word_cloud = WordCloud(font_path="/Users/simhei.ttf", # 设置词云字体
background_color="white", # 词云图的背景颜色
mask=graph,
stopwords=stop_words, # 去掉的停词
color_func=image_colors) # 设置颜色
# 根据词频生成词云图
word_cloud.generate_from_frequencies(keywords)
最终效果如下: