Python基於共現提取《釜山行》人物關系


Python基於共現提取《釜山行》人物關系

一、課程介紹

1. 內容簡介

《釜山行》是一部喪屍災難片,其人物少、關系簡單,非常適合我們學習文本處理。這個項目將介紹共現在關系中的提取,使用python編寫代碼實現對《釜山行》文本的人物關系提取,最終利用Gephi軟件對提取的人物關系繪制人物關系圖。

2. 課程知識點

本課程項目完成過程中將學習:

  • 共現網絡的基本原理
  • Python代碼對《釜山行》中人物關系提取的具體實現
  • jieba庫的基本使用
  • Gephi軟件的基本使用

3. 課程來源

課程使用的操作系統為 Ubuntu 14.04。你可以在我的 Github 上找到針對《釜山行》人物關系提取的全部代碼。你也可以直接點擊查看共現網絡簡單的英文介紹

二、實驗原理

實驗基於簡單共現關系,編寫 Python 代碼從純文本中提取出人物關系網絡,並用Gephi 將生成的網絡可視化。下面介紹共現網絡的基本原理。你可以在我的博客查看對共現網絡簡單的英文介紹

實體間的共現是一種基於統計的信息提取。關系緊密的人物往往會在文本中多段內同時出現,可以通過識別文本中已確定的實體(人名),計算不同實體共同出現的次數和比率。當比率大於某一閾值,我們認為兩個實體間存在某種聯系。這種聯系可以具體細化,但提取過程也更加復雜。因此在此課程只介紹最基礎的共現網絡。

三、開發准備

打開Xfce終端,進入 Code 目錄,創建 work 文件夾, 將其作為課程的工作目錄。下載並安裝 gephi 。

$ mkdir work && cd work $ mkdir gephi && cd gephi $ wget http://labfile.oss.aliyuncs.com/courses/677/gephi-0.9.1-linux.tar.gz #下載 $ tar -zxvf gephi-0.9.1-linux.tar.gz #解壓 

下載《釜山行》的中文劇本。

$ wget http://labfile.oss.aliyuncs.com/courses/677/busan.txt

安裝jieba中文分詞。

$ sudo pip2 install jieba

四、實驗步驟

你可以通過下面命令將代碼下載到實驗樓環境中,作為參照對比進行學習。

$ wget http://labfile.oss.aliyuncs.com/courses/677/busan.py

1.觀察文本結構、准備詞典

《釜山行》劇本非常適合文本處理,語言簡潔,大致每一段對應一個關鍵情節。人物較少且易於識別,所以非常適合文本處理的學習,因此選用了《釜山行》作為課程的樣例。

由於《釜山行》人物少、關系簡單,所以我們可以通過詞典指定人物名稱的方式做實體識別。你也可以不建立字典並嘗試使用某種分詞算法或包裝好的分詞庫(如教程使用的jieba),但離開特定詞典的針對特定文本的分詞效果可能會有很大程度削弱。因此對簡單網絡而言,建立字典是效率較高的做法。

可以通過各類百科獲取《釜山行》的主要人物,你可以在百度百科中找到他們的介紹,並將人名寫入一個字典中。項目將主要人物的名稱保存在文件dict.txt中,你可以通過下面的命令下載這個字典,也可以自己新建一個文件保存。字典dict.txt需放在文件夾work下。

$ wget http://labfile.oss.aliyuncs.com/courses/677/dict.txt

2.確定需要的變量

work文件下創建代碼文件busan.py,開始進行python代碼的編寫。

在代碼中,我使用字典類型names保存人物,該字典的鍵為人物名稱,值為該人物在全文中出現的次數。我使用字典類型relationships保存人物關系的有向邊,該字典的鍵為有向邊的起點,值為一個字典edgeedge的鍵是有向邊的終點,值是有向邊的權值,代表兩個人物之間聯系的緊密程度。lineNames是一個緩存變量,保存對每一段分詞得到當前段中出現的人物名稱,lineName[i]是一個列表,列表中存儲第i段中出現過的人物。

# -*- coding: utf-8 -*- import os, sys import jieba, codecs, math import jieba.posseg as pseg names = {} # 姓名字典 relationships = {} # 關系字典 lineNames = [] # 每段內人物關系 

3.文本中實體識別

在具體實現過程中,讀入《釜山行》劇本的每一行,對其做分詞(判斷該詞的詞性是不是“人名”[詞性編碼:nr],如果該詞的詞性不為nr,則認為該詞不是人名),提取該行(段)中出現的人物集,存入lineName中。之后對出現的人物,更新他們在names中的出現次數。

jieba.load_userdict("dict.txt") # 加載字典 with codecs.open("busan.txt", "r", "utf8") as f: for line in f.readlines(): poss = pseg.cut(line) # 分詞並返回該詞詞性 lineNames.append([]) # 為新讀入的一段添加人物名稱列表 for w in poss: if w.flag != "nr" or len(w.word) < 2: continue # 當分詞長度小於2或該詞詞性不為nr時認為該詞不為人名 lineNames[-1].append(w.word) # 為當前段的環境增加一個人物 if names.get(w.word) is None: names[w.word] = 0 relationships[w.word] = {} names[w.word] += 1 # 該人物出現次數加 1 

你可以在 with 代碼塊之后添加以下代碼輸出生成的 names 來觀察人物出現的次數:

for name, times in names.items(): print name, times 

運行代碼

python busan.py 

在實驗樓中的顯示結果如下圖:

此處輸入圖片的描述

4.根據識別結果構建網絡

對於 lineNames 中每一行,我們為該行中出現的所有人物兩兩相連。如果兩個人物之間尚未有邊建立,則將新建的邊權值設為 1,否則將已存在的邊的權值加 1。這種方法將產生很多的冗余邊,這些冗余邊將在最后處理。

for line in lineNames: # 對於每一段 for name1 in line: for name2 in line: # 每段中的任意兩個人 if name1 == name2: continue if relationships[name1].get(name2) is None: # 若兩人尚未同時出現則新建項 relationships[name1][name2]= 1 else: relationships[name1][name2] = relationships[name1][name2]+ 1 # 兩人共同出現次數加 1 

5.過濾冗余邊並輸出結果

將已經建好的 names 和 relationships 輸出到文本,以方便 gephi 可視化處理。輸出邊的過程中可以過濾可能是冗余的邊,這里假設共同出現次數少於 3 次的是冗余邊,則在輸出時跳過這樣的邊。輸出的節點集合保存為 busan_node.txt ,邊集合保存為 busan_edge.node 。

with codecs.open("busan_node.txt", "w", "gbk") as f: f.write("Id Label Weight\r\n") for name, times in names.items(): f.write(name + " " + name + " " + str(times) + "\r\n") with codecs.open("busan_edge.txt", "w", "gbk") as f: f.write("Source Target Weight\r\n") for name, edges in relationships.items(): for v, w in edges.items(): if w > 3: f.write(name + " " + v + " " + str(w) + "\r\n") 

完成所有代碼編寫后,運行

python busan.py 

在文件夾work下將會生成busan_node.txtbusan_edge.node

6.可視化網絡

前面對《釜山行》劇本中的人物關系數據進行了處理,下面我們將使用gephi這個軟件來將人物關系可視化,以便展示的更直觀,畢竟生硬的數字和文本,或許只有你才懂,其他人可看不明白。

使用 gephi 導入生成的網絡,並生成簡單的可視化布局。執行下面命令啟動 gephi 。

$ cd gephi-0.9.1 $ cd bin $ ./gephi 

點擊 文件 -> Import SpreadSheets 。

此處輸入圖片的描述

分別選擇節點表格和邊表格導入上面代碼中生成的兩個文件,分隔符選擇 空格 ,編碼選擇 GB2312 。

此處輸入圖片的描述

此處輸入圖片的描述

導入后 gephi 將顯示所有節點。此時節點沒有合適的布局,如下圖。你可以在最上方的 數據資料 選項卡中查看圖中所有的邊和節點,對於分詞不准確導致的噪音,可以手動刪除。

此處輸入圖片的描述

分別點擊右側 統計 欄中 平均度 和 模塊化 運行計算。模塊化運算時 Resolution 值填寫 0.5 。

此處輸入圖片的描述

點擊左上角外觀節點第一個選項卡,選擇數值設定,選擇Modularity Class

此處輸入圖片的描述

選中第二個選項卡,選擇數值設定,選擇連入度,最小尺寸填10,最大尺寸填40,點擊應用為節點染色、放大。

此處輸入圖片的描述

選擇左下角布局中的 Force Atlas ,斥力強度填寫 20000.0 ,吸引強度填寫 1.0 。點擊運行,稍后點擊停止。

此處輸入圖片的描述

此時布局大致如下圖所示。節點染色根據模塊化計算結果不定,但染色效果大致相同。

此處輸入圖片的描述

點擊最上方的 預覽 按鈕,選中左側 節點標簽 中 顯示標簽 選項,並選擇一種字體,這里選擇 文泉驛微米黑 。

此處輸入圖片的描述

點擊刷新按鈕,右側顯示最終的人物關系圖。

此處輸入圖片的描述


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM