分詞之后,便是創建文檔-詞條矩陣了。
本文便是針對於此。正式學習tm(text mining)包
數據讀入
在tm 中主要的管理文件的結構被稱為語料庫(Corpus),代表了一系列的文檔集合。語料庫是一個概要性的概念,在這里分為動態語料庫(Volatile Corpus,作為R 對象保存在內存中)和靜態語料庫(Permanent Corpus,R 外部保存)。所對應的函數分別是 VCorpus() 和 PCorpus() 。此外,還有一個 Corpus() 的函數,跟Vcorpus或simpleCorpus的簡便版,取決於參數
我們可以看一下tm 中Corpus(或VCorpus)函數的用法,對於動態語料庫:
VCorpus(x, readerControl = list(reader = reader(x), language = "en"))
在tm 中靜態語料庫也是可以處理的,但需要使用filehash 包來支持:
PCorpus(x, readerControl = list(reader = reader(x), language = "en"), dbControl = list(dbName = "", dbType = "DB1"))
下面來具體介紹以下他們的參數:
x :說明資料來源(input location)的源對象(Source Object)。對於這些資料來源(即x),tm 包提供了 一些相關的函數,比如
- DirSource:處理目錄
- VectorSource:由文檔構成的向量
- DataframeSource:數據框,就像CSV 文件
readerControl :必須聲明reader 和language 兩個內容。reader是指從資料源創立的文本文件。tm 包提供了一系列的函數支持(比如,readPlain(),readGmane(), readRCV1(), readReut21578XMLasPlain(), readPDF(), readDOC() 等)。可以使用getReaders() 獲得這些函數的列表。對於每一類源,都會有自己默認的reader。比如對DirSource 來說,默認讀入輸入文件並把內容解釋為文本。第二個language 就比較簡單了,即字符集,比如可能是UTF-8 字符集。
dbControl :在使用靜態語料庫(Pcorpus)條件下,會有此參數。它用來聲明R 內存對象外的資料來源(比如數據庫)。dbType 控制了包filehash 支持的數據庫類型。數據庫支持可以有效的減少對內存的要求,但數據的訪問會受到硬盤的讀寫能力限制。
小實例:
#1、讀取包tm目錄下的texts/txt目錄下的文本文件 txt <- system.file("texts", "txt", package = "tm") ovid <- Corpus(DirSource(txt),readerControl = list(language = "lat")) ovid #<<SimpleCorpus>> #Metadata: corpus specific: 1, document level (indexed): 0 #Content: documents: 5 #2、從字符向量創建語料庫 docs <- c("This is a text.", "This another one.") Corpus(VectorSource(docs)) #<<SimpleCorpus>> #Metadata: corpus specific: 1, document level (indexed): 0 #Content: documents: 2 #3、讀取路透社文檔創建一個語料庫(用於后續示例) reut21578 <- system.file("texts", "crude", package = "tm") reuters <- Corpus(DirSource(reut21578), readerControl = list(reader = readReut21578XML)) reuters #<<VCorpus>> #Metadata: corpus specific: 0, document level (indexed): 0 #Content: documents: 20
數據輸出
數據輸出,也就是保存語料庫。可用writeCorpus()函數
例如,上面實例1中保存: writeCorpus(ovid) 此時,在工作目錄下會生成與語料庫對應的多個純文本文件
語料庫的提取
對於print() 和summary() 函數依然有效,但源信息被隱藏(可以想象一下每個語料庫包含了大量的文本,就像數據庫一樣)。meta() 函數會提供更多的元數據(meta data)信息,完整信息的提取需要使用inspect(),比如:
對於單個文檔的提取此處使用 [[ ,當然既可以通過位置也可以通過名稱 ovid[["ovid_1.txt"]
此外,查看單個文檔內容也可用 as.character(ovid[[1]])
查看多個文檔內容: lapply(ovid[1:2],as.character)
變換(transformation)
一旦創建了語料庫,后續文檔修改則不可避免,比如填充、停止詞去除。在tm 包里,這些函數都歸到信息轉化里面,其主要函數就是tm_map(),這個函數可以通過maps 方式將轉化函數實施到每一個語料上。
轉化為純文本:在reuters 這個語料庫中保存的是XML 格式的文本,XML 格式文本沒有分析的意義,我們只需要使用其中的文本內容。這個操作可以使用as.PlainTextDocument() 函數來實現:
reuters <- tm_map(reuters, PlainTextDocument)
注意,另外一種方式就是使用readReut21578XMLasPlain 讀取方式,那么在第一步即為純文本格式。
去除多余空白 : reuters <- tm_map(reuters, stripWhitespace)
小寫變化: reuters <- tm_map(reuters, tolower) 更廣泛的字符操作可參考gsub
停止詞去除: reuters <- tm_map(reuters, removeWords, stopwords("english"))
填充: tm_map(reuters, stemDocument) (需要Snowball 包(並行計算)支持)
過濾
過濾器可以移除不感興趣的(或者感興趣的)文檔。tm提供了tm_filter函數,這個函數的原型為
- tm_filter(x, FUN,...)
- tm_index(x,FUN,...)
其中的FUN函數出入為一片文檔,輸出為一個bool值。表示是否接受該文檔。第二個版本tm_index只是返回滿足條件的index,前者返回一個文集,下面是一個使用示例:
還有一種方法: query <- "id == '237' & heading == 'INDONESIA SEEN AT CROSSROADS OVER ECONOMIC CHANGE'" tm_filter(reuters, FUN = sFilter, query)
但是很遺憾,報錯 Error in match.fun(FUN) : object 'sFilter' not found
各種百度谷歌無果,沒有直接解決的辦法。最后都是自定義函數匹配函數實現的。
元數據管理
元數據分為兩個層次,一個是文集級別的元數據,一個是文檔級別的元數據。獲得元數據最簡單的方式是調用meta()函數,除了meta() 函數外,DublinCore() 函數提供了一套介於Simple Dublin Core 元數據和tm 元數據之間的映射機制,用於獲得或設置文檔的元數據信息。
修改文檔級別的元數據:A. DublinCore(crude[[1]], "Creator") <- "Ano Nymous"
B. meta(crude[[1]], "author") <- "Jiang Hang"
修改文集級別的元數據:
創建詞條-文檔關系矩陣
創建詞條-文檔關系矩陣的核心思想就是通過把所有文檔所用到的詞提取出來,然后行(或列)代表文檔,列(或行)代表詞,若該文檔中該詞出現n次,則此處的矩陣元素為n,反之為0。從而構造出一個稀疏矩陣。
在tm包中提供了兩個函數來構造此矩陣,TermDocumentMatrix 和 DocumentTermMatrix,分別以詞條文檔為行列、文檔詞條為行列
其他操作:
- 查找一定頻數范圍的詞。findFreqTerms() 函數, findFreqTerms(x, lowfreq = 0, highfreq = Inf) 找出出現次數高於lowfreq並低於highfreq的條目。例如,findFreqTerms(dtm, 5)找出出現5次以上的條目
- 查找與某個詞相關性高於一定范圍的詞。 findAssocs(x, terms, corlimit) ,其中tems,corlimit可以是一個向量。例如,findAssocs(tdm,"recent",0.5),找出與recent相關性大於0.5的詞,返回的是一個列表。
- 刪減稀疏度大於指定數值的條目。 removeSparseTerms(x, sparse) ,sparse是指稀疏度,0為最大,1為最小。
字典
字典是字符串的集合,通常用一個字符串向量表示,可以在DocumentTermMatrix
函數中指定一個 字典,這樣生成的矩陣中,就只有字典中出現的詞語,不在字典中的詞語不會出現
DocumentTermMatrix(reuters,list(dictionary = c("prices", "crude", "oil")))
此外,標准的操作符 [, [<-, [[, [[<-, c(), lapply() ,可以直接作用在語料庫上
本文參考:劉思喆《R語言環境下的文本挖掘》