本文约
3900
字,
建议阅读
10
分钟。
本文以自然语言处理视角,探索英雄们的说话方式。
《复仇者联盟4:终局之战》仍在热映中。在看到大结局的同时,本文将带你通过数据科普的眼光来回顾《复仇者联盟3:无限战争》:看看这群世界上最强的超级英雄们最爱说的词汇是哪些?
这次回顾旅程将从一个新的角度出发——自然语言处理。
本文通过使用spaCy(用于处理和理解大量文本的NLPPython 开源程序库)对复联3的剧本进行分析,并研究以下几个项目:
-
整部电影中使用最频繁的前十个动词、名词、副词和形容词。
-
特定角色使用最多的动词和名词。
-
电影中提及次数排位前30位的命名实体(namedentities)。
-
各角色之间台词对白的相似性,例如雷神的台词对白和灭霸台词对白的相似性。
看见代码和专业词汇就想睡?今天你可以放心了!为读者着想,本文中使用的词汇和术语都是非技术性的,所以就算是你没有接触过NLP、AI、机器学习或者诸如*insert buzzword here*之类的代码,你都能理解并掌握本文想要传达的信息哦!所以,不看代码也不会影响你对其余内容的理解。
灭霸 图片来源:Marvel
处理数据
实验中使用的数据或文本语料库(通常在NLP中称为语料库)是电影脚本。但是,在使用这些数据之前,需要做一下筛选。因为,心理描写、动作描述或者场景描写的文本,以及每句台词前的角色名(仅指示说话人,不作为文本分析的语料库)都不是本次研究的对象。所以,诸如“Thanoscrushes the Tesseract, revealing the blue Space Stone…” (灭霸捏碎了宇宙魔方,获得了蓝色的空间宝石……)之类的句子都被删除了。
此外,作为spaCy数据处理步骤的一部分,“I”(我)、“you”(你)、“an”(一个)这类被标记为停止词(常用的单词,多为冠词、介词、副词或连词)的术语被将不做处理。同时,实验过程中只使用单词的标准形式,也就是词根。举例说明,动词“talk”、“talked”和“talking”是同一个词“talk”(说话)的不同形式,所以这些词的词根就是“talk”。
要在spaCy中处理一段文本,首先需要加载语言模型,然后在文本语料库上调用模型进行文本处理。结果会输出一个涵盖所有已处理文本的Doc文件。
import spacy
nlp = spacy.load("en_core_web_md")
with open('cleaned-script.txt', 'r') asfile:
text = file.read()
doc = nlp(text)
在spaCy中创建Doc文件。
然后就可以获得一个经过处理、有效信息占比极高的语料库。紧接着就可以开始实验了!
整部电影中使用最频繁的前十个动词、名词、副词和形容词
是否可能仅通过了解出现最频繁的动词就推断出电影的整体走向和情节呢?下文的图表证明了这一观点。
“I know” (我了解……)、“you think” (你觉得……)是最常见的短语。
“know” (了解)、“go” (去)、 “come”(来)、“get” (获得)、“think”(思考)、“tell” (告诉)、“kill” (谋杀)、“need” (需要)、“stop” (制止)、和“want” (想要) 。从中能够推断出什么?介于这部电影于2018年上映,相信大部分观众都已经知道它讲述了一个什么样的故事:根据这些动词推断出《复仇者联盟3:无限战争》是关于了解、思考和调查如何去阻止某物或某人。
通过以下代码就能统计各个动词出现次数:
importspacy
nlp= spacy.load("en_core_web_md")
withopen('cleaned-script.txt', 'r') as file:
text = file.read()
doc= nlp(text)
pos_count= {}
fortoken in doc:
if token.is_stop:
continue
if token.pos_ == 'VERB':
if token.lemma_ in pos_count:
pos_count[token.lemma_] += 1
else:
pos_count[token.lemma_] = 1
print("top10 VERBs {}".format(sorted(pos_count.items(), key=lambda kv: kv[1],reverse=True)[:10]))
那么描述动词的词——副词也会有同样的实验效果吗?
“I seriously don’t know how you fit your head into that helmet.” (我真不知道那个头盔怎么塞得进你的脑袋。)——奇异博士。
对于一部关于阻止紫薯精毁灭半个宇宙的电影来说,台词中有很多类似“right”(没错)、“exactly”(就是这样)、“better”(更好地)这种具有积极意向的副词。
所以,知道了电影中的动作和动作描述,现在是时候看看名词了。
“You will pay for his life with yours.Thanos will have that stone.” (这将是以命换命,灭霸总会得到那块宝石。)——暗夜比邻星
结果显示,“stones”(宝石)不出意料地出现次数最多,毕竟整部电影都在围绕它们发展。出现次数排第二的是灭霸想要摧毁的“life”(生命),接着是复仇者们没有多少的“time”(时间)(注意:出现次数较多也可能是因为电影中多次提到了“the Time Stone”——时间宝石)。
最后,在进入下一个实验项目之间,探究一下形容词或描述名词的单词。与副词的情况类似,这里也有“good”(好的)和“right”(对的)等表达积极意义的词汇,以及“okay”(没问题)和“sure”(当然)等表示肯定的词汇。
“I'm sorry, little one.” (对不起,小家伙)——灭霸
特定角色使用最多的动词和名词
前面的图片列举了电影中最常见的动词和名词。虽然这些结果让我们对电影的整体感觉和情节有了一定的了解,但它并没有过多地讲述各个角色的个人经历。因此,在特定角色的个人台词中,通过使用前面相同的程序,找到了出现次数前十的动词和名词。
由于电影中有很多角色,所以本实验中只选择了一些台词数量较多的角色。这些角色分别是钢铁侠、奇异博士、卡魔拉、雷神、火箭浣熊、星爵、乌木喉和灭霸。对不起,队长没有入选。
下图展示了这些角色使用次数最多的10个名词。
星爵到底为什么这么频繁地叫德拉克斯?
意料之外的是,大多数情况下,亲爱的英雄们最常提及的名词都是同伴的名字。例如,钢铁侠提及“孩子”(指蜘蛛侠)9次,火箭浣熊叫了奎尔(星爵)3次,而星爵叫了(其实是大吼)德拉克斯7次。
通过进一步的观察,可以推断出每个角色心中最重要的东西。拿钢铁侠的情况举例,统计数据表明“地球”对他来说十分重要。卡魔拉的情况也很相似,她总是念叨着“生命”、“宇宙”和“星球”这些涵义更广阔的实体,并为之付出了自己的生命。奇异博士反复提及他与其余英雄不甚相同的目标——保护时间宝石。还有雷神,由于他和灭霸之间的国仇家恨,他提及灭霸的名字多达8次,当然还少不了新的“干脆面”好友——长得像只“兔子”的火箭浣熊。最后一张图的数据表明灭霸不断念叨着要集齐所有无限宝石,并且多次呼唤他的女儿。
名词极具表达意义,但动词可能无法像名词这样鲜明地表达角色的特征。在下面的图片中你会看到,动词的表达能力相比名词的来说产生的效果甚微。像“know”(了解)、“want”(想要)和“get”(获得)这样缺乏特征性的普遍被使用的单词出现的频数都很高。然而,灭霸的头号粉丝——乌木喉可能拥有整个语料库中最独特的动词。乌木喉就像一个忠仆:除了想方设法获取时间宝石,他主要从事的工作就是用“聆听”、“感到荣幸”等词鼓吹他主子的使命。啧啧,真谄媚。
“Hear me, and rejoice. You have had the privilege of being saved by the Great Titan…”(跪下聆听并感到荣幸吧!你有幸被最伟大的救世主拯救……)——乌木喉
最后来个彩蛋(大雾):格鲁特说得最多的是——
“I am Groot.”(我是格鲁特。)
命名实体
到目前为止,我们已经完成了全篇电影、各位英雄和反派最常用的动词、名词、副词和形容词的探索。然而,为了充分理解一直在研究的所有词,需要加入一些上下文,即命名实体,进行研究。
根据有关spaCy的网页说明,命名实体是“指定名称的实际对象——例如,一个人、一个国家、一个产品或一本书的标题。”所以,了解这些实体就意味着了解角色在说些什么。在spaCy程序源库中,实体都有一个预测的标签,该标签将实体分成人、产品、艺术词汇等等类型
(https://spacy.io/api/annotation#named-entities)
,从而为后续实验提供额外的粒度级别,有助于对实体进行进一步分类。但是,为了简化过程,本次实验中将使用实体本身而不是实体分类。
这些是出现次数排名前30的实体。
“MATEFAYA HU”(必胜)是瓦坎达贾巴里部落战士战斗前的口号。
首先,考虑到整部电影都是关于灭霸的,所以灭霸出现次数最多是情理之中。紧随其后的是他的女儿、影片的核心人物之一——卡魔拉。然后在第三位的是格鲁特(不需要解释了吧),紧随其后的是钢铁侠和其他复仇者,以及一些地点,如纽约,阿斯加德和瓦坎达(瓦坎达万岁)。除了英雄名字和地点之外,“六颗无限宝石”(“six Infnity Stones”)的“六”、时间宝石(the Time Stone)和灵魂宝石(the Soul Stone)分别出现在第14、15和16位。意料之外的是,将灭霸吸引到地球来的心灵宝石不在前30名之列。
可以通过以下代码读取Doc文件中各个单词的实物标签‘ents’:
importspacy
nlp = spacy.load("en_core_web_md")
with open('cleaned-script.txt', 'r') as file:
text = file.read()
doc = nlp(text)
entities = {}
for ent in