複雜網路作業五:第四題——Structural Role 結構角色:ROIX
文章目錄
前言
扯淡建議跳過:昨天晚上本來是已經寫完了,結果第二天發現內容不對什麼原因我也不知道。在這個沒有做作業的一週之中,發生了很多的新聞。其中,最令人印象深刻的四川某校的書記的以死明志。想到當初的教科書中的“安能以身之察察,受物之汶汶者乎?寧赴湘流,葬於江魚之腹中。安能以皓皓之白,而蒙世俗之塵埃乎?”真的在現實生活中上了頭條。想想也是如果這個書記不這麼做就無法給這個社會帶來一點震撼,這才是這個時代最需要的脊樑吧!另外,正是因為那些高尚的精神在這個社會中並非隨處可見(應該說是極其罕見),所以才更值得新一帶人所崇拜。最後,說實話如果的作是我,我恐怕會變成一條泥鰍在淤泥中打滾吧。畢竟活著遠遠要比改變環境更容易。(我認為書記並非想逃避,他是想通過這種方式來改變大環境。)呵呵,這也就是為什麼大多數的人都是普通人吧。
一、題目
科學家合作網,下載地址http://www-personal.umich.edu/~mejn/netdata/netscience.zip.這個網路是加權的,把這個網路按照無向和無權網路來處理。
特徵抽取分成兩步:首先抽取節點的基本區域性特徵,然後聚集起來以獲得全域性特徵。特徵抽取構建出矩陣V,包含n個節點,每個節點都有f個特徵,包括區域性和全域性資訊。ROIX從矩陣中抽取節點的特徵。
(1)基本特徵:對於每個節點v,選擇3個基本特徵:
- 節點v的度,deg(v);
- 節點v的區域性網路egonet(v)中的邊數,其中v的區域性網路egonet(v)是包含節點v及其鄰居的匯出子圖
- 節點v的區域性網路和圖G的其他部分連線的邊數,也就是進入或者離開v的區域性網路的邊數。
我們使用V~u來表示節點u的基本特徵向量。對於任意節點對u和v,使用cos相似性來度量其特徵向量x和y之間的相似性。Cos相似性的定義如下面的公式:
問題:計算出節點9的基本特徵向量,並給出與節點9最相似的前5個節點(節點9本身除外)。(注:本題中V~9中的元素不大於10)
(2)遞迴特徵
本步中將遞迴產生更多的特徵。這裡使用mean和sum作為聚合函式。初始時,每個節點u都有一個特徵向量
。在第一輪迭代中,我們聚合u的所有鄰居的特徵向量均值(mean)到Vu中,也特徵向量求和(sum)做相同操作,也就是得到如下面公式所示的Vu(1):
N(u)是節點u的鄰居。如果N(u)為空的話,mean和sum也都為0.
在k輪迭代後,會獲得所有的特徵矩陣
問題:這裡執行2輪迭代,即K=2。給出與節點9最相似的5個節點(節點9本身除外)。(提示:節點9以及與它最相似性的5個節點的相似性值都大於0.9)。與本題中的第一個問題中得出的前5個節點相比,本問題的解和第一個問題的解有哪些相同節點和哪些不同節點?
(3)角色發現
這個部分將根據節點的遞迴特徵向量和節點相似性得出更多的結論。
問題1:建立有20個bin的直方圖,給出節點9和其他節點的cos相似度分佈(根據其遞迴特徵向量)。X軸是其他節點和節點9的cos相似度,y軸是節點的數量。是否可以直方圖得出一些組/角色?能得出幾組?(提示,查詢spikes)
問題2:對於這些組/角色,從每組中選取節點u,檢視其特徵向量,並根據其特徵向量畫出節點的子圖。可以用手畫,也可以使用networkx或者graphviz畫。圖中,需要使用到節點u的區域性特徵,並且注意其1跳鄰居的聚集特徵。如果某些特徵難以使用的話,可以忽略掉,而且不必畫出節點u的三跳以外的節點。
最後,簡單總結一下結構上的角色差異。
二、需要使用的函式的介紹(networkx)
1.構建一個圖
nx.Graph()
2.從gml檔案讀入一個圖
nx.read_gml(path,label=“id”) #和網上的可能會有不同
3.取出圖中的節點
G.nodes #G是networkx.Graph型別的變數
4.取出圖中的邊
G.edges #G是networkx.Graph型別的變數
5.把多個節點批量加入到圖中
G.add_nodes_from(nodes)
6.把多個邊批量加入到圖中
G.add_edges_from(edges)
7.求某一個節點的度
G.degree(node) #G是networkx型別的變數,node是一個int型別的變數
8.獲取一個區域性鄰居子圖
nx.ego_graph(G,node,radius=2)
G:圖
node:是中心點的編號
radius:步長
9.針對一個圖找出一個合理的部局
pos = nx.spring_layout(G)
10.根據部局來畫圖
nx.draw_networkx(G,pos) #沒有標籤
11.根據部局來畫標籤(編號)
nx.draw_networkx_labels(G,pos = pos)
三、需要使用的函式的介紹(matplotlib.pyplot)
1.為什麼要新增這一個
考慮到有人可能對這個模組下的東西不熟,所以就把matplotlib的相關東西也寫一下。(有關list,numpy的東西就不寫了)至於matplotlib的安裝就不過程就不寫了,大家就自己百度吧。
2.設定橫座標
plt.xlabel(name,fontproperties=“simsun”) #fontproperties是用於設定字型,這樣就可以顯示中文了。
3.設定縱座標
plt.ylabel(name,fontproperties=“simsun”)#fontproperties是用於設定字型,這樣就可以顯示中文了。
4.設定標題
plt.title(name,fontproperties=“simsun”)#fontproperties是用於設定字型,這樣就可以顯示中文了。
5.畫柱狀統計圖
plt.bar(x=x_bar,height=y_bar,width=0.1)
6.統計圖展示
plt.show()
7.設定畫布大小
plt.figure(figsize=(15,15))
8.畫布清空
plt.clf()
9.圖畫儲存
plt.savefig(save_path)
程式碼
# -*- coding: utf-8 -*-
import random
import networkx as nx
import numpy as np
import matplotlib.pyplot as plt
#讀取網路圖
path = r"netscience.gml"
science_G = nx.read_gml(path,label="id")
#把原來的無向帶權圖轉化為無向無向無權圖
nodes = science_G.nodes
edges = science_G.edges
G = nx.Graph()
G.add_nodes_from(nodes)
G.add_edges_from(edges)
#統計節點的特徵資訊
node_degree_list = [] #節點度特徵
node_egonet_list = [] #子圖特徵
node_global_list = [] #全域性特徵
local_graph_list = [] #區域性子圖(用於在後面使用)
def calGlobalFeature(G1,G2):
edges = G2.edges
cnt_out_edge = 0
for edge in edges:
u,v = edge
if((u in G1 and v not in G1) or (v in G1 and u not in G1)):
cnt_out_edge+=1
return cnt_out_edge
for node in G:
node_degree = science_G.degree(node)
node_degree_list.append(node_degree)
# print(node_degree)
ego_G = nx.ego_graph(G,node)
node_egonet = ego_G.number_of_edges()
node_egonet_list.append(node_egonet)
# print(node_egonet)
ego2_G = nx.ego_graph(G,node,radius=2)
node_global = calGlobalFeature(ego_G,ego2_G)
node_global_list.append(node_global)
# print(node_global)
local_graph_list.append(ego_G)
node_id_list = list(G.nodes()) #獲得所有節點的編號,但是需要注意是亂序的
node_feature = list(zip(node_id_list,node_degree_list,node_egonet_list,node_global_list)) # [編號,度,鄰域,全域性]
node_feature.sort(key = lambda x:x[0]) #通過排序使得它是按照節點的遞增序排列
node_feature = np.array(node_feature) #轉成ndarray型別方便後續計算
# 資訊特徵統計完成,編號是亂序
# 接下來是計算與9號結點之間的相似性
def calSim(node1,node2):
node1_np = node1[1:]
node2_np = node2[1:]
if(np.sqrt(np.sum(node2_np*node2_np))) == 0:
return (node2[0],0)
return (node2[0],np.sum(node1_np*node2_np)/(np.sqrt(np.sum(node1_np*node1_np))*np.sqrt(np.sum(node2_np*node2_np))))
# 在本題的第一小題中只需要求出9號節點與前10個結點的相似度
# 即可,但是後面以我的理解是和所有節點的相似度。這麼做可以
# 使得其得函式的使用可調整
def calNodeFeatureSim(node_feature_list,node_id,cal_len=99999):
'''
:param node_feature_list: 節點的特徵序列
:param node_id: 目標節點
:param cal_len: 有多少個結點需要用來計算相似度
:return: 與目標節點的相似度序列
'''
node_feature = node_feature_list[node_id]
sim = []
for node in node_feature_list:
if(node[0] == node_id):
continue
if(node[0] > cal_len):
break
sim.append(calSim(node_feature,node))
sim.sort(key = lambda x:x[1],reverse=True)
return sim
sim9 = calNodeFeatureSim(node_feature,9,10)
print("在前10個節點中與9號節點最相似的5個節點如下:")
print("節點編號 相似度")
for i in range(5):
print(" {} {}".format(sim9[i][0],sim9[i][1]))
#計算遞迴特徵
def recursionFeature(node_feature,local_feature_list):
'''
:param node_feature: 結點的特徵序列
:param local_feature_list: 每一個結點的一跳區域性子圖
:return: 新的特徵
'''
new_node_feature = []
for node in node_feature:
node_id = int(node[0])
local_G = local_graph_list[node_id]
feature_len = len(node)
new_feature1 = np.zeros(shape=(feature_len - 1),dtype = np.float32)
# print(node_id)
for neig_node in local_G.nodes():
if(neig_node == node_id):
continue
# print(neig_node,node_feature[neig_node])
new_feature1 += node_feature[neig_node][1:]
if(len(local_G.nodes()) > 1):
new_feature2 = new_feature1/(len(local_G.nodes()) - 1)
else:
new_feature2 = new_feature1 = np.zeros(shape=(feature_len - 1),dtype = np.float32)
new_node_feature.append(np.append(new_feature1,new_feature2))
new_node_feature = np.array(new_node_feature)
node_feature = np.hstack((node_feature,new_node_feature))
return node_feature
for i in range(2):
node_feature = recursionFeature(node_feature,local_graph_list)
sim9 = calNodeFeatureSim(node_feature,9,10)
print(node_feature.shape) #此時每一個節點的特徵數量應該是27個,所以此處應該是28列(第一列是編號)
print("遞迴特徵之後")
print("在前10個節點中與9號節點最相似的5個節點如下:")
print("節點編號 相似度")
for i in range(5):
print(" {} {}".format(sim9[i][0],sim9[i][1]))
#進行角色發現,這裡可能有錯誤。我不知道我理解的角色發現是否正確
sim9 = calNodeFeatureSim(node_feature,9) #按照我的理解應該要在全域性中進行角色發現
sim9 = np.array(sim9) #轉成ndarray型別方便後續計算
#對數量資訊進行統計
bardata = []
base_l = 0
base_u = 0
change = 1/20
for i in range(20):
base_u += change
bar1 = sim9[sim9[:,1] < base_u]
bar2 = bar1[bar1[:,1] >= base_l]
bardata.append(bar2)
base_l = base_u
x_bar = [1/20*x + 0.025 for x in range(20)] #柱形圖的橫軸
y_bar = [len(x) for x in bardata ] #柱形圖的縱軸
plt.xlabel("相似度",fontproperties="simsun")
plt.ylabel("數量",fontproperties="simsun")
plt.title("相似度統計圖",fontproperties="simsun")
plt.bar(x=x_bar,height=y_bar,width=0.1)
plt.show()
import heapq #用於尋找最大的n個值
max3_index = list(map(y_bar.index,heapq.nlargest(3,y_bar))) #用於尋找最大的3個值,並獲取對應的下標
random_node = []
for index in max3_index:
random_node.append(int(bardata[index][random.randint(0,y_bar[index])][0]))
print("從三組中選出的任意結點是:",random_node)
plt.figure(figsize=(15,15)) #設定畫布大小
for node_id in random_node:
plt.clf() #一共要畫三個圖,所以每一次在畫圖之前都需要清空
act_local_G = nx.ego_graph(G,node_id,radius=3)
for node in act_local_G:
act_local_G.add_node(node,local_feature = node_feature[node][1])
pos=nx.spring_layout(act_local_G) #根據spring演算法進行部局,spring演算法我不知道是啥。
nx.draw_networkx(act_local_G,pos)
nx.draw_networkx_labels(act_local_G,pos = pos)
plt.savefig(r"filename" + str(node_id) + ".png") #對圖片進行儲存
執行結果截圖
角色發現圖(這一個不知道對不對)
總結
其中我對角色發現的理解可能是錯的,我之前這作業我不做不知道。做才發現網上有關networkx的使用教程少的可憐。而且都是相互抄來抄去的。估計等我這五個題做完,我的這幾篇部落格networkx的最全使用教程了吧。(_)II
相關文章
- 複雜網路作業一:環境準備
- ansible-role角色
- 9 Role Transitions 角色轉換
- MySQL角色(role)功能介紹MySql
- 第五組【團隊作業】第四周作業2
- 網路流複雜度證明複雜度
- 資料結構:時間複雜度資料結構時間複雜度
- 前端資料結構---複雜度分析前端資料結構複雜度
- 計算機網路的七層結構、五層結構和四層結構計算機網路
- 面試題35:複雜連結串列的複製面試題
- 網路模型複雜度計算方法模型複雜度
- 複雜的資料結構設計求解?資料結構
- Python3 解析複雜結構的 jsonPythonJSON
- 網路複習題
- 第四-六次作業總結
- Angular 自定義結構型指令 structural directive 的使用AngularStruct
- Oracle 19C DELETE_CATALOG_ROLE角色Oracledelete
- 架構雜談《五》架構
- 作業系統結構作業系統
- 複雜連結串列的複製
- B-神經網路模型複雜度分析神經網路模型複雜度
- 資料結構複雜圖形儲存 PHP 版資料結構PHP
- 資料結構與演算法——複雜度分析資料結構演算法複雜度
- 計算機網路期末複習 第四講 網路應用工作原理計算機網路
- 第四到六次pta作業總結
- 複雜頁面架構架構
- 作業系統(二):作業系統結構作業系統
- Altair SimSolid複雜裝配體無網格快速結構模擬研討會AISolid
- 1.2網際網路的網路結構
- 網路部 11.14作業
- 作業系統核心結構作業系統
- 資料結構 之 演算法時間複雜度資料結構演算法時間複雜度
- 資料結構-基本概念和時空複雜度資料結構複雜度
- 資料結構與演算法——時間複雜度資料結構演算法時間複雜度
- Unity 遊戲框架搭建 2019 (三十九、四十一) 第四章 簡介&方法的結構重複問題&泛型:結構複用利器Unity遊戲框架泛型
- 複雜SQL構造資料:SQL
- 網路拓撲結構
- 資料 結構客觀題複習題集