如何站在大数据的角度看100000个故事

最近我从马克·里德尔那拿到了很棒的自然语言方面的数据集:从WIKI下载了112000个故事作品的情节。其中包括了书籍、电影、电视剧集、视频游戏等有“情节”的任何内容。

这为我定量分析故事结构提供了一个很好的契机。在这篇文章中,我将会进行一个简单的分析来检验在故事中的特定情节上,哪些词会频繁出现,比如一些提示了故事开端开始,中间情节或结局的词。

根据我对文本挖掘的习惯,我将使用Julia Silge和我在去年开发的tidytext软件包。如果你想要了解更多相关知识,请参阅我们的这本在线书Text Mining with R: A Tidy Approach,它将很快被O'Reilly出版了。我将为您提供部分代码,以便您可以继续跟上我的思路。为了保持文章简洁,关于可视化部分的代码我基本都没贴出来。但所有的文章和代码都可以在GitHub上找到。

建立

我从GitHub上下载并解压缩了plots.zip文件。然后我们将这些文件读入R,然后将它们与dplyr使用结合。

library(readr) library(dplyr) # Plots and titles are in separate files plots <- read_lines("~/Downloads/plots/plots", progress = FALSE) titles <- read_lines("~/Downloads/plots/titles", progress = FALSE) # Each story ends with an <EOS> line plot_text <- data_frame(text = plots) %>% mutate(story_number = cumsum(text == "<EOS>") + 1, title = titles[story_number]) %>% filter(text != "<EOS>")

然后,我们可以使用tidytext将情节整理为一个简洁的结构,一个词一行。

library(tidytext) plot_words <- plot_text %>% unnest_tokens(word, text) plot_words ## # A tibble: 40,330,086 × 3 ## story_number title word ## <dbl> <chr> <chr> ## 1 1 Animal Farm old ## 2 1 Animal Farm major ## 3 1 Animal Farm the ## 4 1 Animal Farm old ## 5 1 Animal Farm boar ## 6 1 Animal Farm on ## 7 1 Animal Farm the ## 8 1 Animal Farm manor ## 9 1 Animal Farm farm ## 10 1 Animal Farm summons ## # ... with 40,330,076 more rows

该数据集包含了超过4000万个单词,112000个故事。

故事开头和结尾部分的单词

约瑟夫坎贝尔提出了名为“hero‘s journey”的分析方法,他认为每个故事都有一致的结构。无论你是否对他的理论买账,假如一个故事在一开头就是高潮开始的或者到了结束却引入了新角色,你可能也会觉得这是很令人诧异的。

这种结构可以用单词的量化结构来表现-- 有些词汇应该被期望在开始时出现,而一些词词则在应该在结尾出现。

一个简单的测量方法,我们将记录每个单词的位置的中值,同时也记录它出现的次数。

word_averages <- plot_words %>% group_by(title) %>% mutate(word_position = row_number() / n()) %>% group_by(word) %>% summarize(median_position = median(word_position), number = n())

我们对在少数情节出现并且出现频率比较小的词语不感兴趣,所以我们将筛选出至少出现了2500次的单词,并只对他们进行分析。

word_averages %>% filter(number >= 2500) %>% arrange(median_position) ## # A tibble: 1,640 × 3 ## word median_position number ## <chr> <dbl> <int> ## 1 fictional 0.1193618 2688 ## 2 year 0.2013554 18692 ## 3 protagonist 0.2029450 3222 ## 4 century 0.2096774 3583 ## 5 wealthy 0.2356817 5686 ## 6 opens 0.2408638 7319 ## 7 california 0.2423856 2656 ## 8 angeles 0.2580645 2889 ## 9 los 0.2661747 3110 ## 10 student 0.2692308 6961 ## # ... with 1,630 more rows

例如,我们可以看到,“fictional”这个词大约用了2700次,其中半数出现在故事的前12% - 这表明这个词与开端有很大的关系。

下图展示了与故事开头和结尾关联最大的一些词。

img

与开头相关的词时常是描述一些设定:“这个故事主角(protagonist),是一个年轻(young),富有(weathy)的 19世纪(century)的学生(student),最近(rencently)从在美国加利福尼亚州洛杉矶编造的大学(university College)毕业。它们大部分都是名词和形容词,可以用来描述并限定一个人,一个地点或者一个时期。

相比之下,在故事结尾处的单词就充满情感!有些词本身就有结尾的意思。比如“ending”和“final”,但也有一些动词反映了激烈刺激的情节,比如“英雄向恶棍射击(shoots)冲向(rushes)女主角,并道歉(apologizes)。两人团聚(reunited),他们吻了(kiss)。“

可视化词汇趋势

中值的方法为我们提供了一个有用的汇总统计信息,让我们仔细研究下统计信息的内容。首先,我们将每个故事分成几个十分位数(前10%,后10%等),并计算每个单词在每个十分位数内的次数。

decile_counts <- plot_words %>% group_by(title) %>% mutate(word_position = row_number() / n()) %>% ungroup() %>% mutate(decile = ceiling(word_position * 10) / 10) %>% count(decile, word)

上述工作使我们可以通过绘制不同单词在不同情节的位置中的频率分布。我们想看看哪些单词集中在开始/结束的:

img

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpjfxs.html