在文本挖掘中,咱們常常收集一些文檔集合,例如博客文章或新聞文章,咱們但願將其分紅天然組,以便咱們能夠分別理解它們。主題建模是對這些文檔進行無監督分類的一種方法,相似於對數字數據進行聚類,即便咱們不肯定要查找什麼,也能夠找到天然的項目組。算法
潛在狄利克雷分配(LDA)是擬合主題模型特別流行的方法。它將每一個文檔視爲主題的混合體,並將每一個主題看做是單詞的混合體。這容許文檔在內容方面相互「重疊」,而不是分離成離散的組,以反映天然語言的典型用法。ide
結合主題建模的文本分析流程圖。topicmodels包採用Document-Term Matrix做爲輸入,並生成一個能夠經過tidytext進行處理的模型,以即可以使用dplyr和ggplot2對其進行處理和可視化。函數
如圖所示,咱們可使用 文本原理來處理主題建模 。工具
潛在Dirichlet分配是主題建模中最經常使用的算法之一。 學習
每一個文檔都是主題的混合體。咱們設想每一個文檔可能包含來自幾個主題的文字,特別是比例。例如,在雙主題模型中,咱們能夠說「文檔1是90%的主題A和10%的主題B,而文檔2是30%的主題A和70%的主題B.」測試
每一個主題都是詞彙的混合。例如,咱們能夠想象一個美國新聞的兩個主題模型,一個話題是「政治」,一個是「娛樂」。政治話題中最多見的詞語多是「總統」,「國會」和「政府「,而娛樂主題能夠由諸如」電影「,」電視「和」演員「之類的詞組成。 spa
LDA是一種同時估計這兩種狀況的數學方法:查找與每一個主題相關的單詞混合,同時肯定描述每一個文檔的主題混合。這個算法有不少現有的實現,咱們將深刻探討其中的一個。code
library(topicmodels)data("AssociatedPress")AssociatedPress : term frequency (tf)
咱們可使用LDA()topicmodels包中的函數設置k = 2來建立兩個主題的LDA模型。對象
實際上幾乎全部的主題模型都會使用更大的模型k,但咱們很快就會看到,這種分析方法能夠擴展到更多的主題。token
此函數返回一個包含模型擬合完整細節的對象,例如單詞如何與主題關聯以及主題如何與文檔關聯。
# set a seed so that the output of the model is predictableap_lda <- LDA(AssociatedPress,k =2,control =list(seed =1234))ap_lda
擬合模型是「簡單部分」:分析的其他部分將涉及使用整理tidytext軟件包中的函數來探索和解釋模型。
tidytext包提供了這種方法來提取每一個主題的每一個詞的機率,稱爲ββ (「測試版」)。
## # A tibble: 20,946 x 3## topic term beta## ## 1 1 aaron 1.69e-12## 2 2 aaron 3.90e- 5## 3 1 abandon 2.65e- 5## 4 2 abandon 3.99e- 5## 5 1 abandoned 1.39e- 4## 6 2 abandoned 5.88e- 5## 7 1 abandoning 2.45e-33## 8 2 abandoning 2.34e- 5## 9 1 abbott 2.13e- 6## 10 2 abbott 2.97e- 5## # ... with 20,936 more rows
R語言中對文本數據進行主題模型topicmodeling分析
每一個主題中最多見的術語
這種可視化讓咱們瞭解從文章中提取的兩個主題。話題1中最多見的詞語包括「百分比」,「百萬」,「十億」和「公司」,這代表它可能表明商業或財務新聞。話題2中最多見的包括「總統」,「政府」和「蘇維埃」,表示這個話題表明政治新聞。
做爲替代方案,咱們能夠認爲有條款最大的區別在ββ在主題1和主題2之間。
## # A tibble: 198 x 4## term topic1 topic2 log_ratio## ## 1 administration 0.000431 0.00138 1.68## 2 ago 0.00107 0.000842 -0.339## 3 agreement 0.000671 0.00104 0.630## 4 aid 0.0000476 0.00105 4.46## 5 air 0.00214 0.000297 -2.85## 6 american 0.00203 0.00168 -0.270## 7 analysts 0.00109 0.000000578 -10.9## 8 area 0.00137 0.000231 -2.57## 9 army 0.000262 0.00105 2.00## 10 asked 0.000189 0.00156 3.05## # ... with 188 more rows
圖顯示了這兩個主題之間差別最大的詞。
R語言中對文本數據進行主題模型topicmodeling分析
圖β中差別最大的詞β 在主題2和主題1之間
咱們能夠看到,話題2中更常見的詞包括「民主」和「共和黨」等政黨,以及「dukakis」和「gorbachev」等政治家的名字。主題1的特色是「日元」和「美圓」等貨幣以及「指數」,「價格」和「利率」等金融術語。這有助於確認算法肯定的兩個主題是政治和財務新聞。
除了將每一個主題評估爲單詞混合以外,LDA還將每一個文檔建模爲混合主題。咱們能夠檢查每一個文檔的每一個主題機率,稱爲γγ(「伽瑪」),其matrix = "gamma"論點是tidy()。
## # A tibble: 4,492 x 3## document topic gamma## ## 1 1 1 0.248## 2 2 1 0.362## 3 3 1 0.527## 4 4 1 0.357## 5 5 1 0.181## 6 6 1 0.000588## 7 7 1 0.773## 8 8 1 0.00445## 9 9 1 0.967## 10 10 1 0.147## # ... with 4,482 more rows
這些值中的每個都是該文檔中從該主題生成的單詞的估計比例。例如,該模型估計文檔1中單詞的大約24.8%是從主題1生成的。
咱們能夠看到,這些文檔中的許多文檔都是從兩個主題的混合中抽取出來的,但文檔6幾乎徹底是從主題2中得出的,其中有一個γγ從主題1接近零。爲了檢查這個答案,咱們能夠tidy()使用文檔術語矩陣,並檢查該文檔中最多見的詞。
## # A tibble: 287 x 3## document term count## ## 1 6 noriega 16.## 2 6 panama 12.## 3 6 jackson 6.## 4 6 powell 6.## 5 6 administration 5.## 6 6 economic 5.## 7 6 general 5.## 8 6 i 5.## 9 6 panamanian 5.## 10 6 american 4.## # ... with 277 more rows
根據最多見的詞彙,這彷佛是一篇關於美國政府與巴拿馬獨裁者曼努埃爾諾列加之間關係的文章,這意味着該算法將其置於專題2(做爲政治/國家新聞)是正確的。
在考察一個統計方法時,在一個很是簡單的狀況下,你能夠知道「正確的答案」。例如,咱們能夠收集一組明確與四個不一樣主題相關的文檔,而後執行主題建模,以查看該算法是否能夠正確區分這四個組。這讓咱們仔細檢查該方法是否有用,並瞭解它如何以及什麼時候會出錯。咱們將使用經典文獻中的一些數據來嘗試。
假設一個破壞者闖入你的書房並撕毀你的四本書:
Charles Dickens的偉大指望HG Wells 的世界大戰
Jules Verne 在海底的兩萬裏
傲慢與偏見簡·奧斯汀
咱們將使用第3章介紹的gutenbergr包檢索這四本書的內容。
titles <- c("Twenty Thousand Leagues under the Sea","The War of the Worlds","Pride and Prejudice","Great Expectations")
做爲預處理,咱們將它們分紅不一樣的章節,使用tidytext unnest_tokens()將它們分離成單詞,而後刪除stop_words。咱們將每一章都視爲一個單獨的「文檔」,每一個章節都有一個像「 Great Expectations_1或」這樣的名字Pride and Prejudice_11。(在其餘應用程序中,每一個文檔多是一篇報紙文章或一篇博客文章)。
## # A tibble: 104,721 x 3## document word n## ## 1 Great Expectations_57 joe 88## 2 Great Expectations_7 joe 70## 3 Great Expectations_17 biddy 63## 4 Great Expectations_27 joe 58## 5 Great Expectations_38 estella 58## 6 Great Expectations_2 joe 56## 7 Great Expectations_23 pocket 53## 8 Great Expectations_15 joe 50## 9 Great Expectations_18 joe 50## 10 The War of the Worlds_16 brother 50## # ... with 104,711 more rows
如今咱們的數據框word_counts是整齊的,每行一個文檔,但topicmodels包須要一個DocumentTermMatrix。 咱們能夠將每行一個令牌轉換爲DocumentTermMatrix帶有tidytext的表cast_dtm()。
chapters_dtm <- word_counts %>% cast_dtm(document, word, n)chapters_dtm
而後,咱們可使用該LDA()功能建立一個四主題模型。在這種狀況下,咱們知道咱們正在尋找四個主題,由於有四本書; 在其餘問題中,咱們可能須要嘗試一些不一樣的值k。
chapters_lda <- LDA(chapters_dtm,k =4,control =list(seed =1234))chapters_lda ## A LDA_VEM topic model with 4 topics.
就像咱們在美聯社的數據中所作的那樣,咱們能夠檢查每一個主題的每一個詞的機率。
## # A tibble: 72,860 x 3## topic term beta## ## 1 1 joe 5.83e-17## 2 2 joe 3.19e-57## 3 3 joe 4.16e-24## 4 4 joe 1.45e- 2## 5 1 biddy 7.85e-27## 6 2 biddy 4.67e-69## 7 3 biddy 2.26e-46## 8 4 biddy 4.77e- 3## 9 1 estella 3.83e- 6## 10 2 estella 5.32e-65## # ... with 72,850 more rows
這已將模型轉換爲每行一個主題的單行格式。對於每一個組合,該模型計算該術語從該主題生成的機率。例如,術語「joe」從主題1,2或3產生幾乎爲零的機率,但它佔主題4的1.45%。
咱們可使用dplyr top_n()來查找每一個主題中的前5個術語。
top_terms <- chapter_topics %>% group_by(topic) %>% top_n(5, beta) %>% ungroup() %>% arrange(topic, -beta)top_terms ## # A tibble: 20 x 3## topic term beta## ## 1 1 elizabeth 0.0141## 2 1 darcy 0.00881## 3 1 miss 0.00871## 4 1 bennet 0.00695## 5 1 jane 0.00650## 6 2 captain 0.0155## 7 2 nautilus 0.0131## 8 2 sea 0.00885## 9 2 nemo 0.00871## 10 2 ned 0.00803## 11 3 people 0.00680## 12 3 martians 0.00651## 13 3 time 0.00535## 14 3 black 0.00528## 15 3 night 0.00448## 16 4 joe 0.0145## 17 4 time 0.00685## 18 4 pip 0.00682## 19 4 looked 0.00637## 20 4 miss 0.00623
ggplot2可視化
R語言中對文本數據進行主題模型topicmodeling分析
本分析中的每一個文檔都表明一個章節。所以,咱們可能想知道哪些主題與每一個文檔相關聯。
## # A tibble: 772 x 3## document topic gamma## ## 1 Great Expectations_57 1 0.0000135## 2 Great Expectations_7 1 0.0000147## 3 Great Expectations_17 1 0.0000212## 4 Great Expectations_27 1 0.0000192## 5 Great Expectations_38 1 0.354## 6 Great Expectations_2 1 0.0000172## 7 Great Expectations_23 1 0.551## 8 Great Expectations_15 1 0.0168## 9 Great Expectations_18 1 0.0000127## 10 The War of the Worlds_16 1 0.0000108## # ... with 762 more rows
這些值中的每個都是該文檔中從該主題生成的單詞的估計比例。例如,該模型估計,Great Expectations_57文檔中的每一個單詞只有來自主題1(「傲慢與偏見」)的機率爲0.00135%。
如今咱們有了這些話題機率,咱們能夠看到咱們的無監督學習在區分四本書方面作得如何。咱們但願書中的章節大部分(或徹底)都是從相應的主題中產生的。
首先,咱們將文檔名稱從新分爲標題和章節,以後咱們能夠將每一個文檔的每一個主題機率可視化。
## # A tibble: 772 x 4## title chapter topic gamma## ## 1 Great Expectations 57 1 0.0000135## 2 Great Expectations 7 1 0.0000147## 3 Great Expectations 17 1 0.0000212## 4 Great Expectations 27 1 0.0000192## 5 Great Expectations 38 1 0.354## 6 Great Expectations 2 1 0.0000172## 7 Great Expectations 23 1 0.551## 8 Great Expectations 15 1 0.0168## 9 Great Expectations 18 1 0.0000127## 10 The War of the Worlds 16 1 0.0000108## # ... with 762 more rows
R語言中對文本數據進行主題模型topicmodeling分析
咱們注意到,幾乎全部來自「 傲慢與偏見」,「世界大戰 」和「 海底二萬里 」的章節都被認爲是一個單獨的主題。
chapter_classifications <- chapters_gamma %>% group_by(title, chapter) %>% top_n(1, gamma) %>% ungroup()chapter_classifications
而後,咱們能夠將每本書與每本書的「共識」主題(其章節中最多見的主題)進行比較,並查看哪些主題常常被錯誤識別。
LDA算法的一個步驟是將每一個文檔中的每一個單詞分配給一個主題。文檔中的單詞越多,則一般gamma該文檔 - 主題分類的權重越大()。
咱們可能想要採用原始文檔字對,並查找每一個文檔中的哪些字詞分配給哪一個主題。
assignments <- augment(chapters_lda,data =chapters_dtm)assignments
.topic每一個文檔中每一個術語都分配了一個主題。(augment老是以開頭添加額外的列.,以防止覆蓋現有的列)。咱們能夠將此assignments表格與共識書籍標題結合起來,找出哪些詞語被錯誤分類。
## # A tibble: 104,721 x 6## title chapter term count .topic consensus## ## 1 Great Expectations 57 joe 88. 4. Great Expectations## 2 Great Expectations 7 joe 70. 4. Great Expectations## 3 Great Expectations 17 joe 5. 4. Great Expectations## 4 Great Expectations 27 joe 58. 4. Great Expectations## 5 Great Expectations 2 joe 56. 4. Great Expectations## 6 Great Expectations 23 joe 1. 4. Great Expectations## 7 Great Expectations 15 joe 50. 4. Great Expectations## 8 Great Expectations 18 joe 50. 4. Great Expectations## 9 Great Expectations 9 joe 44. 4. Great Expectations## 10 Great Expectations 13 joe 40. 4. Great Expectations## # ... with 104,711 more rows
真正的book(title)和分配給它的book()的組合consensus對於進一步的探索是有用的。例如,咱們能夠將混淆矩陣可視化,使用dplyr's count()和ggplot2 geom_tile顯示一本書中的單詞被分配給另外一本書的頻率。
R語言中對文本數據進行主題模型topicmodeling分析
混淆矩陣顯示了LDA分配每本書的單詞的位置。這張表的每一行都表明每一個單詞來自的真實書籍,每一列表明它分配的書籍。
什麼是最多見的錯誤的話?
wrong_words <- assignments %>% filter(title != consensus)wrong_words ## # A tibble: 3,500 x 4## title consensus term n## ## 1 Great Expectations Pride and Prejudice love 44.## 2 Great Expectations Pride and Prejudice sergeant 37.## 3 Great Expectations Pride and Prejudice lady 32.## 4 Great Expectations Pride and Prejudice miss 26.## 5 Great Expectations The War of the Worlds boat 25.## 6 Great Expectations Pride and Prejudice father 19.## 7 Great Expectations The War of the Worlds water 19.## 8 Great Expectations Pride and Prejudice baby 18.## 9 Great Expectations Pride and Prejudice flopson 18.## 10 Great Expectations Pride and Prejudice family 16.## # ... with 3,490 more rows
咱們能夠看到, 也經常將一些詞語分配給「世界的傲慢與偏見」或「戰爭」。對於其中的一些詞,如「愛」和「女士」,這是由於它們在「傲慢與偏見」中更常見(咱們能夠經過檢查計數來證明)。
另外一方面,有一些錯誤分類的詞在他們錯誤分配的小說中從未出現過。例如,咱們能夠確認只出如今「flopson」 遠大前程,即便它分配給了「傲慢與偏見」 。
word_counts %>% filter(word == "flopson") ## # A tibble: 3 x 3## document word n## ## 1 Great Expectations_22 flopson 10## 2 Great Expectations_23 flopson 7## 3 Great Expectations_33 flopson 1
LDA()topicmodels包中的函數只是潛在Dirichlet分配算法的一個實現。例如,mallet包(Mimno 2013)實現了一個用於文本分類工具的MALLET Java包的包裝,而tidytext包也爲該模型輸出提供了整理器。
library(mallet)# create a vector with one string per chaptercollapsed
然而,一旦模型建立完成,咱們就能夠以幾乎相同的方式使用本章其他部分描述的函數tidy()和augment()函數。這包括提取每一個主題中的單詞機率或每一個文檔中的主題。
可使用ggplot2以與LDA輸出相同的方式探索和可視化模型。