文本探勘分析:用Zotero與資料庫進行書目計量與文本探勘的感想 / Text Analysis: Bibliometrics and Text Mining with Zotero and Database
文本探勘的研究要怎麼進行呢?許多文本分析和書目計量學的研究都使用EndNote跟Excel來整理資料,但其實使用免費的Zotero跟資料庫來做書目計量才是最佳的選擇。我想在這篇簡短聊一下我在2016年底所進行的文本探勘研究的處理方式,也許未來還會有機會做類似的研究吧?
書目資料的獲取 / Gather Bibliography Data
使用Zotero獲取書目資料非常容易:只要網頁上看的到的資料,全部都可以用Zotero的轉譯器(translator)獲取下來。就算只是單純的網頁,Zotero也能將網頁的完整內容一併保存,有助於我們對多個網頁的分析。
更重要的是,Zotero不僅只是抓取書目的後設資料(metadata),如果有轉譯器的搭配,就能夠同時下載書目的全文PDF檔案。Zotero提供了大部分西文資料庫的轉譯器,像是Google Scholar、Scopus,但是較少為中文的資料庫設計相對應的轉譯器。所以我會為我自己常會使用的資料庫設計轉譯器,像是博碩士論文網、或是中國知網CNKI。
Zotero也提供了線上多人同步的Zotero Groups功能。我們可以多人一起分工抓取資料,然後同步在同一個文獻庫(collection)中,非常好用呢!這樣子跟大家一起合作撰寫論文與計劃書時,就很容易共享論文中引用的文獻了。
總之,在做文本探勘之前,就用Zotero蒐集好資料吧。
取得Zotero內的資料 / Access Zotero's Database
資料保存在Zotero裡面了,接下來要如何分析好呢?
Zotero本身提供了一些基本的分析功能,大多都是根據書目資料Metadata的分析,像是標籤雲(tag cloud)、時序表(timelime)、或是用相關書目(relating items)來建立網絡圖:ZotNet。但這次我要分析的是書目附件的PDF檔案的內容,這下子要怎麼辦好呢?
匯出文獻庫到關聯式資料庫 / Expert a collection to RMDB
Zotero提供了「匯出文獻庫」,它可以將保存在Zotero中指定文獻庫(collection)的書目(item)全部匯出到指定的資料夾。資料夾內會有一個以.rdf副檔名的XML格式主要檔案,以及一個files資料夾和底下各書目的相關檔案。
之前我先使用「用Acrobat Pro把PDF轉換成HTML:AutoIt一鍵轉換方案」將附件的論文PDF檔案轉換為HTML檔案。再來用Node.js,以XPath的方式來剖析rdf檔案,取出書目的標題、作者、期刊、年份,並且根據相關附件檔案轉換成HTML後的路徑,取出HTML字串。然後再將所有資料保存在關聯式資料庫中,以方便後續的處理。
一開始我是先用SQLite,處理起來非常簡單。但是當文本資料一多的時候,SQLite的處理速度就大幅下降。後來我改用PostgreSQL來處理,即使是6MB的資料,處理起來也是非常的快。還好我在Node.js使用了Sequelize這個ORM框架來操作資料庫,從SQLite轉換到PostgreSQL資料庫只需要修改參數即可,幾乎是無痛轉移。不過這也多虧SQLite跟PostgreSQL都支援了標準的SQL語法,所以我的程式內容也不太需要修改。如果是MySQL或MSSQL,那可就辛苦了。
直接使用Zotero的資料庫 / Access Zotero's database
做到後來,我才發現原來Zotero早就把它所有資料都保存在「zotero.sqlite」中。Zotero也允許使用者直接存取Zotero的資料庫,請見「Direct Access to the Zotero SQLite Database」。
我們可以使用DB Browser for SQLite Portable來開啟Zotero資料庫,也能用任何程式語言的SQLite資料庫連線方法來存取它。Zotero資料庫包含了62張表格,正規化相當詳細。稍微用點時間來理解,相信大家應該很快就能從中取出想要的資料。
但是Zotero資料庫一次只能提供一個程式使用,這是SQLite的先天限制。因此若使用Zotero資料庫,必須關閉所有Zotero的相關程式,包括Zotero Standalone或Firefox裡面的Zotero面板,並等待一段Zotero寫入資料庫的時間,然後才能連接Zotero資料庫。否則就會出現類似上面的錯誤訊息。
不過Zotero資料庫依然沒有將附件檔案內容抽取成全文的功能,我們還是得要用「用Acrobat Pro把PDF轉換成HTML:AutoIt一鍵轉換方案」來將PDF檔案轉換為HTML,然後另外儲存在其他資料庫中。
最後我將這些資料保存在另一個關聯式資料庫,並開發了PHP KWIC Database來方便我解讀文本。
分析文本 / Text analysis
有了書目與全文之後,接下來我們可以做什麼分析呢?
斷詞:結巴斷詞器 / Tokenization: Jieba
首先,因為我們處理的是中文文本,所以需要對中文文本進行斷詞。斷詞的時候我選擇的是結巴斷詞器 (jieba),它可以將一串中文切割成多的關鍵字。例如以下文本:
這個布丁是在無聊的世界中找尋樂趣的一種不能吃的食物,喜愛動漫畫、遊戲、程式,以及跟世間脫節的生活步調。
經過結巴斷詞後就會變成:
["這個", "布丁", "是", "在", "無聊", "的", "世界", "中", "找尋", "樂趣", "的", "一種", "不能", "吃", "的", "食物", ",", "喜愛", "動漫畫", "、", "遊戲", "、", "程式", ",", "以及", "跟", "世間", "脫節", "的", "生活", "步調", "。"]
最後我將關鍵字、詞性、對應文本編號、在文本內出現次數等資訊記錄在資料庫中,這樣我們就能去做關鍵字統計、關鍵字共伴出現等進階分析。
這次使用結巴斷詞器的經驗也被我應用在後續研究中,「線上中文斷詞工具:Jieba-JS」就是其中一個成果。
停用字過濾 / Filtering stop words
雖然經過斷詞後,文本會變成多個關鍵字的組合。但是這些關鍵字包含了太多過於常見、意義不大的詞彙,我們需要在統計分析前先將之過濾。
結巴斷詞器本身有提供詞性標註。許多研究都建議將詞性為「名詞」(n)的關鍵字挑出來分析,其他關鍵字則忽略。另一種做法是整理一個停用字詞表,將意義不大的詞彙列入其中,就能夠以此進行過濾。
結巴斷詞器本身提供了停用字的功能,請看stop_words.utf8的設定。然而實務上,斷詞器本身的停用字相當不好用。因為停用字列表是會隨著研究分析的進度而時常增減,但結巴斷詞是一個相當費時的操作。若每次修改停用字列表就要重新斷詞,這將會大幅拖慢研究效率。
我的做法是用關聯式資料庫建立一張停用字的表格,將之與前面的關鍵字表格整合查詢,建立一張經過停用字過濾的view (視圖),這樣就能動態產生被過濾停用字的關鍵字詞表。
在分析的過程中,我們會不斷增加或減少停用字。為了讓人方便編輯,我又另外寫了一隻程式來存取資料庫中的停用字表。這樣就很容易調整了。
情緒分析 / Emotion Analysis
有這樣的關鍵詞表之後,我們就可以進一步來看看要怎麼分析。最簡單的做法是時下流行的情緒分析。這個做法是分析文本內容出現「正面情緒」關鍵字和「負面情緒」關鍵字的多寡,就能知道該文本到底是偏向「正面情緒」(positive)還是「負面情緒」(negative)。
GitHub上可以看到sweslo17開源的中文情緒分析系統 chinese_sentiment,他提供的停用詞表 stopword.txt、正面情緒詞表 ntusd-positive.txt、負面情緒詞表ntusd-negative.txt是相當好的起點,我就參考他的詞表來作為初始的停用字列表、正面情緒列表與負面情緒列表。
同樣地,我也選擇將「正面情緒」跟「負面情緒」的列表以固定、難以修改的txt格式儲存,而是將它儲存成資料庫的表格。這樣我們就可以像是停用字一樣地建立一個view,分析文本中正面情緒關鍵字與負面情緒關鍵字兩者各別所佔的比例。
篩選出具代表的關鍵字 / Finding core keywords
關鍵字這麼多,要怎麼找出代表性的關鍵字呢?最基本的做法就是找出頻率最高的關鍵字。
因為使用了關鍵式資料庫,並將關鍵字單獨儲存成表格了,要建立關鍵字出現次數的統計表格可說是易如反掌。其難度大概就是大學資料庫的期中前小作業的程度。
接下來我們可以用文件的年份來切割,找出每個年份代表性的關鍵字,這樣可以看到文本與時間的關聯。在這裡我本來想要以TF-IDF來取代單純的次數統計,這樣雖然能夠找出該年度更具代表性的關鍵字,但後來卻發現這樣反而難以解釋。看來工科的角度不一定適用在文科的做法上,值得我們反思。
若我們對於找出的關鍵字感到好奇,又可以進一步使用PHP KWIC Database來看看該關鍵字在各個文本中的脈絡。讓我們對這個關鍵字有更深入的理解。
文本量化指標 / Text quantization
除了關鍵字之外,我們還能夠從文本中抽取出什麼特徵呢?
我在「揭露文字資料的量化數值!文字探勘分析器」這篇介紹過許多可以將文本量化成數字的指標,單純的包括文字的長度、文字的種類程度、句子、對話、虛詞等等的分析。若再加入前面的關鍵字分析、正面情緒比例、負面情緒比例,我們就可以取得更多量化指標。
分群 / Clustering
有了這些量化指標,我們就能夠進行群聚分析,將文本分群成多個群集,這樣就能夠更容易看清楚這些文本的整體特色,研究者就能夠用整體的角度來解釋所有的文本。
結果詮釋 / Interpretation
雖然我最後才講這個部分,但其實對於結果的詮釋,應該是整個貫穿研究的核心議題。因為在這次文本探勘的研究中,我主要負責的是技術支援的部分,對於結果的詮釋並不是由我主導,也就不是本篇的重點。我觀察我的合作夥伴對於結果詮釋的方式,在這裡記錄一下心得。
文本探勘的重點並非是「文本探勘」這個技術,而是我們希望釐清、驗證心中對於「某人」有某些疑惑,因此我們蒐集「某人」產生的文件,以此作為代表某人的想法、模式,再透過「文本探勘」找出的答案來解答我們的疑惑。這個「某人」可以是一個人、一個社群、一些擁有共同特質的人,皆是屬於這個「某人」的範疇。
對於「某人」的某些疑惑,大致上可以分成兩個層次:
- 面的層次:我們對於「某人」完全不瞭解,不知道該怎麽描述「某人」。這時候透過分群來釐清「某人」產生文本的一些模式,就能夠讓我們知道「某人」大概的想法。
- 點的層次:根據理論或個人的好奇心,我們對「某人」有一些「假設」。這時候就可以透過文本探勘後得到的量化指標,例如情緒分析,來驗證看看「某人」在某些文本上的正面情緒與負面情緒,是否符合我們的「假設」。
一份研究大多選擇上述兩種層次其中一個來進行分析,而我們選擇的是第二個點的層次,希望透過文本探勘來驗證心中的假設。
但老實說,像我這種不學無術的人,對這些文本一點想法都沒有的話,還真的不知道要詮釋個什麼結果。感謝當時有個擁有厚實理論基礎的好夥伴一同進行研究,我們最後才能得到相當有意思的結果。
到這裡為止,大概就是我在2016年底所進行的文本探勘研究的大致過程了。
小結 / In closing
(圖片來源:Are you a geek?)
本來一開始只是想為了鼓勵大家使用Zotero而寫這篇,順便反省一下當初不是直接使用Zotero資料庫而是使用文獻庫匯出的缺點。但寫著寫著,連文本探勘後續的分析都寫上來了,好吧,那我就把整個過程記錄得完整些好了。
許多喜歡技術的工科腦看到這些處理過程,都會很自豪地說:「如果沒有這些關聯式資料庫處理技術、統計分析、資料探勘分群,人文學者要怎麽做這樣的研究?」但我做到最後的感想是……就算沒這些花俏的技術,大家還是可以一篇一篇慢慢解讀文本、記錄覺得重要的關鍵字。我用機器可以在30分鐘左右抽取出四百多篇文件的關鍵字,但人文學者也可以選擇花上一個月仔細閱讀每一篇文件,然後得到類似的結果。
在研究過程中,比起「這樣的量化分析結果能夠對結論的詮釋有什麼幫助」,我更常感覺到的是人文學者的無奈:「好吧,既然你都分析了,那我就看看吧……但這表格跟指標是什麼意思?」整個研究過程讓我時常遭遇兩難的問題,到底是要以技術為主,想辦法將這個分析結果跟理論搭上邊?還是要以理論為主,再用技術找出與該理論相關的解釋?但是不熟分析技術的一般人所想得到的量化分析十分表面,大多不脫次數統計,要談到比例那就更難了一些,更別說其他的統計方法。
工科腦會想用許多華麗的分析技術,但這個分析技術不見得可以用於結果詮釋上。要如何在這個兩難的問題上取得一個平衡點,是值得我們深思的問題。別忘了,我們做研究的目標是追求真理,而不是手段。
在真理之前,我們都應當懂得謙虛。共勉之。
這篇談文本探勘就到此為止了。你對文本分析、內容分析等研究的看法如何呢?你是否也曾經做過對大量文本進行解讀的研究呢?從資訊技術的角度來看,你對文本分析又有什麼看法呢?歡迎在下面的留言處與我分享你的想法,或是在AddThis分享工具按讚、分享到Facebook等社群媒體吧!感謝你的耐心閱讀,讓我們下一篇見。