Python绘制实时疫情词云

“词云”这个概念由美国西北大学新闻学副教授里奇·戈登(Rich Gordon)于提出。他一直很关注网络内容发布的最新形式——即那些只有互联网能够采用而报纸、广播、电视等其它媒体都可望不可即的传播方式。一般,这些最新的、最适合网络的传播方式,也是最好的传播方式。 所以,“词云”就是经过造成“关键词云层”或“关键词渲染”,对网络文本中出现频率较高的“关键词”的视觉上的突出。html

词云图过滤掉大量的文本信息,使浏览网页者只要一眼扫过文本就能够领略文本的主旨。python

当初的想法是定时将丁香园肺炎疫情实时动态爬下来保存在本地,作成一个网站,将详细的疫情播报作成词云,人们就能够不用看长篇大论,而是经过词云获取关键词。结果发现网上都是一个个xxx肺炎疫情实时动态git

读取文件

首先,我从丁香园肺炎疫情实时动态复制如下文本将其绘制成词云。github

病毒: 新型冠状病毒 2019-nCoV

传染源: 野生动物,可能为中华菊头蝠

传播途径: 经呼吸道飞沫传播,亦可经过接触传播,存在粪-口传播可能性

易感人群:人群广泛易感。老年人及有基础疾病者感染后病情较重,儿童及婴幼儿也有发病

潜伏期:通常为 3~7 天,最长不超过 14 天,潜伏期内存在传染性
复制代码

效果以下:面试

第一步固然是将数据保存在本地,而后读取数据。 由于文件对象会占用操做系统的资源,因此文件读取完后必需要关闭。 由于文件读写时都有可能产生IOError,出错后就不会调用close(),因此保证程序正常运行,应该使用try……finally。 代码以下:算法

try:
    fp=open("D:\\githubMe\\flask-tutorial\\doc\\coronavirus_data.txt",'r', encoding='UTF-8')
    text=fp.read()
    print(text)
finally:
    if fp:
        fp.close()
复制代码

固然,pythonwith能够自动调用close()。 优化的代码以下:编程

with open("D:\\githubMe\\flask-tutorial\\doc\\coronavirus_data.txt",'r', encoding='UTF-8') as fp:
    text=fp.read()
复制代码

生成词云

想要生成词云,方式有不少,这里调用wordcloud包。flask

pip install WordCloud
复制代码

其官网的案例。 导入PIL图片处理库,对图片进行保存。数组

pip install PIL
复制代码

PIL已是弃用了,因此能够安装PIL fork 版的 Pillow来替代它。bash

pip install Pillow
复制代码
from wordcloud import WordCloud
import PIL .Image as image

with open("D:\\githubMe\\flask-tutorial\\doc\\coronavirus_data.txt",'r', encoding='UTF-8') as fp:
    text=fp.read()
    wordcloud=WordCloud().generate(text)
    word_image=wordcloud.to_image()
    word_image.save('coronavirus_test_1.png','png')
复制代码

生成词云,可是图中出现中文乱码,能够正常显示英文字符。

将所有中文内容换成英文,词云无乱码

wordcloud默认是DroidSansMonowindow10上没有该字体,因此要修改font_path来调整此路径。 我导入了系统自带的字体微软雅黑msyh.ttc。固然也能够导入网上的第三方字体。

font_path指向字体的地址,代码以下:

wordcloud=WordCloud(font_path="D:\\githubMe\\flask-tutorial\\doc\\msyh.ttc").generate(text)
复制代码

执行后生成的词云

到这一步,基本的中文词云已经出现了,可是有些不是一个词,而是一句话,那怎么分词呢?

中文分词

这里就须要导入jieba分词

  1. 支持四种分词模式: 精确模式,试图将句子最精确地切开,适合文本分析; 全模式,把句子中全部的能够成词的词语都扫描出来, 速度很是快,可是不能解决歧义; 搜索引擎模式,在精确模式的基础上,对长词再次切分,提升召回率,适合用于搜索引擎分词。 paddle模式,利用PaddlePaddle深度学习框架,训练序列标注(双向GRU)网络模型实现分词。同时支持词性标注。
  2. 支持繁体分词
  3. 支持自定义词典
pip install jieba
复制代码

代码以下:

from wordcloud import WordCloud
import PIL .Image as image
import jieba

def participle_word(text):
    text_list=jieba.cut(text)
    res=' '.join(text_list)
    return res

with open("D:\\githubMe\\flask-tutorial\\doc\\coronavirus_data.txt",'r', encoding='UTF-8') as fp:
    text=fp.read()
    text=participle_word(text)
    wordcloud=WordCloud(font_path="D:\\githubMe\\flask-tutorial\\doc\\msyh.ttc").generate(text)
    word_image=wordcloud.to_image()
    word_image.save('coronavirus_test_4.png','png')
复制代码

生成的中文分词词云以下:

改变宽高

wordcloud不只有font_path属性,还有widthheight,二者分别默认是400px200px。 可让画布变大,使之成为800*800的正方形,更改以下:

wordcloud=WordCloud(font_path="D:\\githubMe\\flask-tutorial\\doc\\msyh.ttc",width=800,height=800).generate(text)
复制代码

改变形状

除了上述三个属性以外,还有mask这个常见属性。 在绘制文字的位置给出二进制掩码。若是mask有值,则将忽略宽度和高度,并改用mask的形状。全部白色区域都将被视为“蒙版”,而其余区域则能够随意使用。

mask只接受nd-arrayNone类型的值,因此须要numpy将图片转化。

找了一张白底的图片“妖”,很符合此次疫情的始做俑者的操做。

pip install numpy
复制代码

导入numpy包,支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。能够把图片“妖”想象成一个大型矩阵,而后worlcloud根据算法在非白色区域填充文字。numpy最重要的一个特色是其 N 维数组对象 ndarray,它是一系列同类型数据的集合,以 0 下标为开始进行集合中元素的索引。ndarray 对象是用于存放同类型元素的多维数组。 ndarray 中的每一个元素在内存中都有相同存储大小的区域。

from wordcloud import WordCloud
import PIL .Image as image
import jieba
import numpy as np

def participle_word(text):
    text_list=jieba.cut(text)
    res=' '.join(text_list)
    return res

with open("D:\\githubMe\\flask-tutorial\\doc\\coronavirus_data.txt",'r', encoding='UTF-8') as fp:
    text=fp.read()
    text=participle_word(text)
    shade=np.array(image.open('D:\\githubMe\\flask-tutorial\\doc\\wordcloud2.png'))
    wordcloud=WordCloud(font_path="D:\\githubMe\\flask-tutorial\\doc\\msyh.ttc",width=800,height=800,mask=shade).generate(text)
    word_image=wordcloud.to_image()
    word_image.save('coronavirus_test_6.png','png')
复制代码

执行脚本生成以下词云,轮廓就是“妖”

其他属性

  1. prefer_horizontal

The ratio of times to try horizontal fitting as opposed to vertical. If prefer_horizontal < 1, the algorithm will try rotating the word if it doesn’t fit. (There is currently no built-in way to get only vertical words.)

个人理解是:当该值取0时,词云中全部词汇都是垂直; 当该值取1或大于1时,词云中全部词汇都是水平; 只有大于0小于1之间,词汇才会放置合理。

wordcloud=WordCloud(font_path="D:\\githubMe\\flask-tutorial\\doc\\msyh.ttc",width=800,height=800,mask=shade,prefer_horizontal=1).generate(text)
复制代码

wordcloud=WordCloud(font_path="D:\\githubMe\\flask-tutorial\\doc\\msyh.ttc",width=800,height=800,mask=shade,prefer_horizontal=0).generate(text)
复制代码

  1. background_color 词云的背景颜色,默认是黑色。好比,下面我改为白色。
wordcloud=WordCloud(font_path="D:\\githubMe\\flask-tutorial\\doc\\msyh.ttc",width=800,height=800,mask=shade,background_color='#fff').generate(text)
复制代码

  1. relative_scaling 相对词频对字体大小的重要性。当relative_scaling = 0时,仅考虑单词排名。当relative_scaling = 1时,频繁出现的单词的大小将是两倍。若是要考虑单词频率而不是单词频率,那么.5左右的relative_scaling一般看起来不错。若是为auto,除非重复为true,不然它将设置为0.5,在这种状况下,它将设置为0

参考文献

word_cloud官网

一个学习编程技术的公众号。天天推送高质量的优秀博文、开源项目、实用工具、面试技巧、编程学习资源等等。目标是作到我的技术与公众号一块儿成长。欢迎你们关注,一块儿进步,走向全栈大佬的修炼之路

相关文章
相关标签/搜索