[關係圖譜] 二.Gephi匯入共線矩陣構建作者關係圖譜

Eastmount發表於2018-12-17

本文主要講解Gephi繪製作者間的關係圖譜,該軟體可以廣泛應用於社交網路、知識圖譜分析,推薦讀者使用。這是非常基礎的一篇文章,重點講解Gephi使用方法,希望對大家有所幫助。
推薦前文:
[python資料探勘課程] 十七.社交網路Networkx庫分析人物關係(初識篇)
[關係圖譜] 一.Gephi通過共線矩陣構建知網作者關係圖譜

PS:2019年1~2月作者參加了CSDN2018年部落格評選,希望您能投出寶貴的一票。我是59號,Eastmount,楊秀璋。投票地址:https://bss.csdn.net/m/topic/blog_star2018/index

[關係圖譜] 二.Gephi匯入共線矩陣構建作者關係圖譜
五年來寫了314篇部落格,12個專欄,是真的熱愛分享,熱愛CSDN這個平臺,也想幫助更多的人,專欄包括Python、資料探勘、網路爬蟲、影象處理、C#、Android等。現在也當了兩年老師,更是覺得有義務教好每一個學生,讓貴州學子好好寫點程式碼,學點技術,"師者,傳到授業解惑也",提前祝大家新年快樂。2019我們攜手共進,為愛而生。

一.網路資料抓取

本文采用Python+Selenium抓取中國知網水族文獻990篇,然後構建水族文獻作者間的共現矩陣。其中爬蟲核心程式碼如下,這裡不再詳細敘述。

# -*- coding: utf-8 -*-
import requests
import json
import time
import re
from datetime import datetime
import pandas as pd
from bs4 import BeautifulSoup
import sys,urllib,urllib2 
import numpy as np
import random
import csv
import codecs

c = open("best-07-qikan.csv","wb")    #建立檔案
c.write(codecs.BOM_UTF8)              #防止亂碼
writer = csv.writer(c)                         #寫入物件
writer.writerow(['文章標題','出版社','型別','出版年份','下載次數','引用次數','作者','摘要','關鍵詞'])

myheaders = {
        "Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
        "Accept-Encoding":"gzip, deflate",
        "Accept-Language":"zh-CN,zh;q=0.9",
        "Cache-Control":"max-age=0",
        "Connection":"keep-alive",
        "Cookie":'SID=201099; UM_distinctid=162000d85ad3b9-0d8861d0e80845-454f032b-144000-162000d85ae62; CNZZDATA1356416=cnzz_eid%3D1081444310-1520419105-http%253A%252F%252Fepub.cnki.net%252F%26ntime%3D1520419105; CNZZDATA3636877=cnzz_eid%3D1821403385-1520416905-http%253A%252F%252Fepub.cnki.net%252F%26ntime%3D1520416905; ASP.NET_SessionId=wvqxbf45i04xma55s30jse55',
        "Host":"www.cnki.net",
        "Referer":"http://search.cnki.net/search.aspx?q=python",
        "Upgrade-Insecure-Requests":"1",
        "User-Agent":"Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.108 Mobile Safari/537.36"          
        }


#CNKI 3.0 列表資訊抓取  搜尋'水族 民族'關鍵詞
keyword = u'水族 民族'
keyword = keyword.encode('utf-8')
i = 0
while i<2: #100
    #學術期刊 CJFDTOTAL
    start_url = 'http://search.cnki.net/Search.aspx?q={}&rank=relevant&cluster=zyk&val=CJFDTOTAL&p={}'.format(keyword,i*15)
    print(start_url)
    html = requests.get(start_url).text
    #print html

    #解析
    soup = BeautifulSoup(html, "html.parser")
    #定位論文摘要
    wz_tab = soup.find_all("div",class_="wz_tab")
    for j  in range(0,len(wz_tab)):
        print('******')
        print("i={},j={}".format(i,j))
        tab = wz_tab[j]
        #文章標題
        title = tab.h3.a.get_text().strip()
        filename = re.search("filename=(.*?)&",tab.h3.a.attrs['href']).group(1)
        dbname = re.search("dbname=(.*?)$",tab.h3.a.attrs['href']).group(1)
        #摘要資訊
        abstract = tab.find(attrs={"class":"text"}).get_text()
        print abstract
        
        #print tab
        print title
        print filename
        print dbname

        #獲取其他資訊
        other = tab.find(attrs={"class":"year-count"})
        if other.span:
                other_list = other.span.get_text().split(u'\xa0\xa0')
                if len(other_list) == 3:
                    # 出版社
                    library = other_list[0]
                    # 等級
                    x_class = other_list[1]
                    # 出版年份
                    year = other_list[2]
                    
                elif len(other_list) == 2:
                    # 出版社
                    library = other_list[0]
                    # 等級
                    x_class = None
                    # 出版年份
                    year = other_list[1]
        else:
                library= None
                x_class = None
                year = None

        print library
        print x_class
        print year

        Num_list = other.find("span",class_="count").get_text().split('|')
        # 下載
        if re.search('[0-9]',Num_list[0]):
            #print Num_list[0]
            test  = re.findall(r'\d+\.?\d*',Num_list[0], re.M)
            #print test
            load_num = int(test[0])
            #print load_num, type(load_num)
        else:
            load_num = 0
        #被引用次數
        if re.search('[0-9]',Num_list[1]):
            from_num  = int(re.findall(r'\d+\.?\d*',Num_list[1], re.M)[0])
        else:
            from_num = 0
        print load_num
        print from_num


        ###################################
        # 抓取摘要
        time.sleep(1)
        #http://kns.cnki.net/KCMS/detail/detail.aspx?dbcode=CJFQ&dbname=CJFD2011&filename=GZMZ201106003&v=MTM5MTBkdUZDcmhWYnZJSWpmR2RMRzRIOURNcVk5Rlo0UjhlWDFMdXhZUzdEaDFUM3FUcldNMUZyQ1VSTEtmYis=
        url = "http://www.cnki.net/kcms/detail/detail.aspx?dbcode=CMFD&dbName={}&FileName={}&v=&uid=".format(dbname,filename)
        print url
        #html = requests.get(url).text
        html = requests.get(url,headers = myheaders,timeout = 500)
        print html.status_code

        #抓取作者
        bs4Obj = BeautifulSoup(html.text)
        if bs4Obj.find("a",class_="KnowledgeNetLink"):
            test = bs4Obj.find_all("a", class_="KnowledgeNetLink")
            Author = ""
            for n in test:
                Author = Author + n.get_text().rstrip() + " "
        else:
            Author = None

        #摘要
        if bs4Obj.find("span",{"id":"ChDivSummary"}):
            summury = bs4Obj.find("span",{"id":"ChDivSummary"}).get_text().rstrip()
        else:
            summury = None

        # 關鍵詞
        if bs4Obj.find("span",{"id":"ChDivKeyWord"}):
            keywords = bs4Obj.find("span",{"id":"ChDivKeyWord"})
            #print keywords
            keywords_list = '|'.join(list(map(lambda x:x.get_text(),keywords.find_all('a'))))
            #print keywords_list
        else:
            keywords_list = None
            print 'list no'

        print '' #換行
        
        templist = []
        num1 = title.encode('utf-8') #否則寫入檔案報錯
        num2 = library.encode('utf-8')
        if x_class is None:
            num3 = ""
        else:
            num3 = x_class.encode('utf-8')
        num4 = year.encode('utf-8')
        num5 = str(load_num).encode('utf-8')
        num6 = str(from_num).encode('utf-8')
        num7 = Author.encode('utf-8')
        if summury is None:
            num8 = ""
        else:
            num8 = summury.encode('utf-8')
        if keywords_list is None:
            num9 = ""
        else:
            num9 = keywords_list.encode('utf-8')
        
        templist.append(num1)
        templist.append(num2)
        templist.append(num3)
        templist.append(num4)
        templist.append(num5)
        templist.append(num6)
        templist.append(num7)
        templist.append(num8)
        templist.append(num9)
        #print templist
        writer.writerow(templist)
        
    i = i + 1


c.close()

執行結果如下圖所示:

[關係圖譜] 二.Gephi匯入共線矩陣構建作者關係圖譜

二.共現矩陣

引文分析常見的包括兩類,一種是共現關係,另一種是引用和被引用關係。本文主要講解共現關係,假設現在存在三篇文章,如下所示:

文章標題                                        作者
大資料發展現狀分析                              A,B,C
Python網路爬蟲                                 A,D,C
貴州省大資料戰略                                 D,B

1.首先寫程式碼抓取該領域文章的所有作者,即:A、B、C、D。
2.接著獲取對應的共現矩陣,比如文章“大資料發展現狀分析”,則認為A、B、C共現,在他們之間建立一條邊。共現矩陣如下所示:
(1)[ABCDA0121B1011C2101D1110] \left[ \begin{matrix} -&amp; A &amp; B &amp; C &amp; D \\ A &amp; 0 &amp; 1 &amp; 2 &amp; 1 \\ B &amp; 1 &amp; 0 &amp; 1 &amp; 1 \\ C &amp; 2 &amp; 1 &amp; 0 &amp; 1 \\ D &amp; 1 &amp; 1 &amp; 1 &amp; 0 \end{matrix} \right] \tag{1}

3.通過共現矩陣分別獲取兩兩關係及權重,再寫入CSV或Excel檔案中,如下所示。
(2)[SourceTargetWeightAB1AC2AD1BC1BD1CD1] \left[ \begin{matrix} Source &amp; Target &amp; Weight \\ A &amp; B &amp; 1 \\ A &amp; C &amp; 2 \\ A &amp; D &amp; 1 \\ B &amp; C &amp; 1 \\ B &amp; D &amp; 1\\ C &amp; D &amp; 1 \end{matrix} \right] \tag{2}

4.將該CSV檔案匯入Gephi中,並繪製相關的圖形。因為該例項節點比較少,下面是Pyhton呼叫Networkx繪製的程式碼及圖形。

# -*- coding: utf-8 -*-
import networkx as nx
import matplotlib.pyplot as plt
 
#定義有向圖
DG = nx.Graph() 
#新增五個節點(列表)
DG.add_nodes_from(['A', 'B', 'C', 'D'])
print DG.nodes()
#新增邊(列表)
DG.add_edge('A', 'B', weight=1)
DG.add_edge('A', 'C', weight=2)
DG.add_edge('A', 'D', weight=1)
DG.add_edge('B', 'C', weight=1)
DG.add_edge('B', 'D', weight=1)
DG.add_edge('C', 'D', weight=1)
#DG.add_edges_from([('A', 'B'), ('A', 'C'), ('A', 'D'), ('B','C'),('B','D'),('C','D')])
print DG.edges()
#繪製圖形 設定節點名顯示\節點大小\節點顏色
colors = ['red', 'green', 'blue', 'yellow']
nx.draw(DG,with_labels=True, node_size=900, node_color = colors)
plt.show()

繪製圖形如下所示:

[關係圖譜] 二.Gephi匯入共線矩陣構建作者關係圖譜

由於我們的資料集比較多,故推薦大家使用Gephi軟體繪製相關圖形。


三.資料匯入Gephi

1.資料集為“data.csv”檔案,共包括1095條關係。

[關係圖譜] 二.Gephi匯入共線矩陣構建作者關係圖譜

2.新建工程,並選擇“資料資料”,輸入電子表格。

[關係圖譜] 二.Gephi匯入共線矩陣構建作者關係圖譜 [關係圖譜] 二.Gephi匯入共線矩陣構建作者關係圖譜

3.然後匯入資料如下圖所示,設定為“邊表格”,注意CSV表格資料一定設定為 Source(起始點)、Target(目標點)、Weight(權重),這個必須和Gephi格式一致,否則匯入資料會提示錯誤。

[關係圖譜] 二.Gephi匯入共線矩陣構建作者關係圖譜 [關係圖譜] 二.Gephi匯入共線矩陣構建作者關係圖譜

匯入資料如下圖所示,但此時匯入的圖形為 **“有向圖” **,而且Gephi軟體中沒有設定為無向圖的選項,那怎麼辦呢?

[關係圖譜] 二.Gephi匯入共線矩陣構建作者關係圖譜

4.在 data.csv 檔案中增加一列為 Type,其值均為Undirected,用Gephi重新匯入一遍則可構建無向圖。如果您需要設計的圖為有向圖,則忽略該步驟。

[關係圖譜] 二.Gephi匯入共線矩陣構建作者關係圖譜

注意:如果您只按照“邊表格”匯入資料,則節點會因為沒有 Label 值,最終呈現的圖形會沒有文字。如下圖所示,所以接下來匯入資料分為了兩個步驟。

[關係圖譜] 二.Gephi匯入共線矩陣構建作者關係圖譜

5.匯入節點檔案:Edges.csv,注意CSV檔案中表頭切記定位為 id、label。

[關係圖譜] 二.Gephi匯入共線矩陣構建作者關係圖譜
[關係圖譜] 二.Gephi匯入共線矩陣構建作者關係圖譜

6.匯入邊檔案:Edges.csv,注意CSV檔案中表頭切記為Source(起始點)、Target(目標點)、Weight(權重)、Tpye(無向邊 Undirected)。

[關係圖譜] 二.Gephi匯入共線矩陣構建作者關係圖譜

匯入成功後如下圖所示:

[關係圖譜] 二.Gephi匯入共線矩陣構建作者關係圖譜
[關係圖譜] 二.Gephi匯入共線矩陣構建作者關係圖譜

7.匯入成功後點選“概覽”顯示如下所示,接著就是調整引數。

[關係圖譜] 二.Gephi匯入共線矩陣構建作者關係圖譜

四.調整引數繪製關係圖譜

設定外觀如下圖所示,主要包括顏色、大小、標籤顏色、標籤尺寸。

[關係圖譜] 二.Gephi匯入共線矩陣構建作者關係圖譜

1.設定節點大小和顏色。
選中顏色,點選“數值設定”,選擇渲染方式為“度”。

[關係圖譜] 二.Gephi匯入共線矩陣構建作者關係圖譜

顯示結果如下所示:

[關係圖譜] 二.Gephi匯入共線矩陣構建作者關係圖譜

接著設定節點大小,數值設定為“度”,最小尺寸為20,最大尺寸為80。

[關係圖譜] 二.Gephi匯入共線矩陣構建作者關係圖譜

2.設定邊大小和顏色。
設定邊顏色的數值設定為“邊的權重”,如下圖所示。

[關係圖譜] 二.Gephi匯入共線矩陣構建作者關係圖譜

設定邊的大小數值設定為“邊的權重”。

[關係圖譜] 二.Gephi匯入共線矩陣構建作者關係圖譜

3.在佈局中選擇“Fruchterman Reingold”。

[關係圖譜] 二.Gephi匯入共線矩陣構建作者關係圖譜

顯示結果如下所示:

[關係圖譜] 二.Gephi匯入共線矩陣構建作者關係圖譜

4.設定模組化。在右邊統計中點選“執行”,設定模組性。

[關係圖譜] 二.Gephi匯入共線矩陣構建作者關係圖譜
[關係圖譜] 二.Gephi匯入共線矩陣構建作者關係圖譜

5.設定平均路徑長度。在右邊統計中點選“執行”,設定邊概述。

[關係圖譜] 二.Gephi匯入共線矩陣構建作者關係圖譜

6.重新設定節點屬性。
節點大小數值設定為“度”,最小值還是20,最大值還是80。
節點顏色數值設定為“Modularity Class”,表示模組化。

[關係圖譜] 二.Gephi匯入共線矩陣構建作者關係圖譜

此時圖形顯示如下所示,非常好看,有關係的人物顏色也設定為了類似的顏色。

[關係圖譜] 二.Gephi匯入共線矩陣構建作者關係圖譜

7.點選預覽。
顯示標籤如下圖所示:

[關係圖譜] 二.Gephi匯入共線矩陣構建作者關係圖譜
[關係圖譜] 二.Gephi匯入共線矩陣構建作者關係圖譜

希望基礎文章對大家有所幫助,同學們可以嘗試挖掘《紅樓夢》或《人民的名義》,當兩名覺得在一章或一集中同時出現,則認為共現,並構建類似的圖片。

(By:Eastmount 2018-12-17 下午4點 http://blog.csdn.net/eastmount/ )

相關文章