:::

匯出文字探勘結果:用R畫文字雲 / Draw Word Cloud in R

image

在「整合PostgreSQL資料庫的R中文文本探勘」我們用R對文本進行斷詞分析處理,最後將結果儲存到資料庫中。這篇我們就要用儲存在資料庫的結果來繪製文字雲圖片。


文字雲的詞頻資料來源 / Term Frequency Data Source for Word Cloud

跟一般的文字探勘流程做法不一樣的是,我認為文字雲的繪製並不需要從文本探勘開始做起。實際上,只要詞彙跟頻率兩種資料,我們就可以用它來繪製文字雲。

image

wordcloud2.js的展示網頁為例(因為網頁中的文字雲太大了,所以我稍微把它變矮了一點),我們可以看到下面所輸入的詞頻資料格式。資料類似以下內容:

12 Love
5 Liebe
5 ፍቅር
5 Lufu
5 حب
5 Aimor
5 Amor

每一行空格之前為詞彙出現的頻率,空格之後則是詞彙。這個資料並非wordcloud2.js真正使用的格式,只是方便使用者鍵入。但光是如此,我們就可以藉此瞭解文字雲所需要的資料來源。

儲存在資料庫中的詞頻 / Term Frequency in Database

2016-11-07_175310

在「整合PostgreSQL資料庫的R中文文本探勘」這篇中,我將文本探勘最後的詞頻結果儲存在資料表「term_freq」,然後我們再用SQL語法「SELECT term AS word, sum(freq) AS freq FROM term_freq GROUP BY term ORDER BY sum DESC」建立了視表「view_term_freq_sum」。所得到的結果如下表所示:

word

freq

布丁

70

name

38

false

38

var

28

rstudio

26

true

22

server

20

url

20

有了這樣的詞頻資料之後,我們就可以在R中取得資料庫的詞頻資料,再用套件wordcloud來繪製文字雲了。


繪製文字雲的R腳本 / R Script for Word Cloud

以下這個R Script所做的工作是從PostgreSQL資料庫中取得詞頻資料,然後把資料整理後輸入到wordcloud套件中,以此繪製文字雲。後面文字雲的寫法就跟用R進行中文 text Mining的做法一樣,差別在於陳嘉葳是直接沿用文本探勘的結果,而我是從資料庫取得資料來繪製文字雲。

雖然這次的R Script也是拆成設定跟執行兩個部分來撰寫,但是因為整個R Script並不長,所以我就沒有把它分開成兩個檔案了。基本上設定部分一定要修改的地方只有資料庫的連線設定,其他大部分都可以用預設值即可。這個R Script可以從以下網址下載:

# ==========================
# 設定部分

# 詞頻查詢
sql.term_freq <- "SELECT word, freq FROM view_term_freq_sum"
wordcloud.min.freq <- 10 # 文字雲顯示最小文字頻率

# 資料庫設定
db.host <- "192.168.56.152" # 資料庫主機位置
db.port <- 5432 # 資料庫連接埠
db.user <- "postgres" # 資料庫登入帳號
db.password <- "password" # 資料庫登入密碼
db.name <- "text_mining" # 資料庫名稱

# ==========================
# 執行部分

# 引用函式
library("RPostgreSQL") # PostgreSQL資料庫連線需要的套件
library("wordcloud") # 文字雲繪圖工具

# 資料庫連接
drv <- dbDriver("PostgreSQL")
con <- dbConnect(drv, dbname = db.name,
                 host = db.host, port = db.port,
                 user = db.user, password = db.password)

# 資料庫查詢
db.term_freq <- dbGetQuery(con, sql.term_freq)

# 如果有資料的話
if (length(colnames(db.term_freq)) > 0) {

# 製作文字雲
d <- data.frame(word = db.term_freq[,1], freq = db.term_freq[,2])
wordcloud(d$word, d$freq, min.freq = wordcloud.min.freq, random.order = F, ordered.colors = F,
    colors = rainbow(length(row.names(db.term_freq))))

} #if (length(colnames(db.term_freq)) > 0) {

最後可以輸出下圖的結果:

2016-11-08_055905

從文本探勘直接到文字雲輸出的R腳本 / R Script for Text Mining and Word Cloud

為了考慮到有人可能只需要文本探勘的文字雲結果,不需要儲存中間的詞頻,我將上一篇「整合PostgreSQL資料庫的R中文文本探勘」的R Script與這篇整合在一起。這次整個流程就不將結果儲存在資料庫,而是直接作為文字雲輸出了。

這個R Script可以從以下網址下載:


結語 / Conclusion

寫到這邊為止,對R文本探勘部分的研究就差不多告一個段落了。文字雲的美觀與細節當然有必要再進行細部的調整,不過其實我還是比較偏好使用JavaScript的互動圖表,例如wordcloud2.js函式庫

2016-11-08_080310

如果將詞頻資料以JSON輸出到wordcloud2.js,就可以呈現如上圖的成果。而這個範例程式碼可以在我寫的CodePen「wordcloud2.js demo」線上查看。

當然接下來還可以做基於使用詞頻的文件分類等資料探勘的處理,但這可以等到手邊資料多一點再來處理吧。

不要用最新版的R / Don’t use Up-to-date R

最後我來講一下寫這篇的另外一個教訓:沒事不要升級R

 

原本這篇寫到一半的時候,我在想,R應該可以顯示互動型的圖表吧?找了一下,真的有這種東西!套件名字是htmlwidgets,它除了plotly這樣強大的互動圖表之外,還有wordcloud2漂亮的文字雲。但是它不能裝在R 3.0.2這麼舊的版本上,怎麼辦好呢?我又找了一下,發現這篇「How To Set Up R on Ubuntu 14.04」介紹了如何在Ubuntu 14.04安裝R的方法,做法是加入額外的保存庫就能裝上最新版的R。我照著這樣操作,也的確升級了最新版的R 3.3.2 (2016-10-31發佈,才一週前!),並且可以正常安裝htmlwidgets並使用互動圖表。

2016-11-08_061813

上圖是用wordcloud2套件做出來文字雲,他是基於前面提到的wordcloud2.js開發的套件,所以文字雲結果看起來很像。而且這不是單純的圖片而已,它是可以點選、互動的文字雲喔!

這看起來一切都很美好,我也寫了wordcloud2的R Script並成功測試,但是接下來悲劇就發生了。

當我回頭去測試之前的文本探勘R Script的時候,發生了許多之前沒有遇到過的問題。大部分問題都集中在mclapply()函式上,我猜這可能是新版本的R開始用到多核心運算,所以背後的架構整個大改。我緊急尋找解決方法,但不論是這篇說的為tm_map()加上lazy=TRUE、還是加上content_transformer()、或是segmentCN結果轉換,都沒辦法讓文本探勘腳本順利運作。而這個問題讓網路上的R與文本探勘使用者哀嚎遍野,似乎一直沒能有個很好的解決方法。

最後我索性用虛擬機器的備份/還原功能把整個系統還原到R 3.0.2的版本,這樣子文本探勘就能夠正常運作了。

現在回頭刪除這篇中的wordcloud2套件R Script,雖然有點可惜,不過畢竟在R上面輸出圖表本來就不是我的初衷,這也不是一件太令人難過的事情。這樣說來,使用最新版的R看來不見得都是好事啊。那我之前寫的「R套件怎麼裝不起來?Ubuntu中舊版R安裝套件的方法」也算是值得了。