親手制作一個《哈利·波特》人物圖譜,原來羅恩和赫敏的姻緣從第一部就已注定?
文摘菌記得小時候看《哈利·波特》小說的時候,最難記住的就是那些音譯的名字,又長又多,最后只能關注那幾個主要人物,跟著主要劇情一路過去,當個爽文看完了。
這就導致一些邊緣人物根本沒關注到,也錯過了J·K·羅琳埋下的許多小伏筆。
比如盧娜與韋斯萊其實是鄰居關系,這個在《火焰杯》中眾人出發(fā)去世界杯時有伏筆,但是很少有人第一遍看的時候能注意到。
大概是為了從一開始就厘清人物關系,Medium上一位博主Tomaz Bratanic開發(fā)了一個小項目,用Selenium結合SpaCy來創(chuàng)建一個Neo4j哈利·波特人物圖譜,把《哈利·波特》第一部中所有的人物都納入一張網(wǎng)絡中,人物關系一目了然。
從圖譜中我們似乎可以看到,三人小分隊中,哈利和赫敏的直接連接很少,這兩人出現(xiàn)時基本羅恩都在,而羅恩和赫敏二人卻連接很多,這讓人不禁聯(lián)想,難道從第一部開始,J·K·羅琳就安排好了羅恩和赫敏的姻緣了?
制作一個這樣的圖譜需要5步,動手試試?
八卦的事情我們先放在一邊,還是先來看看Tomaz Bratanic是如何制作這一圖譜的。
總體來說,整個過程被分為了5步:
爬取“哈利波特迷”網(wǎng)站數(shù)據(jù)
書籍文本預處理
基于 SpaCy 規(guī)則匹配的實體識別
推斷字符之間的關系
將結果存儲到 Neo4j 圖形數(shù)據(jù)庫中
作者將整個過程記錄了一個Google Colab notebook,方便大家動手試試,鏈接如下:
https://github.com/tomasonjo/blogs/blob/master/harry_potter/HarryPotterNLP.ipynb
第一步,爬取“哈利波特迷”網(wǎng)站數(shù)據(jù)
“哈利波特迷”網(wǎng)站頁面包含了第一本書中的人物列表,其中還包括了各個人物最初出現(xiàn)在哪一章,這可以幫助進一步消除字符的歧義,因此第一步就是去爬取“哈利波特迷”網(wǎng)站數(shù)據(jù)。
作者選擇使用Selenium進行Web頁面抓取,然后形成一個字符列表,其中包含人物最先出現(xiàn)的章節(jié)的信息,此外,每個角色都有一個網(wǎng)頁,上面有關于角色的詳細介紹。
例如,從赫敏·格蘭杰的頁面你可以觀察到一個結構化的表格,其中包含了更多的信息,作者使用別名部分的實體提取然后添加其他字符細節(jié),如家族和血型來豐富最后的人物圖譜。
第二步,書籍文本預處理
由于文本中人物往往散布于文本的不同位置,其中涉及到的人物通??梢杂卸喾N不同的表達方式,例如某個語義關系中的實體可能是以代詞形式(比如he和she)出現(xiàn)的,為了更準確且沒有遺漏地從文本中抽取相關信息,必須要對文章中的指代現(xiàn)象進行消解。
在尋找合適的指代消解(Co-reference Resolution)模型時,作者考慮了NeuralCoref和AllenNLP,這兩個模型都能提供指代消解功能。
但是在試用AllenNLP模型輸入整個章節(jié)時,作者的內存不夠,把一個章節(jié)分割成一個句子列表又運行得非常慢,所以作者最后還是使用了NeuralCoref,NeuralCoref很輕松地處理了整個章節(jié),并且工作得更快。
準備好了文本,是時候從文本中提取提到的字符了。
第三步,基于SpaCy規(guī)則匹配的實體識別
作者一開始試了幾個不同的命名實體識別(Named Entity Recognition,NER)模型,SpaCy、HuggingFace、Flair,甚至是 Stanford NLP。
但是這些模型都不能很好地滿足我的要求。因此,作者決定使用SpaCy基于規(guī)則的模式匹配特性,而不是自己訓練模型。
根據(jù)第一步從網(wǎng)站上搜集的數(shù)據(jù),現(xiàn)在已經(jīng)知道我們需要在尋找哪些角色,下面只需要找到一種方法,在文本中盡可能完美地匹配他們。
首先必須為每個字符定義文本模式。這需要添加全名作為我們正在尋找的模式,然后我們使用空格將名稱分開,并創(chuàng)建一個模式,將這個,名字中的每個單詞分開。舉個例子,如果我們定義了matcher模式,我們最終會得到3個不同的文本模式來表示給定的字符:
全名: 阿不思·鄧不利多(Albus Dumbledore)
名: 阿不思(Albus)
姓: 鄧布利多(Dumbledore)
當然,還會有許多特例,比如“天狼星布萊克”(Sirius Black),為了不將所有“黑色”(Black)和人物搞混,作者定義只有當“布萊克”是標題格式的,才會假設“小天狼星布萊克”被引用。
另外,還需要考慮當只提到姓時,如何匹配到正確的人,比如這句話,“Weasley, get over here!”,這里面的Weasley可能指向羅恩的任何一個兄弟姐妹,這時必須為實體消歧提出一個通用的解決方案。
第四步,推斷字符之間的關系
解決了實體識別問題,其實就已經(jīng)完成了整個工作中最難的部分。
推斷角色之間的關系則非常簡單,首先,需要定義相互作用的距離閾值或兩個字符之間的關系。
作者將距離閾值定義為14,也就是說,如果兩個字符在14個單詞的距離內共同出現(xiàn),那么我們假設它們一定是相互作用的。
此外,作者還合并了一些實體以避免扭曲結果,比如“哈利今天過得很愉快。他下午去找鄧布利多談話了?!?/p>
如果簡單分析這句話,會讓“哈利”和“鄧布利多”發(fā)生兩次互動,因此需要按照引用單個實體的相同字符的順序合并實體,來解決重復統(tǒng)計的問題。
第五步,將結果存儲到Neo4j圖形數(shù)據(jù)庫中
提取了字符之間的交互網(wǎng)絡后,剩下的唯一工作就是將結果存儲到圖形數(shù)據(jù)庫中。
導入查詢非常簡單,因為這里處理的是單向網(wǎng)絡,如果使用的 是作者準備的Colab Notebook,那么創(chuàng)建一個免費的Neo4j Sandbox 或者免費的Aura數(shù)據(jù)庫實例來存儲結果將是最簡單的。
最后,可視化結果,我們就能得到最終的人物關系圖譜。
靈感來自《權利的游戲》人物圖譜,下一步要分析哈利·波特宇宙
在文章中,作者表示,這一項目的靈感來源于此前Andrew Beveridge建立的《權利的游戲》人物圖譜。
相比于《哈利·波特》,《權力的游戲》擁有更多的人物和劇情,生成的網(wǎng)絡也更加復雜。
除了對整個1-8季進行分析,Andrew Beveridge還對每一季做了人物圖譜分析,看看每一季中誰和誰是盟友,誰跟誰又是敵人。感興趣的讀者可以查看項目鏈接:
https://networkofthrones.wordpress.com/
相比而言,Tomaz Bratanic的《哈利·波特》人物圖譜項目更容易上手,讀者可以用第二部或第三部嘗試這種方法,唯一需要稍微調整的是實體消除歧義過程。
《哈利·波特》人物圖譜GitHub鏈接:
https://github.com/tomasonjo/blogs/blob/master/harry_potter/HarryPotterNLP.ipynb
Tomaz Bratanic表示,下一步他將著手整個哈利·波特宇宙的分析,將《神奇動物在哪里》的部分也囊括進去,感興趣的小伙伴可以持續(xù)關注。
參考鏈接:
https://medium.com/neo4j/turn-a-harry-potter-book-into-a-knowledge-graph-ffc1c45afcc8
https://networkofthrones.wordpress.com/
https://harrypotter.fandom.com/wiki/Main_Page
*博客內容為網(wǎng)友個人發(fā)布,僅代表博主個人觀點,如有侵權請聯(lián)系工作人員刪除。