文本挖掘介紹
文本挖掘:“自動化或半自動化處理文本的過程”,包含了文檔聚類、文檔分類、自然語言處理、文本變化分析及網絡挖掘等領域內容。
對於文本處理過程首先需要有分析的語料(text corpus),然后根據這些語料建立半結構化的文本庫(text database)。最后生成包含語頻的結構化的詞條——文檔卷着那(term-document matrix)。
這個一般性數據結構會被用於后續的分析:
- 文本分析,比如根據現有的文本分類情況,對未知文本進行歸類;
- 語法分析;
- 信息提取和修復
- 文檔信息匯總,比如提取相關有代表性的關鍵詞、句子等
自然語言處理
安裝Snowball包,zip文件下載地址
依賴的包:RWeka、RWekajars、rJava
識別某個英文單詞,需要對其進行詞干化(stemming)
SnowballStemmer(c('functions','stemming','liked','doing'))
記號化(Tokenization)是將一段文本分割成叫做token(象征)過程。
NGramTokenizer('我 站在 六里橋 的 柳樹下')
中文分詞
在英文結構中,每個表意的單詞都是獨立的,但中文表意的字符之間沒有空格連接。
Rwordseg包,調用Java分詞程序對語句進行分詞。安裝方法:
install.packages("Rwordseg", repos = "http://R-Forge.R-project.org")
分詞結果:
segmentCN('花兒為什么這樣紅')
使用Rwordseg的中文分詞,它不但分詞的精度較高,且支持詞性標注等功能。另外的中文分詞引擎有rmmseg4j。
tm包
數據讀入
在tm中主要的管理文件的結構被稱為語料庫(Corpus),代表了一系列的文檔集合。動態語料庫(Volatile Corpus,作為R對象保存在內存中)和靜態語料庫(Permanent Corpus,R外部保存)。
在語料庫構成中,x必須有一個說明資料來源(input location)的源對象(Source Object)。
動態語料庫:
Corpus(x,readerControl = list(reader = x$DefaultReader,language = "en"),...)
靜態語料庫,需要使用filehash包來支持:
PCorpus(x,readerControl = list(reader = x$DefaultReader,language = "en"), dbControl = list(dbName = "",dbType = "DB1"),...)
對於這些資料來源(x),tm包提供了一些相關的函數:
DirSource:處理目錄VectorSource:由文檔構成的向量DataFrameSource:數據框
第二個參數是readerControl,必須聲明reader和language兩個內容。第一個reader是指從資料源建立的文本文件。tm包提供了一系列的函數文件(readPlain(),readGmane(),readRCV1(),readReut21578XMLasPlain(),readPDF(),readDOC()等)。
使用getReaders()獲得這些函數的列表。對於每一類源,都有自己默認的reader。DirSource,默認讀入輸入文件並把內容解釋為文本。
第二個language字符集。
在使用靜態語料庫條件下,涉及第三個參數dbControl,用來聲明R內存對象外的資料來源。dbType控制了包filehash支持的數據庫類型。數據庫支持可以有效的減少對內容的要求,但數據的訪問會受到硬盤的讀寫能力限制。
讀取txt目錄下的文檔:
txt <- system.file("texts","txt",package = "tm")
ovid <- Corpus(DirSource(txt),readerControl = list(language = "lat"))
從字符集向量創建語料庫:
docs <- c("This is a text.","This another one.")
Corpus(VectorSource(docs))
路透社21578語料庫reuters,下載地址
reut21578 <- system.file("texts","crude",package = "tm")
reuters <- Corpus(DirSource(reut21578),readerControl = list(reader = readReut21578XML))
數據輸出
在R中創建的語料庫,使用writeCorpus()函數保存。
writeCorpus(ovid)
語料庫的提取
summary()函數會提供更多的元數據(meta data)信息,完整信息的提取需要使用inspect(),比如:
inspect(ovid[1:2])
單個文檔的提取需要使用[[,,既可以通過位置也可以通過名稱:
identical(ovid[[2]],ovid[["ovid_2.txt"]])
信息轉化
創建語料庫,后續文檔修改通過函數tm_map()處理,這個函數可以通過maps方式將轉化函數實施到每一個語料上。
轉化為純文本
在reuters這個語料庫中保存的是XML格式的文本,XML格式文本沒有分析的意義,只需要使用其中的文本內容。這個操作可以使用as.PlainTextDocument()函數來實現:
reuters <- tm_map(reuters,as.PlainTextDocument)
另外一種方式是使用readReut21578XMLasPlain讀取方式,第一步即為純文本格式。
去除多余的空白
reuters <- tm_map(reuters,stripWhitespace)
小寫變化
reuters <- tm_map(reuters,tolower)
停止詞去除
reuters <- tm_map(reuters,removeWords,stopwords("english"))
填充
通過以下方式,需要Snowball包(並行計算)支持:
tm_map(reuters,stemDocument)
過濾
tm_filter函數選取給定條件下的文檔。sFilter適用於一般情況下的用戶自定義過濾情況:它整合了適用於元數據的最小查詢語句。
元數據管理
元數據是為了標記語料庫的附加信息,最簡單的使用方式就是調用meta()函數。這些附加的元數據標簽都是獨立的附加在單個文檔上。從語料庫的視角上看,這些元數據標簽被獨立的存儲在每個文檔上。除了meta()函數上,DublinCore()函數提供了一套介於Simple Dublin Core元數據和tm元數據之間的映射機制,用於獲得或設置文檔的元數據信息。
在tm包元數據管理體系中,元數據標簽對應了兩個level:
- 對於語料庫(corpus)級別:文檔的集合
- 單個文檔的元數據
后一種元數據的使用主要是由於一些性能原因,或者是由於一些分析上的需要,比如要對文檔進行分類(classification),分類的結果直接和每個文檔的標記有關系。
標准操作和函數
對於語料庫來說,其標准操作和函數與R的一般函數非常類似:
[, [<-, [[, [[<-, c(), lapply()
對於像c()函數即是連接多個語料庫的意思。連接之后,元數據信息也會被更新。
創建詞條——文檔關系矩陣
文本挖掘需要創建詞條-文檔關系矩陣,它是后續構建模型的基礎。
在tm包里,根據詞條。文檔分別作為行、列或反之,對應有TermDocumentMatrix和DocumentTermMatrix兩類稀疏矩陣:
dtm <- DocumentTermMatrix(reuters) inspect(dtm[1:5,100:105])
對詞條-文檔關系矩陣操作
找出發生5次以上的條目,可以使用findFreqTerms()函數:
findFreqTerms(dtm,5)
使用findAssocs()找到相關性:
findAssocs(dtm,"opec",0.8)
對於一般矩陣,會將矩陣直接轉化為相關陣,這種方式可以實現不同的相關計算方式。詞條-文檔關系矩陣一般都是非常龐大的數據集,提供了一種刪減稀疏條目的方法。
字典
字典是一個字符集合。經常用於在文本挖掘中展現相關的詞條時,使用Dictionary()函數實現。當將字典傳遞到DocumentTermMatrix()以后,生成的矩陣會根據字典提取計算。
網頁解析的利器——XML包
網頁解析
在R中對網頁解析(XML、HTML文件,或包含XML、HTML的字符串)有多種方法,比較成熟的方法是使用XML包。這個包能夠將XML、HTML網頁樹(tree)解析成R結構數據。當解析的內容已知為(潛在畸形的)HTML時應當使用HTMLTreeParse函數,這個函數擁有大量的參數來適應解析需要。它可以在R中或使用內置C-level節點來創建樹,兩種方式在不同的環境下都非常有用。
xmlParse、HTMLParse分別等價於XMLTreeParse和HTMLTreeParse,只是使用了一個默認的值代替了為TRUE的useInterNodes參數。
xmlTreeParse(file,ignoreBlanks = T,handlers = NULL,
replaceEntities = F,asText = F,trim = T,validate = F,getDTD = T,
isURL = F,asTree = F,addAttributeNamespaces = F,useInternalNodes = F,
isSchema = F,fullNamespaceInfo = F,encoding = character(),
useDotNames = length(grep("^\\.",names(handlers))) > 0,xinclude = T,
addFinalizer = T,error = xmlErrorCumulator())
file,包含XML內容的文件名。可以使用聲明用戶工作目錄,也可以是一個URL(參考isURL)。甚至文件還可以是一個壓縮文件(gzip),文件可以被直接讀取而不需要用戶解壓縮(gunzip)。
ignoreBlanks,邏輯型,在結果“樹”中是否包含空白行。
handlers,選項函數,用於將不同的XML節點映射到R對象中。一般是函數的列表 (list)。它提供了一種通過增加、減少節點來過濾樹的方式。一般使用C代碼 來做處理。
replaceEntities, 邏輯值,是否將單位的參考條目進行對於那個文本的替換。默認為False。
asText, 邏輯值,和第一個參數file相關。file應被作為XML文本處理,而不是文件名稱。這 個選項可以允許還原不同的數據源(HTTP、XML-RPC等),並且依舊使用這個解 析器。
trim,是否刪除文本字符串中的空白。
validate,邏輯值,是否使用一個確認的解析器,或者根據DTD規范檢查內容。為TRUE則 DTD的錯誤告警信息將被展示,但解析仍將繼續,除非是致命的錯誤。
getDTD,邏輯值,DTD是否被返回(包括內部和外部)。被改變返回的類型。
isURL,聲明file參數是否涉及URL(通過ftp和http)或系統上的常規文件。如果asText為 TRUE,則這個參數不應該被指定。這個函數試圖從數據源中通過grep找到是否有 URL。libxml解析器處理服務器連接,這並不是R的特性(scan)。
asTree,僅僅在handlers參數使用時有效。
useInternalNodes,是否使用XMLInternalNode而不是用XMLNode類。內部節點 (internalnodes)不轉化到R時這個參數能使過程變得更快。
encoding,文檔的編碼方式。文檔應該包含編碼信息,如果沒有,這個參數可以為解析器指 定文檔的編碼方式。
使用XML包進行網頁解析,網頁源碼可以通過readLines,在exampleData目錄下:
fileName <- system.file("exampleData","include.xml",package = "XML")
root <- xmlParse(fileName)
test <- getNodeSet(root,'//para')
返回內容是一個list,可以使用lapply進行批量提取
sapply(test, xmlValue)
將test中para的內容提取出來,使用xmlValue函數:
vdata <- sapply(test, xmlValue)
函數getNodeSet提供了使用XPath語法抽取XML節點信息的功能。
首先解析一個xml文件,而后在doc的XPath目錄下,找到含有status字段的a節點。
doc <- xmlParse(system.file("exampleData","tagnames.xml",package = "XML"))
els <- getNodeSet(doc,"/doc//a[@status]")
sapply(els, function(el) xmlGetAttr(el,"status"))
最后通過XMLGetAttr函數獲得a節點的屬性值(Attribute Value)
字符集轉化
如果處理的是中文字符,可能會遇到字符編碼轉換的問題,可以使用iconv處理:
iconv(x,from = "",to = "",sub = NA,mark = T,toRaw = F)
XML和tm包配合使用(to do)
在得到TermDocument矩陣后,基本上所有的數據挖掘算法都可以使用,如Cluster、Classification、Regression等,甚至Apriori、SNA等技術。
基礎分析技術
在tm包中提供了諸如頻數提取(findFreqTerms)、相關性提取(findAssocs)等函數,以及用於計算cosine距離的dissimilarity函數。
R中的wordcloud包提供了繪制文本雲的技術,甚至還可以對兩個文本雲進行比較。
文本聚類
聚類一般會考慮使用層次(Hierarchical)聚類法或分割(Partitioning)聚類,對於層次聚類的核心實際在距離陣的計算,一般會使用歐氏距離、閔式距離等,但在大型數據條件下會優先選擇cosine距離,及dissmilarity函數。使用kmeans函數構建K均值聚類模型。
潛變量語義分析(not done)
潛變量語義分析(Latent Semantic Analysis)是一種通過語料的統計計算,對語境的提取和抽象。LSA和神經網絡模型非常接近,但它基於奇異值分解(singular value decomposition)。
LSA是一個提取語義的數學(統計)方法,它不是傳統的自然語言處理或人工智能,也沒有使用任何人類主導的字典、語義網絡、語法、詞法,而僅僅是把文本解析為有意義的單詞。基本步驟如下:
- 第一步是構建詞條-文檔(文章)矩陣,即每一行代表了詞條,每一類代表了文檔(文章),每個單元代表了發生的頻數;
- 接下來對這個矩陣實施奇異值分解。在奇異值分解中,原始矩陣被分解為三個矩陣,其中的一個矩陣描述了原始的行信息,作為正交基構成的向量;另外一個以相同的方式描述了列的信息;第三個是對角矩陣,包含了標度值(scaling values)。當這三個矩陣相乘時,可以得到原始矩陣。
主題模型
在機器學習和自然語言處理中,主題模型是專門抽象一組文檔所表達“主題”的統計技術。LDA主題模型涉及到貝葉斯理論、Dirichlet分布、多項分布、圖模型、變分推斷、EM算法、Gibbs抽樣等知識。
LDA是一個三層的貝葉斯概率模型,且有一個假設:bag of word。認為文檔就是一個詞的集合,忽略任何語法或出現順序關系。
附錄
XML文件
XML(eXtensive Markup Language)可擴展的標記語言,是萬維網(W3C)定義的一種標准。用戶可按照XML規則自定義標記(tags標簽)。
可作為跨平台的純文本通訊數據,且無關語言。其設計目標核心是數據的內容,和顯示分離。但XML不能直接用來寫網頁,即使包含了XML數據,依然要轉化為HTML格式才能在瀏覽器上顯示。XML被設計用來傳輸和存儲數據。而HTML被設計用來顯示數據。
- XML指可擴展標記語言
- XML是一種標記語言,很類似HTML
- XML的設計宗旨是傳輸數據,而非顯示數據
- XML標簽沒有被預定義,需要自定定義標簽
- XML被設計為具有自我描述性
- XML是W3C的推薦標准
- XML文件由聲明、元素、屬性、實體、注釋構成
正則表達式
