基于之前關于文本聚類和文本模型的博客,我們現在可以深入探討一個經典主題 - 情感分析。情感分析通過計算方式識別和分類文本中的情感,幫助理解公眾意見或消費者反饋。
什么是情感分析?
情感分析確定文本背后的情感基調,將其分類為積極、消極或中性。它被廣泛用于社交媒體監控和理解消費者需求。
為什么使用情感分析?
- 公眾意見:評估對話題或品牌的情緒。
- 消費者洞察:快速識別客戶反應(例如,Expedia加拿大的商業案例)。
挑戰
人類語言很復雜,機器在處理諷刺等細微差別時存在困難(例如,"太~~~~好了!!"可能被誤讀為積極)。算法正在不斷發展以處理這些情況,但還不能達到100%的準確性。
情感分析流程
- 文本預處理:
- 分詞:將文本分割成單詞或短語。
- 停用詞過濾:刪除常見詞(如"和"、“的”)。
- 否定處理:處理否定詞(如"不好"與"不是不好")。
- 詞干提取:將詞還原為詞根形式(如"跑步"到"跑")。
- 情感分類:使用詞典或算法分配極性(積極/消極)。
- 情感評分:量化情感強度,考慮大寫等因素(如"GOOD"表示更強的情緒)。
示例數據
文本 | 情感 |
---|---|
喜歡悉尼的德國面包店… | 積極 |
@VivaLaLauren 我的也壞了!… | 消極 |
@Mofette 太棒了!愿原力與你同在… | 積極 |
R語言中的情感分析
使用R的tm
、syuzhet
和其他包,我們可以預處理文本并分析情感。
預處理和詞云
library(tm)
library(SnowballC)
library(wordcloud)
library(RColorBrewer)# 用于情感分析的示例文本數據
text <- c("我絕對喜歡這個產品!它超出了我所有的期望,運行完美。","服務太差了。我從未對一次購買如此失望過。","這個還行。不是很好,但也不差。我想它能完成工作。","客服團隊非常樂于助人,幾分鐘內就解決了我的問題。太棒了!","考慮到價格,質量相當差。根據評論我期望會更好。","這是我今年買過的最好的東西。每一分錢都值得!","我對發貨延遲感到非常沮喪。產品很好,但等待時間讓人無法接受。","說明不夠清晰,但一旦我弄明白了,產品就如描述的那樣工作。","我不會向任何人推薦這個。完全浪費金錢和時間。","設計很漂亮,使用非常方便。我對這次購買非常滿意!"
)docs <- Corpus(VectorSource(text))
toSpace <- content_transformer(function(x, pattern) gsub(pattern, " ", x))
docs <- tm_map(docs, toSpace, "/")
docs <- tm_map(docs, toSpace, "@")
docs <- tm_map(docs, content_transformer(tolower))
docs <- tm_map(docs, removeNumbers)
docs <- tm_map(docs, removeWords, stopwords("english"))
docs <- tm_map(docs, removePunctuation)
docs <- tm_map(docs, stripWhitespace)
docs <- tm_map(docs, stemDocument)# 創建詞-文檔矩陣
dtm <- TermDocumentMatrix(docs)
dtm_m <- as.matrix(dtm)
dtm_v <- sort(rowSums(dtm_m), decreasing=TRUE)
dtm_d <- data.frame(word = names(dtm_v), freq=dtm_v)# 生成詞云,調整參數
# 設置圖形邊距(下、左、上、右)
par(mar = c(0, 0, 0, 0)) # 移除所有邊距# 創建新圖形,設置更大尺寸
png("wordcloud.png", width = 10, height = 8, units = "in", res = 300) # 高分辨率set.seed(1234)
wordcloud(words = dtm_d$word, freq = dtm_d$freq, min.freq = 1,max.words = 50,random.order = FALSE, rot.per = 0, # 不旋轉scale = c(4, 0.8), # 最大和最小詞之間的比例colors = brewer.pal(8, "Dark2"),vfont = c("sans serif", "plain"),use.r.layout = TRUE # 更好的布局算法
)dev.off() # 關閉設備# 顯示保存的圖像
if (requireNamespace("png", quietly = TRUE) && requireNamespace("grid", quietly = TRUE)) {library(png)library(grid)if (file.exists("wordcloud.png")) {img <- png::readPNG("wordcloud.png")grid::grid.raster(img)} else {warning("未找到詞云圖像。請檢查文件路徑。")}
} else {warning("請安裝'png'和'grid'包以顯示詞云。")
}
這段代碼預處理文本,去除噪音,并在詞云中可視化頻繁出現的詞。
情感評分
使用syuzhet
進行不同詞典的情感分析:
library(syuzhet)
library(ggplot2)# 使用多種方法進行情感評分
syuzhet_vector <- get_sentiment(text, method="syuzhet")
bing_vector <- get_sentiment(text, method="bing")
afinn_vector <- get_sentiment(text, method="afinn")# 比較前幾個分數
rbind(sign(head(syuzhet_vector)),sign(head(bing_vector)),sign(head(afinn_vector))
)# 使用NRC進行情感分類
d <- get_nrc_sentiment(text)
td <- data.frame(t(d))
td_new <- data.frame(rowSums(td))
names(td_new) <- "count"
td_new <- cbind("sentiment" = rownames(td_new), td_new)# 創建更具信息量的圖表
ggplot(td_new, aes(x = reorder(sentiment, count), y = count, fill = sentiment)) +geom_bar(stat = "identity") +theme_minimal() +theme(axis.text.x = element_text(angle = 45, hjust = 1),legend.position = "none") + # 移除圖例,因為它是多余的labs(title = "情感分析結果",x = "情感",y = "計數") +scale_fill_brewer(palette = "Set3") +coord_flip() # 翻轉坐標以獲得更好的可讀性# 創建多個可視化
# 1. 基本情感分數比較
sentiment_scores <- data.frame(Text = 1:length(text),Syuzhet = syuzhet_vector,Bing = bing_vector,Afinn = afinn_vector
)# 重塑數據以便繪圖
sentiment_long <- tidyr::pivot_longer(sentiment_scores, cols = c(Syuzhet, Bing, Afinn),names_to = "Method",values_to = "Score")# 圖表1:比較不同的情感評分方法
p1 <- ggplot(sentiment_long, aes(x = Text, y = Score, fill = Method)) +geom_bar(stat = "identity", position = "dodge") +theme_minimal() +labs(title = "情感評分方法比較",x = "文本樣本",y = "情感分數") +scale_fill_brewer(palette = "Set2")# 圖表2:NRC情感分析(上面已創建)
p2 <- ggplot(td_new, aes(x = reorder(sentiment, count), y = count, fill = sentiment)) +geom_bar(stat = "identity") +theme_minimal() +theme(axis.text.x = element_text(angle = 45, hjust = 1),legend.position = "none") +labs(title = "情感分析結果",x = "情感",y = "計數") +scale_fill_brewer(palette = "Set3") +coord_flip()# 圖表3:詞云(上面已創建)
# 詞云已保存為"wordcloud.png"# 顯示所有圖表
print(p1)
print(p2)# 打印匯總統計
cat("\n情感分數匯總:\n")
print(summary(sentiment_scores[, -1]))# 打印最積極和最消極的文本
cat("\n最積極的文本:\n")
print(text[which.max(syuzhet_vector)])
cat("\n最消極的文本:\n")
print(text[which.min(syuzhet_vector)])
情感分數匯總:Syuzhet Bing Afinn Min. :-1.750 Min. :-2.00 Min. :-5.00 1st Qu.:-0.250 1st Qu.: 0.00 1st Qu.:-0.75 Median : 0.325 Median : 0.00 Median : 1.50 Mean : 0.600 Mean : 0.80 Mean : 2.20 3rd Qu.: 1.738 3rd Qu.: 2.75 3rd Qu.: 5.75 Max. : 3.150 Max. : 4.00 Max. :10.00 最積極的文本:
[1] "客服團隊非常樂于助人,幾分鐘內就解決了我的問題。太棒了!"最消極的文本:
[1] "我對發貨延遲感到非常沮喪。產品很好,但等待時間讓人無法接受。"
這段代碼使用syuzhet
、bing
和afinn
詞典進行情感評分,并使用NRC詞典可視化情感(如喜悅、悲傷)。
基于詞典的分析
像bing
和afinn
這樣的詞典為詞分配情感分數:
- Bing:二元(積極/消極,例如"放棄"=消極)。
- Afinn:數值分數(例如"放棄"=-2)。
- NRC:對情感進行分類(憤怒、喜悅等)。
示例:酒店情感分數
酒店 | Agoda情感 | Agoda評分 | Booking.com情感 | Booking.com評分 |
---|---|---|---|---|
One World | 6.85 | 8.5 | 6.59 | 8.5 |
Summer Suite | 7.27 | 8.4 | 7.1 | 8.7 |
這些分數反映了評論的整體情感,通常與評分一致,但提供了更深層次的情感洞察。
結論
情感分析提供了一種強大的方式來理解文本中的情感,盡管由于語言的復雜性需要謹慎解釋。使用R的tm
和syuzhet
包,你可以預處理文本、評分情感并可視化情緒,使其成為社交媒體或評論分析的理想工具。