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官網

一個學習編程技術的公衆號。天天推送高質量的優秀博文、開源項目、實用工具、面試技巧、編程學習資源等等。目標是作到我的技術與公衆號一塊兒成長。歡迎你們關注,一塊兒進步,走向全棧大佬的修煉之路

相關文章
相關標籤/搜索