A tibble: 6 × 2
word | n |
---|---|
good | 359 |
friend | 166 |
hope | 143 |
happy | 125 |
love | 117 |
deal | 92 |
我们在这里看到的大多是关于
friend
和love
的积极、快乐的话语。
我们还可以检查每部小说的情绪如何变化。我们只需几行主要是 dplyr 函数就可以做到这一点。首先,我们使用 Bing 词典和 inner_join() 找到每个单词的情感分数。
接下来,我们计算每本书的某些位置有多少积极和消极的词。这样我们可以分析情绪的变化情况。我们在这里定义一个索引来跟踪我们在叙述中的位置;该索引(使用整数除法)对 80 行文本的部分进行计数。
一小段文本可能没有足够的单词来很好地估计情绪,但对于太大的文本可能会导致正负情绪抵消。对于这些书,使用80行效果很好,但这可能会因单个文本、行的开头长度等而有所不同。然后我们使用 pivot_wider() 以便我们在不同的列中拥有消极和积极的情绪,最后计算净情绪(正面 - 负面)。
library(tidyr)
jane_austen_sentiment <- tidy_books %>%
inner_join(get_sentiments("bing")) %>%#使用bing情绪词典进行内连接
count(book, index = linenumber %/% 80, sentiment) %>%#按八十行为一个小段进行记数
pivot_wider(names_from = sentiment, values_from = n, values_fill = 0) %>%#将数据转换成宽数据
mutate(sentiment = positive - negative)#计算净情绪,如果大于0说明是积极情绪,小于0说明是消极的
jane_austen_sentiment %>% head()
A tibble: 6 × 5
book | index | negative | positive | sentiment |
---|---|---|---|---|
Sense & Sensibility | 0 | 16 | 32 | 16 |
Sense & Sensibility | 1 | 19 | 53 | 34 |
Sense & Sensibility | 2 | 12 | 31 | 19 |
Sense & Sensibility | 3 | 15 | 31 | 16 |
Sense & Sensibility | 4 | 16 | 34 | 18 |
Sense & Sensibility | 5 | 16 | 51 | 35 |
现在我们可以在每部小说的情节轨迹上绘制这些情绪分数。请注意,我们绘制在x轴上的索引,是对应的小段文本,即每隔八十行为一段,这也反应了每本书的时间情绪变化
library(ggplot2)
ggplot(jane_austen_sentiment, aes(index, sentiment, fill = book)) +
geom_col()+#绘制柱形图
facet_wrap(~book, ncol = 2, scales = "free\_x")#根据不同书进行分面绘图,两行
我们可以在上图中看到,每部小说故事情节的情绪变化
3.对比三种情感字典
如何选用不同的情绪词典,我们可能需要更多信息,了解哪一个适合我们研究的目的。现在我们使用三个不同的情感词典,并分析情感在《傲慢与偏见》中是如何变化的。 首先,让我们使用 filter() 从我们感兴趣的一本小说中选择单词。代码如下:
pride_prejudice <- tidy_books %>%
filter(book == 'Pride & Prejudice')
pride_prejudice %>% head()
A tibble: 6 × 4
book | linenumber | chapter | word |
---|---|---|---|
Pride & Prejudice | 1 | 0 | pride |
Pride & Prejudice | 1 | 0 | and |
Pride & Prejudice | 1 | 0 | prejudice |
Pride & Prejudice | 3 | 0 | by |
Pride & Prejudice | 3 | 0 | jane |
Pride & Prejudice | 3 | 0 | austen |
我们现在可以使用inner_join()计算不同形式的情感
注意:AFINN词典是通过-5—+5来衡量情感的。而其他两个词典以二进制方式对情感单词进行分类。
# 使用AFINN词典
afinn <- pride_prejudice %>%
inner_join(get_sentiments("afinn")) %>% #内连接,得到带有情感的文本
group_by(index = linenumber %/% 80) %>% #每隔80行作为一小段
summarise(sentiment = sum(value)) %>% #这里我们进行一个求和处理,因为这里是以数字表示情感的
mutate(method = "AFINN")
# bing词典
bing <- pride_prejudice %>%
inner_join(get_sentiments("bing")) %>%#使用bing词典进行内连接
mutate(method = "Bing")%>%
count(index = linenumber %/% 80, sentiment) %>%
pivot_wider(names_from = sentiment,
values_from = n,
values_fill = 0) %>%
mutate(sentiment = positive - negative)
# 使用nrc词典
nrc <- pride_prejudice %>%
inner_join(get_sentiments("nrc") %>%
filter(sentiment %in% c('positive','negative'))) %>%
mutate(method = "NRC")%>%
count(index = linenumber %/% 80, sentiment) %>%
pivot_wider(names_from = sentiment,
values_from = n,
values_fill = 0) %>%
mutate(sentiment = positive - negative)
现在我们比较使用三个不同词典的结果进行可视化分析
bind_rows(afinn,
bing_and_nrc) %>%
ggplot(aes(index, sentiment, fill = method)) +
geom_col(show.legend = FALSE) +
facet_wrap(~method, ncol = 1, scales = "free\_y")
用于情感分析的三个不同词典给出的结果在绝对意义上是不同的,但在小说情节中具有相似的相对轨迹。我们在小说中几乎相同的地方看到了类似的情绪低谷和高峰,但绝对值明显不同。
- AFINN词典给出了最大的绝对值,具有较高的正值。
- Bing 等的词典。具有较低的绝对值,并且似乎标记了较大的连续正面或负面文本块。
- NRC结果相对于其他两个词典,更积极地标记文本。
在查看其他小说时,我们发现这些方法之间存在类似的差异; NRC更偏向给予积极的情绪,AFINN 情绪有更多变化,Bing的情绪似乎会找到更长的相似文本,但三个词典都大致情绪的整体趋势。
例如,与 Bing等词典相比,为什么 NRC 词典的结果在情感上的偏差如此之大。让我们简要地看一下这些词典中有多少积极和消极的词。
get_sentiments('nrc') %>%
filter(sentiment %in% c('positive','negative')) %>%
count(sentiment)
A tibble: 2 × 2
sentiment | n |
---|---|
negative | 3316 |
positive | 2308 |
get_sentiments('bing') %>%
count(sentiment)
A tibble: 2 × 2
sentiment | n |
---|---|
negative | 4781 |
positive | 2005 |
两个词典的否定词都多于肯定词,但 Bing 词典中否定词与肯定词的比率高于 NRC 词典。这将有助于分析我们在上图中看到的效果,以及单词匹配中的任何系统差异,例如如果 NRC 词典中的否定词与简·奥斯汀使用得很好的词不匹配。无论这些差异的来源是什么,在选择情感词典进行分析时,这些都是要注意.
4.最常见的积极和消极的单词
拥有情绪和词的数据框的一个优点是我们可以分析对每种情绪有贡献的词数。通过在此处使用word和sentiment参数实现 count(),我们找出了每个词都构成每种情绪的比例。
bing_word_count <- tidy_books %>%
inner_join(get_sentiments('bing')) %>%
count(word, sentiment, sort = TrUE) %>%
ungroup()
[1m[22mJoining, by = "word"
bing_word_count %>% head()
A tibble: 6 × 3
word | sentiment | n |
---|---|---|
miss | negative | 1855 |
well | positive | 1523 |
good | positive | 1380 |
great | positive | 981 |
like | positive | 725 |
better | positive | 639 |
这可以直观地显示出来各个积极和消极的词数量, 我们可以使用ggplot2,因为我们一直在使用为处理整洁的数据帧而构建的工具。
bing_word_count %>%
group_by(sentiment) %>%
slice_max(n, n = 10) %>% #删选出前10的
ungroup() %>%
mutate(word = reorder(word, n)) %>%#重新排序
ggplot(aes(n, word, fill = sentiment)) +
geom_col(show.legend = FALSE) +
facet_wrap(~sentiment, scales = "free\_y") +
labs(x = "Contribution to sentiment",
y = NULL)
上图我们发现了情绪分析中的异常情况; “miss”这个词被判断否定词, 但在简·奥斯汀的作品中,它被用作年轻未婚女性的称号。为了去除这样的错误,我们可以使用 bind_rows() 轻松地将“miss”添加到自定义停用词列表中。我们可以通过这样的策略来实现它。
custom_stop_words <- bind_rows(tibble(word = c("miss"),
lexicon = c("custom")),
stop_words)
custom_stop_words %>% head()
A tibble: 6 × 2
word | lexicon |
---|---|
miss | custom |
a | SMArT |
a’s | SMArT |
able | SMArT |
about | SMArT |
above | SMArT |
5.词云绘制
我们已经看到,这种整洁的文本挖掘方法与 ggplot2 配合得很好,但是让我们的数据以整洁的格式显示对其他绘图也很有用。
例如,考虑使用基本 r 图形的 wordcloud 包。这样我们就可以绘制词云图。
library(wordcloud)
tidy_books %>%
anti_join(stop_words) %>%
count(word) %>%
with(wordcloud(word, n, max.words = 100))#出现次数最多的前100个
现在我们进一步进行情感分析的词云图绘制, 使用内连接标记正面和负面词,然后找到最常见的正面和负面词。在这里我们需要使用reshape2包的
comparison.cloud()
函数,其余操作和我们之前一样
library(reshape2)
tidy_books %>%
inner_join(get_sentiments("bing")) %>%
count(word, sentiment, sort = TrUE) %>%
acast(word ~ sentiment, value.var = "n", fill = 0) %>%
comparison.cloud(colors = c("blue", "red"),
max.words = 100)
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
words = 100)
![png](https://img-blog.csdnimg.cn/img_convert/415efecad0a3fc384fe2e9eeeeb58e7a.png#pic_center)
[外链图片转存中...(img-GJQHUfDq-1714822976626)]
[外链图片转存中...(img-AxCty3Yd-1714822976628)]
**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**[需要这份系统化资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618545628)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**