52-R語言機(jī)器學(xué)習(xí):文本挖掘

《精通機(jī)器學(xué)習(xí):基于R 第二版》學(xué)習(xí)筆記

1袖迎、數(shù)據(jù)理解與數(shù)據(jù)準(zhǔn)備

在這個(gè)案例中南捂,我們研究美國前總統(tǒng)奧巴馬的國會(huì)演講。有兩個(gè)主要的分析目標(biāo)陨囊,首先使用7篇國會(huì)演講建立一個(gè)主題模型逗抑,然后對比2010年的第一篇演講和2016年1月的最后一篇演講剧辐。

> library(pacman)
> p_load(tm, wordcloud2, magrittr)
> 
> # 設(shè)置文件所在目錄
> name <- file.path("./data_set/data-master")
> 
> # 查看文件名
> dir(name, pattern = "*.txt")
## [1] "sou2010.txt" "sou2011.txt" "sou2012.txt" "sou2013.txt" "sou2014.txt"
## [6] "sou2015.txt" "sou2016.txt"
> # 查看有多少個(gè)txt文件
> length(dir(name, pattern = "*.txt"))
## [1] 7
> # 建立語料庫,不包括corpus和document level元數(shù)據(jù)
> docs <- Corpus(DirSource(name, pattern = "*.txt"))
> docs
## <<SimpleCorpus>>
## Metadata:  corpus specific: 1, document level (indexed): 0
## Content:  documents: 7

文本整理

> # 字母全部轉(zhuǎn)換為小寫
> docs <- tm_map(docs, tolower) %>% 
      # 剔除數(shù)字
+     tm_map(removeNumbers) %>% 
      # 剔除標(biāo)點(diǎn)符號
+     tm_map(removePunctuation) %>% 
      # 剔除停用詞
+     tm_map(removeWords, stopwords("english")) %>% 
      # 剔除空白字符
+     tm_map(stripWhitespace) %>% 
      # 刪除那些不必要的詞
+     tm_map(removeWords, c("applause", "can", "cant", "will", "that", "weve", "dont", 
+     "wont", "youll", "youre"))
> 
> # 確認(rèn)文本還是純文本形式(會(huì)報(bào)錯(cuò)) 
> # docs <- tm_map(docs,PlainTextDocument)
> 
> # 創(chuàng)建DTM矩陣
> dtm <- DocumentTermMatrix(docs)
> dtm
## <<DocumentTermMatrix (documents: 7, terms: 4753)>>
## Non-/sparse entries: 10913/22358
## Sparsity           : 67%
## Maximal term length: 17
## Weighting          : term frequency (tf)
> dim(dtm)
## [1]    7 4753

這7篇演講稿包含4753個(gè)詞邮府∮兀可以通過 removeSparseTerms() 函數(shù)刪除稀疏項(xiàng),但這一步不是必需的褂傀。需要指定一個(gè)0和1之間的數(shù)忍啤,這個(gè)數(shù)值越大,表示矩陣的稀疏度越高仙辟。稀疏度表示一個(gè)名詞在文檔中的相對頻率同波,所以如果你的稀疏度閾值是0.75,那么就只刪除那些稀疏度大于0.75的名詞欺嗤。在這個(gè)例子中参萄,(1 - 0.75) * 7 = 1.75,因此煎饼,對于任何一個(gè)名詞,如果包含它的文檔少于2個(gè)校赤,它就會(huì)被刪除:

> dtm <- removeSparseTerms(dtm, 0.75)
> dim(dtm)
## [1]    7 2256

因?yàn)闆]有文檔元數(shù)據(jù)吆玖,所以應(yīng)該命名矩陣中的行筒溃,這樣才能知道每行代表的文檔:

> rownames(dtm) <- dir(name, pattern = "*.txt") %>% 
+     stringr::str_extract_all("\\d+") %>% unlist()

查看所有7行中的前5列數(shù)據(jù):

> inspect(dtm[1:7, 1:5])
## <<DocumentTermMatrix (documents: 7, terms: 5)>>
## Non-/sparse entries: 22/13
## Sparsity           : 37%
## Maximal term length: 10
## Weighting          : term frequency (tf)
## Sample             :
##       Terms
## Docs   ability able abroad absolutely accept
##   2010       1    1      2          2      1
##   2011       0    4      3          0      0
##   2012       0    3      1          1      0
##   2013       3    3      2          1      1
##   2014       0    1      4          0      0
##   2015       0    1      1          0      1
##   2016       0    1      0          0      1

2、模型構(gòu)建與模型評價(jià)

2.1 詞頻分析與主題模型

> # 計(jì)算每列詞頻總和沾乘,并降序排列
> freq <- colSums(as.matrix(dtm))
> ord <- order(freq, decreasing = T)
> freq[head(ord)]
##     new america  people    jobs     now   years 
##     193     174     169     163     157     148

找出至少出現(xiàn)125次的詞:

> findFreqTerms(dtm, 125)
##  [1] "america"   "american"  "americans" "jobs"      "make"      "new"      
##  [7] "now"       "people"    "thats"     "work"      "year"      "years"

找出與“job”詞相關(guān)性大于0.85的詞:

> findAssocs(dtm, "jobs", corlimit = 0.85)
## $jobs
## colleges    serve   market shouldnt  defense      put      tax     came 
##     0.97     0.91     0.89     0.88     0.87     0.87     0.87     0.86

生成詞云圖:

> tibble::tibble(word = names(freq), freq = freq) %>% wordcloud2(size = 1, color = "random-dark", 
+     backgroundColor = "white", minRotation = -pi/4, maxRotation = pi/4)
詞云圖

生成柱狀圖:

> tibble::tibble(word = names(freq), freq = freq) %>% dplyr::arrange(freq) %>% dplyr::top_n(10) %>% 
+     ggplot2::ggplot(aes(reorder(word, -freq), freq)) + geom_bar(stat = "identity") + 
+     labs(title = "Word Frequency", y = "", x = "") + theme_bw()
詞頻柱狀圖

建立主題模型怜奖,7篇文章建立3個(gè)主題:

> p_load(topicmodels)
> set.seed(124)
> lda <- LDA(dtm, k = 3, method = "Gibbs")
> topics(lda)
## 2010 2011 2012 2013 2014 2015 2016 
##    1    3    3    3    2    2    1

第一篇和最后一篇演講具有同樣的主題分組,看來奧巴馬以同樣的方式開始和結(jié)束了自己的任期翅阵。
查看每個(gè)主題中的前25個(gè)詞:

> terms(lda, 25)
##       Topic 1      Topic 2    Topic 3     
##  [1,] "americans"  "new"      "jobs"      
##  [2,] "year"       "make"     "now"       
##  [3,] "one"        "like"     "thats"     
##  [4,] "know"       "world"    "american"  
##  [5,] "right"      "work"     "people"    
##  [6,] "time"       "help"     "tonight"   
##  [7,] "economy"    "america"  "lets"      
##  [8,] "businesses" "congress" "america"   
##  [9,] "people"     "every"    "energy"    
## [10,] "families"   "want"     "tax"       
## [11,] "years"      "need"     "government"
## [12,] "even"       "years"    "well"      
## [13,] "take"       "job"      "also"      
## [14,] "security"   "future"   "nation"    
## [15,] "give"       "first"    "last"      
## [16,] "many"       "country"  "business"  
## [17,] "still"      "better"   "education" 
## [18,] "work"       "home"     "put"       
## [19,] "get"        "american" "get"       
## [20,] "change"     "today"    "good"      
## [21,] "care"       "back"     "reform"    
## [22,] "just"       "way"      "companies" 
## [23,] "next"       "hard"     "deficit"   
## [24,] "health"     "sure"     "must"      
## [25,] "support"    "college"  "small"

2.2 其他定量分析

比較2010年和2016年的演講:

> p_load(qdap)
> speech.16 <- readLines("./data_set/data-master/sou2016.txt") %>% paste(collapse = " ") %>% 
+     # 將文本編碼設(shè)為ASCⅡ
+     iconv("latin1", "ASCII", "")

qdap包中的 qprep() 函數(shù)打包的函數(shù)如下所示:
? bracketX() :去掉括號
? replace_abbreviation() :替換縮略語
? replace_number() :將數(shù)字替換為單詞歪玲,例如,可以將100替換為one hundred
? replace_symbol() :將符號替換為單詞掷匠,例如滥崩,可以將@替換為at

> prep16 <- qprep(speech.16) %>% 
      # 替換縮寫,如can't替換為connot
+     replace_contraction() %>% 
      # 剔除前100個(gè)常用的停用詞
+     rm_stopwords(Top100Words, separate = F) %>% 
      # 剔除句號和問號之外的所有字符
+     strip(char.keep = c(".", "?"))

將文檔分割成句子:

> sent16 <- data.frame(speech = prep16) %>% sentSplit("speech") %>% dplyr::mutate(year = "2016")
> str(sent16)
## 'data.frame':    299 obs. of  3 variables:
##  $ tot   : chr  "1.1" "2.2" "3.3" "4.4" ...
##  $ speech: chr  "mister speaker mister vice president members congress fellow americans tonight marks eighth year ive here report state union." "final im going try shorter." "know antsy back iowa." "also understand because election season expectations well achieve year low." ...
##  $ year  : chr  "2016" "2016" "2016" "2016" ...

數(shù)據(jù)框包括三個(gè)變量讹语,tot的意思是談話的順序(Turn of Talk)钙皮,作為表示句子順序的指標(biāo);speech是將文本拆分為句子顽决;year作為分組變量的演講年份短条。

對2010年的演講重復(fù)上面的步驟:

> speech.10 <- readLines("./data_set/data-master/sou2010.txt") %>% 
+     paste(collapse = " ") %>% iconv("latin1", "ASCII", "") %>% 
+     gsub("Applause.", "", .) %>% qprep() %>% 
+     replace_contraction() %>% 
+     rm_stopwords(Top100Words, separate = F) %>% 
+     strip(char.keep = c(".", "?"))
> 
> sent10 <- data.frame(speech = speech.10) %>% 
+     sentSplit("speech") %>% dplyr::mutate(year = "2010")

將兩個(gè)獨(dú)立年份的數(shù)據(jù)合成一個(gè)數(shù)據(jù)框:

> sentences <- rbind(sent10, sent16)

再看看詞頻:

> freq_terms(sentences$speech) %>% dplyr::top_n(15) %>% ggplot2::ggplot(aes(FREQ, 
+     reorder(WORD, FREQ))) + geom_bar(stat = "identity") + labs(x = "", y = "") + 
+     theme_bw()
詞云圖

建立一個(gè)詞頻矩陣,表示每篇演講中每個(gè)單詞的數(shù)量:

> word.mat <- wfm(sentences$speech, sentences$year)
> head(word.mat)
##            2010 2016
## abide         1    0
## ability       1    0
## able          1    1
## abroad        2    0
## absolutely    2    0
## abuse         0    1
> # 將矩陣按詞頻排序
> word.mat <- word.mat[order(word.mat[, 1], word.mat[, 2], decreasing = T), ]
> head(word.mat)
##           2010 2016
## our        120   85
## us          33   33
## year        29   17
## americans   28   15
## why         27   10
## jobs        23    8

為每年建立一個(gè)詞云:

> trans_cloud(sentences$speech, sentences$year, min.freq = 10)
2010

2016

對兩篇文檔進(jìn)行綜合統(tǒng)計(jì):

> ws <- word_stats(sentences$speech, sentences$year, rm.incomplete = T)
> plot(ws, label = T, lab.digits = 2)
綜合統(tǒng)計(jì)

2016年的演講要比2010年的短很多才菠,少100多個(gè)句子和差不多1000個(gè)單詞茸时。還有,2016年(10個(gè)問句)相對于2010年(4個(gè)問句)赋访,更多地使用了問句這種修辭手法屹蚊。

比較兩篇文檔的極性(情感評分):

> pol <- polarity(sentences$speech, sentences$year)
> pol
##   year total.sentences total.words ave.polarity sd.polarity stan.mean.polarity
## 1 2010             435        3900        0.052       0.432              0.121
## 2 2016             299        2982        0.105       0.395              0.267

stan.mean.polarity 表示標(biāo)準(zhǔn)化后的極性均值,就是用極性均值除以標(biāo)準(zhǔn)差进每⌒谠粒可以看到2016年的標(biāo)準(zhǔn)化極性均值(0.267)要比2010年(0.121)稍高一些。

> plot(pol)
情感評分

2010年的演講以非常悲觀的情感開始田晚,而且整體上比2016年悲觀嘱兼。通過pol對象中的數(shù)據(jù)框,可以找出最悲觀的句子贤徒。

> pol.all <- pol$all
> 
> pol.all$text.var[which.min(pol.all$polarity)]
## [1] "year ago took office amid wars economy rocked severe recession financial system verge collapse government deeply debt."

總結(jié):
文本定量分析包括:
1.極性分析通常稱為情感分析芹壕,它可以告訴你文本的情感有多么積極或者多么消極; polarity() 函數(shù);
2.自動(dòng)易讀性指數(shù)是衡量文本復(fù)雜度和讀者理解能力的一個(gè)指標(biāo)接奈;automated_readability_index()函數(shù)踢涌;
3.正式度可以表示文本和讀者之間或者演講者與聽眾之間的相關(guān)程度;formality()函數(shù)序宦;
4.多樣性表示文本中使用的不同詞數(shù)和全部詞數(shù)的比值睁壁;diversity()函數(shù);
5.分散度,或稱詞匯分散度潘明。它是一種可以幫助你理解詞在整篇文本中的分布的有用工具行剂,也是探索文本并識別模式的極好方法;dispersion_plot()函數(shù)钳降。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末厚宰,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子遂填,更是在濱河造成了極大的恐慌铲觉,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,000評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件吓坚,死亡現(xiàn)場離奇詭異撵幽,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)凌唬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,745評論 3 399
  • 文/潘曉璐 我一進(jìn)店門并齐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人客税,你說我怎么就攤上這事况褪。” “怎么了更耻?”我有些...
    開封第一講書人閱讀 168,561評論 0 360
  • 文/不壞的土叔 我叫張陵测垛,是天一觀的道長。 經(jīng)常有香客問我秧均,道長食侮,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,782評論 1 298
  • 正文 為了忘掉前任目胡,我火速辦了婚禮锯七,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘誉己。我一直安慰自己眉尸,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,798評論 6 397
  • 文/花漫 我一把揭開白布巨双。 她就那樣靜靜地躺著噪猾,像睡著了一般。 火紅的嫁衣襯著肌膚如雪筑累。 梳的紋絲不亂的頭發(fā)上袱蜡,一...
    開封第一講書人閱讀 52,394評論 1 310
  • 那天,我揣著相機(jī)與錄音慢宗,去河邊找鬼坪蚁。 笑死奔穿,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的迅细。 我是一名探鬼主播巫橄,決...
    沈念sama閱讀 40,952評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼淘邻,長吁一口氣:“原來是場噩夢啊……” “哼茵典!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起宾舅,我...
    開封第一講書人閱讀 39,852評論 0 276
  • 序言:老撾萬榮一對情侶失蹤统阿,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后筹我,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體扶平,經(jīng)...
    沈念sama閱讀 46,409評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,483評論 3 341
  • 正文 我和宋清朗相戀三年蔬蕊,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了结澄。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,615評論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡岸夯,死狀恐怖麻献,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情猜扮,我是刑警寧澤勉吻,帶...
    沈念sama閱讀 36,303評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站旅赢,受9級特大地震影響齿桃,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜煮盼,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,979評論 3 334
  • 文/蒙蒙 一短纵、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧僵控,春花似錦香到、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,470評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至泛烙,卻和暖如春理卑,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背蔽氨。 一陣腳步聲響...
    開封第一講書人閱讀 33,571評論 1 272
  • 我被黑心中介騙來泰國打工藐唠, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留帆疟,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,041評論 3 377
  • 正文 我出身青樓宇立,卻偏偏與公主長得像踪宠,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子妈嘹,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,630評論 2 359

推薦閱讀更多精彩內(nèi)容

  • 首頁 資訊 文章 資源 小組 相親 登錄 注冊 首頁 最新文章 IT 職場 前端 后端 移動(dòng)端 數(shù)據(jù)庫 運(yùn)維 其他...
    Helen_Cat閱讀 3,887評論 1 10
  • 撐傘于雨中漫步柳琢,偶有雨絲躍入傘下,打濕裙擺润脸,風(fēng)揚(yáng)起涼意沁入心中柬脸,便覺身心如水般剔透,縱有驚雷閃電毙驯,也不過人生尋常倒堕。
    綠沉lvc閱讀 244評論 0 2
  • 給定一個(gè)鏈表和一個(gè)特定值 x垦巴,對鏈表進(jìn)行分隔,使得所有小于 x 的節(jié)點(diǎn)都在大于或等于 x 的節(jié)點(diǎn)之前铭段。你應(yīng)當(dāng)保留兩...
    上行彩虹人閱讀 150評論 0 0
  • “畫室的故事”·我是加菲貓系列 (文/亦濃) 畫室的故事 上個(gè)周末骤宣,在美術(shù)課畫室,有同學(xué)當(dāng)著小辛老師的面開玩笑說“...
    開在夜里的花兒閱讀 527評論 10 7