自然語言處理帶你深入了解《復聯3》的超級英雄們
經過漫長的等待,漫威迷心心念念的《復聯4》(《復仇者聯盟4:終局之戰》)終於來了,相信有不少人在工作日的凌晨守在大熒幕前,目睹了超級英雄們是如何再次拯救世界的。同時這場持續10年(甚至不止10年)的超級英雄故事也隨著《復聯4》的上映畫上了句號。
關於劇情,觀眾們的感受千人千面,但數據從來都是最誠實的見證者。所以讓我們來重溫一下《復聯3》,只不過回顧的不只是劇情,而是用自然語言處理(簡稱NLP)研究電影的腳本。
在本文中,我們會用NLP Python開源庫spaCy來幫助我們處理和理解大量的文本,並分析電影腳本,以研究以下概念:
電影中排名前10位的動詞,名詞,副詞和形容詞。
由特定角色說出的動詞和名詞。
電影中排名前30位的實體。
每對人物台詞之間的相似性,例如,雷神和滅霸台詞之間的相似性。
除了這些,我們同時還會用代碼解釋spaCy是如何進行這些研究的。
對代碼和技術辭彙感興趣的朋友可以關注本文,文中使用的辭彙和術語大部分都是非技術性的,所以即使你沒有NLP、AI、機器學習等專業技能,也能夠理解本文想要表達的主要想法和概念。
瘋狂泰坦
處理數據
實驗中使用的數據或文本語料庫(在NLP中通常稱為語料庫)是電影腳本。但是,在使用數據之前,我們需要對數據進行清理。主要是刪除一些描述動作的評論或場景,以及說出該行台詞的角色名字(實際上,該名稱用於了解誰說了什麼,但不是用於分析的實際語料庫的一部分)。此外,作為spaCy數據處理步驟的一部分,我們不用標記為停止字的術語,也就是常用的單詞,如"I"、"you"、"an"等。而且,我們只使用引理,也就是每個單詞的正則形式。例如,動詞"talk"、"talking"和"talking"是同一個詞素的形式,其引理是"talk"。
在spaCy中處理一段文本時,我們首先需要載入語言模型,然後在文本語料庫上調用模型。結果是一個Doc對象,一個保存已處理文本的對象。
import spacy
# load a medium-sized language model
nlp = spacy.load("en_core_web_md")
with open("cleaned-script.txt", "r") as file:
text = file.read()
doc = nlp(text)
在spaCy中創建Doc對象
現在我們已經有了經過處理的語料庫,接下來要開始我們的研究了。
十大動詞、名詞、副詞和形容詞
僅僅看動詞就能知道電影的整體動作或情節嗎?本文的第一個圖表說明了這一點。
"I know", "you think"是一些最常見的短語
Know"、"go"、"come"、"get"、"think"、"tell"、"kill"、"need"、"stop"和 "want". 我們能從中推斷出什麼?可能是因未看過電影的緣故,作者根據這些動詞總結出,《復仇者聯盟3:無限戰爭》是關於了解、思考和調查如何去阻止某事或某個人的。
這就是我們使用spaCy獲取動詞的方法:
import spacy
# load a medium-sized language model
nlp = spacy.load("en_core_web_md")
with open("cleaned-script.txt", "r") as file:
text = file.read()
doc = nlp(text)
# map with frequency count
pos_count = {}
for token in doc:
# ignore stop words
if token.is_stop:
continue
# pos should be one of these:
# "VERB", "NOUN", "ADJ" or "ADV"
if token.pos_ == "VERB":
if token.lemma_ in pos_count:
pos_count[token.lemma_] += 1
else:
pos_count[token.lemma_] = 1
print("top 10 VERBs {}".format(sorted(pos_count.items(), key=lambda kv: kv[1], reverse=True)[:10]))
那麼副詞的情況怎麼樣?
「我真的不知道你的頭是怎麼塞進頭盔里的」——奇異博士
對於一部關於阻止一個人毀滅半個宇宙的電影來說,口語中有很多實證主義的成分,比如"right"、"exactly"和"better"。
我們已經知道動詞以及副詞的情況,所以接下來讓我們一起來看看名詞。
"你會用生命付出代價,Thanos會擁有那塊石頭。" - Proxima Midnight
看到"stones"作為第一出現並不奇怪,畢竟這部電影是關於石頭的。第二個詞是"life",這是滅霸想要摧毀的東西,緊隨其後的是"time",而這正是《復仇者聯盟》所沒有的(注:"time"上榜也有可能是因為提到了時間之石)。
最後,我們倆看一下描述名詞的形容詞。與副詞類似,形容詞中也有"good"和"right"等表達積極意義的辭彙,以及"okay"和"sure"等表示肯定的辭彙。
"我很抱歉,小傢伙。" - 滅霸
由特定角色說出的動詞和名詞
在此之前,我們看到了電影中提到的最常見的動詞和名詞。雖然這讓我們對電影的整體感覺和情節有所了解,但它並沒有說明角色的個人經歷。因此,我們使用相同的程序來查找前十個動詞和名詞。
由於電影中有很多角色,我們只選擇其中比較合理和完整的角色。這些角色分別是鋼鐵俠Tony Stark、奇異博士、格莫拉、雷神托爾(Thor)、火箭浣熊、 Peter Quill(星爵)、Ebony Maw(烏木喉)和滅霸。
下一張圖片顯示了這些角色使用的最常用名詞。
星爵稱德拉克斯什麼?
我發現,在大多數情況下,英雄們最常用的名詞都是夥伴的名字,這很奇怪,甚至令人耳目一新。例如,鋼鐵俠說了9次"kid"(指蜘蛛俠),火箭叫了3次Quill (星爵),而Quill自己叫了7次。
通過進一步的觀察,我們可以推斷出對每個角色來說什麼是最重要的。以鋼鐵俠為例,數據表明地球對他來說是有價值的。與他相似的是格莫拉,她總是想著更高的目標"生命"、"宇宙"和"行星",並最終為此付出了代價。奇異博士還有反覆提到的另一個目標:保護石頭。還有雷神托爾,他和滅霸之間有私人恩怨,並且連續喊了8遍他的名字。還有瘋狂泰坦滅霸,他一直在收集無極寶石,另外就是關於他的女兒。
雖然名詞是有表達意義的,但動詞就不一樣了。在下一張圖片中可以看到,動詞不像名詞那樣豐富多彩。像"know"、"want"和"get"這樣的詞佔據了大部分的榜首。然而,有一個角色可能擁有整個語料庫中最獨特的動詞:烏木喉(Ebony Maw)。滅霸的頭號追隨者,就像忠實的僕人一樣,他的目標是得到時間寶石和宣揚主人的使命。他最常說的就是"hear," 和"rejoice."
"聽我說,高興吧。你有幸被偉大的泰坦所拯救……"——烏木喉
彩蛋:以下是格魯特(Groot)最常用的名詞。
我是Groot。
命名實體
到目前為止,我們已經掌握了超級英雄和反派們在這部史詩級電影中最常說的動詞、名詞、副詞和形容詞。然而,要充分理解這些詞語和人物,我們還需要命名實體。
引用spaCy的網站上的話,命名實體是"指定名稱的真實世界對象。例如,一個人、一個國家、一個產品或一個書名"。 所以,了解這些實體,意味著了解角色在說些什麼。在spaCy包中,實體具有預測標籤,該標籤將實體分類為多種類型中的一種,例如人、產品、藝術品等。並給予我們額外的粒度級別,這可能有助於進一步對它們進行分類。
這些是前30個實體。
MAYEFA YA HU"是瓦坎達賈巴里戰士的口號
第一位是滅霸,畢竟電影是關於他的,這不足為奇。第二位是他的女兒格莫拉,影片的核心人物之一。第三位是Groot,緊隨其後的是Tony和其他復仇者以及一些地方,如紐約,阿斯加德和瓦坎達。除英雄和地點外,還有兩個"六"(見實體號)。時間之石和靈魂之石分別位於第15位和第16位。令人驚訝的是,將滅霸帶到地球上的心靈之石不在名單之列。
要訪問spaCy中的實體,請像這樣讀取Doc的屬性ents:
import spacy
# load a medium-sized language model
nlp = spacy.load("en_core_web_md")
with open("cleaned-script.txt", "r") as file:
text = file.read()
doc = nlp(text)
# create an entity frequency map
entities = {}
# named entities
for ent in doc.ents:
# Print the entity text and its label
if ent.text in entities:
entities[ent.text] += 1
else:
entities[ent.text] = 1
print("top entities {}".format(sorted(entities.items(),
key=lambda kv: kv[1], reverse=True)[:30]))
每對人物台詞之間的相似性
當我們討論每個角色最重要的動詞時,我們意識到,與名詞不同的是,大多數動詞非常相似,並且表達的感覺非常相似。像"go"和"come"這樣的詞給我們運動的印象,或者給我們角色想要去或到達某個特定地方的感覺。諸如"kill"和"stop"之類的動詞意味著確實存在一個必須阻止的巨大威脅。
考慮到這一點,為了進一步研究相似度的概念,我計算了每對字元的口語台詞之間的相似度評分
NLP中相似性的概念描述了兩段文本的合成或語法意義的接近程度。通常,相似性得分的範圍從0到1,其中0表示完全不同,1表示完全相似(或兩個文本是相同的)。從技術上講,相似性是通過測量單詞向量之間的距離來計算的,即單詞的多維表示。
下圖顯示了相似度矩陣。
結果令人意外。其實所街結果相似度為1是可以接受的,因為這部電影本身就闡述了一個主要情節,對話關聯度高是可以理解的。但是,他們的相似度太高了,看看滅霸就知道了,原本以為反派的得分會有很大不同。但慶幸的是,蜘蛛俠的分數變化很大,畢竟他只是一個在混亂中被抓住的孩子,結果有如預期。
這是如何在spaCy中計算兩個文件之間的相似性的例子:
# for the full example on how I obtained all the similarities
# see the full code at: https://github.com/juandes/infinity-war-spacy/blob/master/script.py
import spacy
# load a medium-sized language model
nlp = spacy.load("en_core_web_md")
with open("tony-script.txt", "r") as file:
tony_lines = file.read()
with open("thor-script.txt", "r") as file:
thor_lines = file.read()
tony_doc = nlp(tony_lines)
thor_doc = nlp(thor_lines)
similarity_score = tony_doc.similarity(thor_doc)
print("Similarity between Tony"s and Thor"s docs is {}".format(similarity_score))
回顧和結論
在電影《復仇者聯盟3:無限戰爭》中,我們跟隨超級英雄們展開了阻止滅霸毀滅半個宇宙的旅程。在整部電影中,我們了解到這些英雄大多有拯救世界的動機,這反映在他們表達自己的方式上。在本文中,我們在Python、NLP和spaCy中研究了英雄和反派們是如何通過他們的每句台詞來表達和交流的,重溫了鋼鐵俠對地球的忠誠、奇異博士保護時間之石的誓言、雷神托爾復仇的渴望以及滅霸毀滅宇宙的野心。


※Facebook數據再泄露 5.4億數據曝光於AWS伺服器
※如何與IT供應商談判?
TAG:IT168企業級 |