【譯文】使用文本挖掘技術分析Twitter用戶對電影的評價

【譯文】使用文本挖掘技術分析Twitter用戶對電影的評價

作者 佚名

譯者 錢亦欣

引言

使用一些建模分析手段來評價電影的成功已經屢見不鮮,這類預測模型常常使用注入電影製作成本,類型,主演,出品方等結構化數據作為輸入。然而,在社交媒體日益發達的現在,人們時常會在Twitter,Facebook等網站上發表自己的意見和建議。社交媒體已然是衡量電影觀眾情緒的潛在工具了。

本文將以2017年的寶萊塢電影「Rangoon」為例子,用R語言來分析Twitter用戶對他的情感評價。

目錄

  1. 文本挖掘導論

  2. 分析目標

  3. 數據

  4. 分析過程1 - 使用「tm」包

  5. 分析過程2 - 使用「suazyhet」包

  6. 結論

  7. 為電影預測構建一個演算法

1. 文本挖掘導論

在進入正題之前,我們不妨問這樣一個問題:什麼是文本挖掘?

簡而言之,文本挖掘就是把非結構化的文本數據轉化為有意義的觀點的過程。轉化後的觀點可以針對用戶建議,產品評價,情感分析和消費者反饋等

與傳統方法依靠的結構化數據不同,文本挖掘的對象是結構鬆散有諸多語法和拼寫錯誤的文本,而且還時常包含多種語言。這使得整個挖掘過程變得更有趣且富有挑戰性。

在文本挖掘領域有兩大常用方法:情感分析和詞包挖掘(Bag of Words,a.k.a bow model)。

情感分析關心單詞的結構和語法,詞包挖掘則是把文本(句子,微博,文檔)視作單詞的集合(包)。

2. 分析目標

每個分析項目都應該有個明確的目標,本文的目標就是對Twitter數據使用文本挖掘技術來獲取用戶對電影「Rangoon」的情感評價。

3. 數據

分析的第一步就是要獲取數據,如今獲取Twitter數據只需要通過網頁爬蟲或者API就可以實現。本文則使用R語言中的「twitterR」包收集了10000條關於「Rangoon」的推文

我使用了「twitterR」採集了10000條關於「Rangoon」的推特和回復,這部電影與2017年2月24日上映,我採集了2月25日的推特並把它們存在csv文件里,再用「readr」包讀入R里。從推特採集數據的過程超出了本文的範疇,暫且不表。

# 載入數據library(readr)rangoon = read_csv("rangoontweets.csv")

4. 用「tm」包進行分析

「tm」包是在R內進行文本挖掘的框架,它會基於廣泛使用的「Bag of Words」原則進行分析。這一方法非常簡單易用,它會統計文本中每個詞的頻率,然後把詞頻作為變數。這一看似簡單的方法其實非常有效,並且現在已經成了自然語言處理領域的基準。

主要步驟如下:

Step 1: 載入相應的包並且提出數據

# 載入包library(stringr)library(readr)library(wordcloud)library(tm)library(SnowballC)library(RWeka)library(RSentiment)library(DT)# 提出相關數據r1 = as.character(rangoon$text)

Step 2: 數據預處理

對文本進行預處理可以顯著提升Bag of Words方法(其他方法也是)的效果。

預處理的第一步是構建語料庫,簡單地說就是一本詞典。語料庫一旦建立好了,預處理也就完成了大半。

首先,讓我們移除標點,基礎方法就是把不是數字和字母的對象移除。當然,有時標點符號也很有用,像web地址中標點就有提示符的作用。所以,移除標點要具體問題具體分析,本文中則不需要它們。

之後,我們把單詞都變成小寫防止統計錯誤。

預處理的另一個任務是把沒有用的片語去掉,很多詞被頻繁使用但只在句子里才有意義。這些詞被稱為「stop words」(停詞)。舉個例子,像the,is這些詞就是停詞,它們對之後的情感分析無甚作用,所以就把它們去掉來給數據瘦身。

另一個重要環節是stemming(詞幹提取),他能把不同結尾的詞轉換成原始形式。比如,love,loved,loving這些詞之間的差異很小,可以用一個詞幹也就是lov來代表它們,這個降維過程就叫詞幹提取。

一旦我們把數據預處理好了,我們就可以開始統計詞頻來為未來建模做準備了。tm包提供了一個叫「DocumentTermMatrix」的來完成相應功能,它會返回一個矩陣,矩陣的每一行代表文檔(本例中是一條推特),列就代表了推特中的單詞。具體的數據就代表了每條對特相應單詞的出現頻率。

我們生成這個舉證並把它命名為「dtm_up」。

# 數據預處理set.seed(100)sample = sample(r1, (length(r1)))corpus = Corpus(VectorSource(list(sample)))corpus = tm_map(corpus, removePunctuation)corpus = tm_map(corpus, content_transformer(tolower))corpus = tm_map(corpus, removeNumbers)corpus = tm_map(corpus, stripWhitespace)corpus = tm_map(corpus, removeWords, stopwords(english))corpus = tm_map(corpus, stemDocument)dtm_up = DocumentTermMatrix(VCorpus(VectorSource(corpus[[1]]$content)))freq_up <- colSums(as.matrix(dtm_up))

Step 3: 計量情感

現在是時候來進行情感打分了。R中的「calculate_sentiment」函數可以完成這一工作,它會讀入文本並計量每個句子的情感得分。這一函數會把文本作為輸入,輸出一個包含每個句子情感得分的向量。

讓我們來實現這一功能。

# 計量情感sentiments_up = calculate_sentiment(names(freq_up))sentiments_up = cbind(sentiments_up, as.data.frame(freq_up))sent_pos_up = sentiments_up[sentiments_up$sentiment == Positive,]sent_neg_up = sentiments_up[sentiments_up$sentiment == Negative,]cat("We have far lower negative Sentiments: ",sum(sent_neg_up$freq_up)," than positive: ",sum(sent_pos_up$freq_up))

我們發現褒義詞和貶義詞的比例是5780/3238 = 1.8,乍一看電影還是受到觀眾的好評的

讓我們分別深入挖掘好拼和差評來獲取更深的理解。

- 褒義詞

下方的表格展示了被分類為好拼的文本的詞頻,我們通過datatable函數實現這個功能。

「love」,「best」和「brilliant」是好評中的三大高頻詞。

DT::datatable(sent_pos_up)

textsentimentfreq_upaccomplishaccomplishPositive1adaptadaptPositive2appealappealPositive4astonishastonishPositive3awardawardPositive85aweawePositive11awestruckawestruckPositive5benefitbenefitPositive1bestbestPositive580betterbetterPositive186

我們可以把這個結果用詞雲進行可視化,詞雲中單詞個頭越大代表它出現頻率越高。

- 褒義詞詞雲

layout(matrix(c(1, 2), nrow=2), heights=c(1, 4))par(mar=rep(0, 4))plot.new()set.seed(100)wordcloud(sent_pos_up$text,sent_pos_up$freq,min.freq=10,colors=brewer.pal(6,"Dark2"))

詞雲也顯示了love是好評中頻率最高的單詞。

- 貶義詞

重複之前的步驟,貶義詞中「miss」,「dismal」和「hell」是top3,讓我們也用詞雲來可視化。

DT::datatable(sent_neg_up)

textsentimentfreq_upabruptabruptNegative3addictaddictNegative1annoyannoyNegative3arduousarduousNegative1attackattackNegative2awkwardawkwardNegative2badbadNegative64badbadNegative64baselessbaselessNegative1bashbashNegative5beatbeatNegative22

貶義詞詞雲

plot.new()set.seed(100)wordcloud(sent_neg_up$text,sent_neg_up$freq, min.freq=10,colors=brewer.pal(6, "Dark2")

注意:在文本分析時,最好對分析的對象有一定了解。比如「bloody」或者「hell」這樣的貶義詞可能是從電影的插曲「bloody hell」中被統計出來的。相似的,「miss」也可能來自於Ragoon中的女性人物「Miss Julia」,這樣把它作為貶義詞處理可能就不合適了。

考慮到這些異象,我們要對分析結果做進一步處理。之前統計的褒貶詞的比例是1.8,現在3238個貶義詞中的144個「hell」先不考慮,這樣這個比例會上升到1.87。

這是得到觀眾對Rangoon平價的第一步,看起來好評居多,我們需要用更細緻的方法省查這一結論。

5. 用 「syuzhet」 包進行分析

「syuzhet」包會使用3個情感詞典來進行情感分析。與上述方法不同,它能分析更廣範圍的情感。當然,第一步還是要對數據進行預處理,包括對html鏈接進行清洗。

# 方法2 - 使用syuzhet包text = as.character(rangoon$text) ## 去掉回復some_txt<-gsub("(RT|via)((?:\b\w*@\w+)+)","",text)## 清洗html鏈接some_txt<-gsub("http[^[:blank:]]+","",some_txt)## 去掉人名some_txt<-gsub("@\w+","",some_txt)## 去掉標點some_txt<-gsub("[[:punct:]]"," ",some_txt)## 去掉數字some_txt<-gsub("[^[:alnum:]]"," ",some_txt)

在預處理之後,可以用「get_nrc_sentiment」函數來提取情感。這個函數會調用NRC情感詞典來計量不同的情感的程度和相關比例。

這個函數會輸出一個數據框,每一行代表原始文件的一個句子,每一列代表一種情感類型和正負情感配比。一共有十列,代表「anger」, 「anticipation」, 「disgust」, 「fear」, 「joy」, 「sadness」, 「surprise」, 「trust」, 「negative」, 「positive」。

讓我們把這個結果也可視化

# 可視化library(ggplot2)library(syuzhet)mysentiment<-get_nrc_sentiment((some_txt))

# 得到每種情感的得分mysentiment.positive =sum(mysentiment$positive)mysentiment.anger =sum(mysentiment$anger)mysentiment.anticipation =sum(mysentiment$anticipation)mysentiment.disgust =sum(mysentiment$disgust)mysentiment.fear =sum(mysentiment$fear)mysentiment.joy =sum(mysentiment$joy)mysentiment.sadness =sum(mysentiment$sadness)mysentiment.surprise =sum(mysentiment$surprise)mysentiment.trust =sum(mysentiment$trust)mysentiment.negative =sum(mysentiment$negative)

# 繪製柱狀圖yAxis <- c(mysentiment.positive,+ mysentiment.anger,+ mysentiment.anticipation,+ mysentiment.disgust,+ mysentiment.fear,+ mysentiment.joy,+ mysentiment.sadness,+ mysentiment.surprise,+ mysentiment.trust,+ mysentiment.negative)

xAxis <- c("Positive","Anger","Anticipation","Disgust","Fear","Joy","Sadness","Surprise","Trust","Negative")colors <- c("green","red","blue","orange","red","green","orange","blue","green","red")yRange <- range(0,yAxis) + 1000barplot(yAxis, names.arg = xAxis, xlab = "Emotional valence", ylab = "Score", main = "Twitter sentiment for Movie Rangoon 2017", sub = "Feb 2017", col = colors, border = "black", ylim = yRange, xpd = F, axisnames = T, cex.axis = 0.8, cex.sub = 0.8, col.sub = "blue")colSums(mysentiment)

看看這個柱狀圖和每種情感的總和,積極情感(「positive」,「joy」,「trust」)比消極情感(「negative」,「disgust」,「anger」)得分高很多。這或許暗示了觀眾對電影評價比較正面。

6. 結論

兩個方法都表名電影「Rangoon」得到了觀眾的肯定。

7. 對電影表現構建一個預測模型

本文專註於對電影「Rangoon」相關推特進行情感分析,然而對於預測票房而言這可能不是很有作用。眾所周知,很多電影叫好不叫座,一些腦殘片卻能賺得盆滿缽滿。

這可咋整?

解決方案就是分析同類型電影的PT/NT比(好評差評比例)轉換為票房的歷史數據,並構建一個擬合與預測兼優的模型。這個模型可以用來預測電影是否會獲得商業上的成功,在Rangoon這個例子里,1.87會被作為輸入的值。

由於這個問題超過了本文的範疇,我們不會展開討論。但需要注意的是文本分析也能用來預測電影票房。

結語

本文使用電影相關推特來進行情感分析,需要注意的是採集的推特的發表時間可能很重要。在電影上映前後的推特可能在情感上有很大分歧,不同的預處理方式也會影響到結果。

本文的目的不在分析電影Rangoon的好壞,而是提出了情感分析的具體步驟。在這一領域還有很多先進的方法,本文介紹的兩個方法是最簡單直觀的。

如有任何問題請在下方留言。

註:原文刊載於Analytic Vidhya網站

原文鏈接:Measuring Audience Sentiments about Movies using Twitter and Text Analytics

推薦閱讀:

基於R語言的唐僧「師徒關係」分析(詞向量分析)
【乾貨】--手把手教你完成文本情感分類
達觀數據情感分析架構演進
輿情監控技術如何應對各類水軍刷屏?
學習文本挖掘,如何入門?

TAG:文本挖掘 | R编程语言 |