在互聯網時代,人們獲取信息的途徑多種多樣,大量的信息涌入到人們的視線中。如何從浩如煙海的信息中提煉出關鍵信息,濾除垃圾信息,一直是現代人關注的問題。在這個信息爆炸的時代,我們每時每刻都要更新自己的知識儲備,而網絡是最好的學習平臺。對信息過濾和處理能力強,學習效率就會得到提高。“詞云”就是為此而誕生的。“詞云”是對網絡文本中出現頻率較高的“關鍵詞”予以視覺上的突出,形成“關鍵詞云層”或“關鍵詞渲染”,從而過濾掉大量的無意義信息,使瀏覽者只要一眼掃過詞云圖片就可以領略文章或者網頁內容的主旨。不僅如此,一幅制作精美的詞云圖片,可以起到一圖勝千言的效果,在報告或者PPT
中適當的使用詞云,會使表達更清晰充分,為演講者表達的意義加分。本實驗將使用Python
的Wordcloud
擴展包制作詞云,生成圖片保存。并介紹如何改進wordcloud
擴展包使其能顯示中文字符,最后介紹如何使用自己喜歡的圖片定制詞云圖片輪廓。
Python
代碼實現詞云制作wordcloud
擴展包的使用使用自定義圖片制作詞云,分析《三體》I、 II、 III的關鍵詞該實驗在Ubuntu14.04
下完成,由于Python
具有跨平臺特性,該實驗的代碼也可以運行于Windows
和Mac
系統上,只需要對字體部分做相應處理即可。
python2.7
Xfce
終端本課程難度為一般,屬于初級級別課程,適合具有Python
基礎的用戶,熟悉python
基礎知識加深鞏固。
你可以通過下面命令將代碼下載到實驗樓環境中,作為參照對比進行學習。
$ wget http://labfile.oss.aliyuncs.com/courses/756/simple.py$ wget http://labfile.oss.aliyuncs.com/courses/756/my_word_cloud.py二、實驗原理
詞云的原理是對輸入的文本數據進行詞頻統計,根據詞匯出現頻率的不同,按不同比例顯示出詞匯,生成圖片。頻率高的詞匯顯示的大,頻率低的詞匯顯示的小。文本數據可以是本地數據,也可是是爬蟲動態從網絡中獲取的。
三、開發準備
打開Xfce
終端,進入 Code
目錄,創建 work
文件夾, 將其作為課程的工作目錄。下載并安裝實驗需要的擴展包 。如果大家平時想在自己的電腦上進行實驗,無論是Windows
還是linux
還是Mac
,都強烈推薦安裝Anaconda
,這是一個Python
的科學計算包,里面幾乎包含了常用的所有擴展包,不用自己費力安裝了,該軟件由Python
之父帶頭維護,三個平臺同時更新。
$ mkdir work && cd work$ sudo apt-get update$ sudo apt-get install python-dev$ sudo pip install numpy$ sudo apt-get install python-matplotlib$ sudo apt-get install python-pil下載小說《三體》I、 II、 III。
$ wget http://labfile.oss.aliyuncs.com/courses/756/santi.txt$ wget http://labfile.oss.aliyuncs.com/courses/756/santi2.txt$ wget http://labfile.oss.aliyuncs.com/courses/756/santi3.txt安裝wordcloud
擴展包。
$ sudo pip install wordcloud四、實驗步驟
5.1 運行一個簡單工程,測試擴展包安裝是否正常
在對《三體》進行處理之前,我們先運行一下官方的示例程序,確保擴展包安裝正常,程序能夠正常工作。在work
目錄下新建python
腳本,命名為simple.py
,
$ gedit simple.py代碼如下:
#!/usr/bin/env python"""Minimal Example===============Generating a square wordcloud from the US constitution using default arguments."""from os import pathfrom wordcloud import WordCloudd = path.dirname(__file__)# Read the whole text.text = open(path.join(d, 'constitution.txt')).read()# Generate a word cloud imagewordcloud = WordCloud().generate(text)# Display the generated image:# the matplotlib way:import matplotlib.pyplot as pltplt.imshow(wordcloud)plt.axis("off")# lower max_font_sizewordcloud = WordCloud(max_font_size=40).generate(text)plt.figure()plt.imshow(wordcloud)plt.axis("off")plt.show()由代碼可見,程序運行時會搜尋腳本所在的路徑下的文本文件“constitution.txt”
,所以我們在運行腳本前需要將這個文本放入work
文件夾下面。 通過下面的命令下載文本:
$ wget http://labfile.oss.aliyuncs.com/courses/756/constitution.txt在work
文件夾下啟動控制臺,操作如下圖所示:

在控制臺中運行腳本:
$ python simple.py如果擴展包安裝一切正常,程序將輸出如下窗口:

至此,我們得到了一個英文詞云。
5.2 解決中文顯示問題
我們已經成功安裝了wordcloud
擴展包,并成功運行了一個示例文件。但是這個示例文件有很多問題,首先,顯示的是英文字符,在面對中國同事或者老板做報告和分享時,使用英文的詞云明顯不合適,而且很多文本本身就是中文詞匯,沒法制作成英文詞云;詞云的外輪廓顯示的方方正正中規中矩,比較呆板,沒有美感。以上問題,我們一一來解決。首先,我們先解決中文顯示的問題。 我們先嘗試一下,如果什么都不做,直接把一本小說輸入到simple.py
文件中,看看輸出結果是什么樣子的。我們只需要修改源文件成為下面這樣,注意在文件頭部要聲明文件用utf8
編碼:
#!/usr/bin/env python#-*- coding: utf-8 -*-"""Minimal Example===============Generating a square wordcloud from the US constitution using default arguments."""from os import pathfrom wordcloud import WordCloudd = path.dirname(__file__)# Read the whole text.#text = open(path.join(d, 'constitution.txt')).read()text = open(u"santi.txt").read()# Generate a word cloud imagewordcloud = WordCloud().generate(text)# Display the generated image:# the matplotlib way:import matplotlib.pyplot as pltplt.imshow(wordcloud)plt.axis("off")# lower max_font_sizewordcloud = WordCloud(max_font_size=40).generate(text)plt.figure()plt.imshow(wordcloud)plt.axis("off")plt.show()在控制臺中運行程序,得到的結果是這樣的:

是不是激動地以為自己成功了?仔細看看這個詞云,一本中文小說,統計出來的最高詞匯居然是3K
和CPU
?這可不是計算機雜志啊!所以這個結果肯定是有問題的,之少我們要知道這本小說畫出來的詞云應該是漢字才對。
出現上面詭異的結果有兩個,第一是三體這本小說的編碼不是utf8
的,小說里的漢字是使用gbk
編碼的。所以我們直接使用
text = open(u"santi.txt").read()這句程序去讀取文件的時候,除了英文單詞,其他的讀出來都是亂碼,wordcloud
不認識這些亂碼,自然就不能顯示其頻率了。 好的那我們現在來修改一下代碼,機智的你肯定知道怎么修改了,對,改成下面這個樣子:
text = open(u"santi.txt").read().decode('gbk')再看看這次的輸出變成了什么,我們大膽猜一下,這次肯定不會是英文最大了。對的,這次的輸出是這個樣子的:

這怎么回事呢? 仔細看發現一個英文都沒有了,說明我們正確識別了漢字。那么這些框框出現的頻率比英文高,他們肯定是漢字啊!但是漢字怎么顯示成這樣了呢?這是因為wordcloud
沒有找到用于顯示漢字的字體啊! 我們都知道Ubuntu
是外國人搞出來的系統,所以對中文的支持肯定沒有對英文那么好,尤其是字體什么的,更少了。而wordcloud
也是個外國人開發的詞云庫,這倆貨都沒考慮到顯示中文的問題。 但是呢,既然python
能顯示中文,那么wordcloud
就應該也可以的。我們來想想辦法解決這個問題。 仔細的看一下我們的代碼,我們發現,生成詞云的關鍵環節是這一句:
wordcloud = WordCloud(max_font_size=40).generate(text)我們仔細看看這個類,傳給它的參數里有個關鍵參數:
font_path : string Font path to the font that will be used (OTF or TTF). Defaults to DroidSansMono path on a Linux machine. If you are on another OS or don't have this font, you need to adjust this path.恩,我們發現可以指定一個字體文件給它,代替默認的字體顯示詞云。問題轉化為我們要找一個linux
下支持漢字的字體文件。我這邊隨手找了一個ubuntu
系統中安裝的字體DroidSansFallbackFull.ttf
,為了防止在別的linux
系統中沒有這個字體而帶來麻煩,干脆直接把字體文件放在work
文件夾下讓它跟著源文件走,這樣就不會出現找不到的情況啦。 通過下面的命令下載字體文件:
$ wget http://labfile.oss.aliyuncs.com/courses/756/DroidSansFallbackFull.ttf將字體文件放在python
腳本所在的文件夾下,然后修改源代碼,首先找到我們自己的字體文件:
font=os.path.join(os.path.dirname(__file__), "DroidSansFallbackFull.ttf")然后在我們的源程序中,實例化wordcloud
類的兩個地方,指定wordcloud
使用我們自己的字體文件:
wordcloud = WordCloud(font_path=font).generate(text)wordcloud = WordCloud(font_path=font,max_font_size=40).generate(text)好的,修改完以后我們再看一下執行效果:

OK,我們期望的目的達到了!
5.3 定制詞云
我們經常在網上看到別人家的詞云都是奇形怪狀的,像下面這樣:

所以看著我們自己方方正正的詞云,是不是感覺太中規中矩了?都不好意思拿出手了吧? 沒關系,我們也可以做一個不規則邊緣的詞云! 為了達到一個定制詞云的效果,我們需要一個圖片作為mask
,這個mask
的作用就是為我們的詞云提供一個空間,讓我們的詞云只在這個空間里顯示,這就達到了類似上面詞云的效果。 我們的mask
圖片是星球大戰的士兵的頭盔,長成這個樣子:

做實驗時請在這里下載:
$ wget http://labfile.oss.aliyuncs.com/courses/756/stormtrooper_mask.png為此,我們需要修改我們的代碼,增加圖片mask
,修改后的代碼如下:
#!/usr/bin/python#-*- coding: utf-8 -*-"""Using custom colors====================Using the recolor method and custom coloring functions."""import numpy as npfrom PIL import Imagefrom os import pathimport matplotlib.pyplot as pltimport randomimport osfrom wordcloud import WordCloud, STOPWORDSfont=os.path.join(os.path.dirname(__file__), "DroidSansFallbackFull.ttf")def grey_color_func(word, font_size, position, orientation, random_state=None, **kwargs): return "hsl(0, 0%%, %d%%)" % random.randint(60, 100)d = path.dirname(__file__)mask = np.array(Image.open(path.join(d, "stormtrooper_mask.png")))text = open(u"santi.txt").read().decode('gbk')# PReprocessing the text a little bittext = text.replace(u"程心說", u"程心")text = text.replace(u"程心和", u"程心")text = text.replace(u"程心問", u"程心")# adding movie script specific stopwordsstopwords = set(STOPWORDS)stopwords.add("int")stopwords.add("ext")wc = WordCloud(font_path=font,max_words=2000, mask=mask, stopwords=stopwords, margin=10, random_state=1).generate(text)# store default colored imagedefault_colors = wc.to_array()plt.title("Custom colors")plt.imshow(wc.recolor(color_func=grey_color_func, random_state=3))wc.to_file("a_new_hope.png")plt.axis("off")plt.figure()plt.title(u"三體-詞頻統計")plt.imshow(default_colors)plt.axis("off")plt.show()這段代碼對詞云的顯示結果做了一點點修改,例如,“程心說”應該算是“程心”的詞頻,而不應該獨立計算,所以程序中做了一個簡單的替換。在試驗環境中不一定能輸入漢字,所以大家運行這個代碼體驗一下,以后在自己的電腦上安裝中文輸入法即可修改漢字了。 這段代碼的運行結果如下:

我們使用了星球大戰的武士的頭盔作為詞云形狀,怎么樣,看起來還不錯吧?
然而,我們的任務并沒有結束。我們說了要自己定制詞云,那么就連這個mask圖片也好根據我們自己的喜好進行定制。 為了在ubuntu
下將我們喜歡的圖片作為mask
圖片,我們需要安裝gimp
軟件:
$ sudo apt-get install gimp然后我隨意上網百度了一個美女圖片,就是這面這張:

請使用下面命令獲取該美女圖片的jpg
格式:
$ wget http://labfile.oss.aliyuncs.com/courses/756/04.jpg圖片有什么要求呢?恩,最好是背景是純色的,這樣好處理,當然如果有PS
高手幫忙的話,背景是什么也無所謂了。我們用gimp
軟件對這幅圖片進行處理,把除了女孩之外的背景改為白色,就可以作為mask圖片使用了。好下面我們動手開始制作。 首先,在圖層頁面下,右鍵這張圖,增加alpha
圖層:

然后,使用左側工具欄中的魔術棒工具,在這個姑娘身上隨便畫一下,就選中了這個姑娘:

然后,在空白區域,右鍵,編輯,使用白色作為背景顏色填充圖片:

搞定之后,我們把圖片導出來:

注意導出的時候選擇png
格式,如下設置:

然后我們就得到了這個mask圖片。我將其重命名為04.png
我們修改代碼使用這個圖片作為mask
圖片:
mask = np.array(Image.open(path.join(d, "04.png")))請使用如下命令獲取圖片04.png
:
$ wget http://labfile.oss.aliyuncs.com/courses/756/04.png再看我們的運行結果:


好的,至此我們就得到了定制的詞云。
五、實驗總結
我們使用wordcloud
擴展包實現了定制詞云,通過指定字體文件解決了wordcloud
默認不能顯示中文的問題,進一步,使用gimp
軟件實現了自定義mask
圖片的功能。最后,使用自定義的詞云分析了小說《三體》的詞頻,制作了詞云。
六、課后習題
在本實驗中,只對《三體》I 進行了分析,同學們可以根據我提供的文本,為《三體》II、III制作詞云,制作時注意把沒有意義的副詞都過濾掉。
新聞熱點
疑難解答