Python 使用NetworkX的图之间的相似性度量

Python 使用NetworkX的图之间的相似性度量,python,networking,graph,networkx,graph-theory,Python,Networking,Graph,Networkx,Graph Theory,我有两个图A和B。它们可能是同构的、完全不同的或有一些相似之处(少数节点相同,或少数节点共享相同的边) 我想看看/检查这些图表有多不同/相似。 is_isomorphic()是一种方法。然而,这并不仅仅说明是真是假 例如,差分(A,B)函数返回一个新图形,其中包含存在于A中但不存在于B中的边;但它需要有相同数量的节点 我的图形A和B的节点数不一样。并且可能有几百个节点。因此,如果不是NP难的话,算法将是最好的(比如NP难的graph_edit_distance()函数)。不确定这是否正是您想要的

我有两个图AB。它们可能是同构的、完全不同的或有一些相似之处(少数节点相同,或少数节点共享相同的边)

我想看看/检查这些图表有多不同/相似。 is_isomorphic()是一种方法。然而,这并不仅仅说明是真是假

例如,差分(A,B)函数返回一个新图形,其中包含存在于A中但不存在于B中的边;但它需要有相同数量的节点


我的图形A和B的节点数不一样。并且可能有几百个节点。因此,如果不是NP难的话,算法将是最好的(比如NP难的graph_edit_distance()函数)。

不确定这是否正是您想要的,但希望您会发现其中一些有用的。让我们以下面的图形
G
H
为例:

l1 = [['A','C'], ['A', 'D'], ['I','F'], ['K', 'E'], ['D', 'A'], ['A', 'B'], ['C', 'D']]
l2 = [['A','B'], ['Q', 'D'], ['J','F'], ['A', 'E'], ['D', 'F'], ['X','A']]

G = nx.from_edgelist(l1)
H = nx.from_edgelist(l2)

G.nodes()
# NodeView(('A', 'C', 'D', 'I', 'F', 'K', 'E', 'B'))
H.nodes()
# NodeView(('A', 'B', 'Q', 'D', 'J', 'F', 'E', 'X'))
为了获得相似性度量,考虑到边并集的交集,您可能会提出一些相似性或差异的自定义定义。或许,该公司可能是一个很好的候选人:

def jaccard_similarity(g, h):
    i = set(g).intersection(h)
    return round(len(i) / (len(g) + len(h) - len(i)),3)

jaccard_similarity(G.edges(), H.edges())
# 0.091

这里可能也有用的是提出一个可视化的概念,给出两个图形的相似性和不同性。我们可以从使用开始,这将为我们提供节点集和边集的简单并集:

GH = nx.compose(G,H)
GH.nodes()
# NodeView(('A', 'C', 'D', 'I', 'F', 'K', 'E', 'B', 'Q', 'J', 'X'))
迭代合成图的边和节点,并根据它们所属的图(同时包括两者)为它们指定颜色。这也可以扩展到添加一些属性,指示它也属于哪个图形:

# set edge colors
edge_colors = dict()
for edge in GH.edges():
    if G.has_edge(*edge):
        if H.has_edge(*edge):
            edge_colors[edge] = 'magenta'
            continue
        edge_colors[edge] = 'lightgreen'
    elif H.has_edge(*edge):
        edge_colors[edge] = 'lightblue'

# set node colors
G_nodes = set(G.nodes())
H_nodes = set(H.nodes())
node_colors = []
for node in GH.nodes():
    if node in G_nodes:
        if node in H_nodes:
            node_colors.append('magenta')
            continue
        node_colors.append('lightgreen')
    if node in H_nodes:
        node_colors.append('lightblue')
因此,这里相交的节点和边将具有洋红色。否则,如果它们分别属于G或H
图形,则它们将是绿色或蓝色

现在,我们可以分别使用上面的边和节点颜色字典/列表绘制图形。这样可以很好地查看两个图上相交和不相交的节点/边:

pos = nx.spring_layout(GH, scale=20)
nx.draw(GH, pos, 
        nodelist=GH.nodes(),
        node_color=node_colors,
        edgelist=edge_colors.keys(), 
        edge_color=edge_colors.values(),
        node_size=800,
        width=8,alpha=0.5,
        with_labels=True)

在您的上下文中,“相似”是什么意思?+1表示某种形式的Jaccard re边,或边和节点。我经常使用Jaccard,一旦你得到它,它在概念上就很简单,而且对于各种集合/成员问题都非常好。我想到的第一件事就是读这个问题。最令人印象深刻的交叉口维兹太!你认为这足够好吗,特别是对于简单的图形,比如树?