知識圖譜,在經過一個大體的網上資料的搜索之后,簡單的來說它是由實體節點和實體之間的關系組成的一個圖結構。
根據網上了解到的這種關系,在使用neo4j構建知識圖譜之前,我決定利用python中的networkx工具來自己構建一個知識圖譜,以此來加深自己對於知識圖譜的關系之后,再學習neo4j構建知識圖譜並將其應用到實際的例子中。
networkx是一個處理復雜圖結構的一個python工具,一般用在網絡拓撲結構的處理當中。在將其轉化為知識圖譜的過程中,我們需要添加節點之間的關系,經過上述的簡單分析,我們開始一個最簡單的知識圖譜的構建過程。
在構建之前,簡單了解networkx提供的函數。
因為networkx相對於neo4j的安裝更加容易,且在使用的過程中更加方便。所以暫時先以networkx作為接觸知識圖譜的一個例子。networkx為我們處理復雜網絡提供了特別簡單的函數調用,且聲明簡介易懂。
導入networkx
import networkx as nx
創建有向圖
DG = nx.DiGraph()
創建無向圖
G = nx.Graph()
創建多重無向圖
MG = nx.MultiGraph()
創建多重有向圖
MDG = nx.MultiDigraph()
清空圖
G.clear()
添加節點
G.add_node(node)
添加邊
G.add_edge(node1,node2[,weight])
刪除節點
G.remove_node(node)
獲得前驅節點
G.predecessors(node)
獲得后繼節點
G.successors(node)
分配節點屬性
G.node[node]['attribute'] = 'info'
添加圖屬性
G.graph['attribute'] = 'info'
添加邊屬性
G[node1][node2]['attribute'] = 'info'
迪傑斯特拉求最短路徑
dijkstra_path(G, source, target, weight='weight')
求最短距離
dijkstra_path_length(G, source, target, weight='weight')
圖的所有邊,以元組的列表為結果
F.edges([,date=True])
圖的所有節點
G.nodes([,data=True])
獲得鄰居節點
G.neighbors(node)
了解了networkx的一些基本的函數之后,現在開始一個簡單的知識圖譜構建的過程。
在構建知識圖譜之前,我們得准備一些預料或者知識網絡來開始構建我們的知識圖譜,那么就以一個簡單的知識網絡為例子。
已知張三是李四的朋友,張三現任職於貪心科技(其中張三和李四的關系),根據這種圖中所展示的關系,我們對這個社交網絡進行還原並構建為networkx中的網絡拓撲結構。
那么我們開始構建一個圖,由圖可以分析得到這是一個有向圖。(構建的網絡是一個有向圖而不是無向圖,因為節點和節點之間的關系是有向的,即使通常我們在認為A和B是朋友的這種情況通常來說是雙向的,但也有可能A認為B是自己的朋友,而B卻不認為A是自己的朋友的這種情況)
並將展示可能用到的函數都構造成一個函數,以便以后能夠通用。
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @Time : 2020/7/11 13:32
# @Author: hdq
# @File : simple_knowledge.py
import networkx as nx
#添加雙向關系
def add_double_edge(digraph: nx.DiGraph, node1, node2, info=None, relation='relation'):
digraph.add_edge(node1, node2)
digraph.add_edge(node2, node1)
digraph[node2][node1][relation] = info
digraph[node1][node2][relation] = info
#添加單向關系
def add_edge(digraph: nx.DiGraph, node1, node2, info=None, relation='relation'):
digraph.add_edge(node1, node2)
digraph[node1][node2][relation] = info
#獲取邊的全部relation
def get_edges_relation(digraph: nx.DiGraph,relation="relation"):
result = []
for one in digraph.edges(data=True):
result.append(one[2][relation])
return set(result)
#獲取為relation為info的所有邊
def get_relation_edges(digraph: nx.DiGraph,info=None,relation="relation"):
result = []
for one in digraph.edges(data=True):
if (one[2][relation] == info):
result.append((one[0],one[1]))
return set(result)
#添加節點屬性
def add_node_attribute(digraph: nx.DiGraph,nodelist,info=None):
digraph.add_nodes_from(nodelist,attribute=info)
#獲取全部節點的attribute
def get_nodes_attribute(digraph: nx.DiGraph):
result=[]
for one in digraph.nodes(data=True):
result.append(one[1]["attribute"])
return set(result)
#獲取attribute為info的所有節點
def get_attribute_nodes(digraph: nx.DiGraph,info=None):
result=[]
for one in digraph.nodes(data=True):
if(one[1]["attribute"]==info):
result.append(one[0])
return set(result)
#創建有向圖
G = nx.DiGraph()
#添加節點及其屬性
add_node_attribute(G,['張三','李四','小五','小四'],'人')
add_node_attribute(G,['貪心科技','騰訊'],'公司')
print("所有的節點屬性:",get_nodes_attribute(G))
print("所有屬性為公司的節點:",get_attribute_nodes(G,"公司"))
print("所有屬性為人的節點:",get_attribute_nodes(G,"人"))
print("當前所有節點信息:",G.nodes(data=True))
#添加屬性間的關系
add_double_edge(G,'張三','李四','朋友')
add_edge(G,'張三','貪心科技','現任職於')
add_edge(G,'小五','貪心科技')
add_double_edge(G,'小五','小四','同事')
add_edge(G,'小五','騰訊','現任職於')
add_edge(G,'小四','騰訊','曾任職於')
print("所有邊的屬性:",get_edges_relation(G))
print("所有屬性為朋友的邊:",get_relation_edges(G,"朋友"))
print("當前所有邊信息:",G.edges(data=True))
print("張三和李四的關系:",G['張三']['李四']['relation'])
上述代碼運行的結果: