Python: 两个网络之间的Jaccard相似度?

3

我有使用 networkx 包生成的2个 大型 网络,它们分别为 GG1。我想计算所有节点之间的 Jaccard相似度指数

一种可能的方法如下:

def returnJaccardNetworks(G, G1):
    tmp =   list(G.nodes())
    tmp1 =  list(G1.nodes())
    tmp2 =  np.unique([tmp, tmp1]) ### Find nodes in the networks
    jc = []
    for i in tmp2:
    ## if the node i is in G and in G1 compute 
    ## the similarity between the lists of the ajacent nodes
    ## otherwise append 0
        if (i in G) and (i in G1):  
            k1 = list(G[i]) ## adjacent nodes of i in the network G     
            k2 = list(G1[i]) ## adjacent nodes of i in the network G1 
            ### Start Jaccard Similarity
            intersect = list(set(k1) & set(k2))
            n = len(intersect)
            jc.append(n / float(len(k1) + len(k2) - n))
            ### End Jaccard Similariy
        else:
            jc.append(0)
    return jc

我想知道是否有更有效的方法。我注意到包中有一个名为jaccard_coefficient的函数,但我不确定它是如何工作的。

https://networkx.github.io/documentation/networkx-1.9/reference/generated/networkx.algorithms.link_prediction.jaccard_coefficient.html


根据您提供的链接,看起来jacard_coefficient(X,所有2个配对的元组列表)应该可以工作。其中X是G和G'的组合。 - Bayko
@Bayko 谢谢,但我应该怎么编写代码? - emax
@Bayko 这也是我的第一反应,但这种方法在这里行不通,因为 OP 需要在网络间保留节点的身份,但每个网络的连接方式都不同。 - Paul Brodersen
1个回答

4

您的实现非常高效(虽然在我看来并不漂亮)。使用此版本,我可以在我的机器上减少15%的执行时间:

def get_jaccard_coefficients(G, H):
    for v in G:
        if v in H:
            n = set(G[v]) # neighbors of v in G
            m = set(H[v]) # neighbors of v in H
            length_intersection = len(n & m)
            length_union = len(n) + len(m) - length_intersection
            yield v, float(length_intersection) / length_union
        else:
            yield v, 0. # should really yield v, None as measure is not defined for these nodes

这个版本更加紧凑,更容易维护,但以30%的执行时间增加为代价:

def get_jaccard_coefficients(G, H):
    for v in set(G.nodes) & set(H.nodes): # i.e. the intersection
        n = set(G[v]) # neighbors of v in G
        m = set(H[v]) # neighbors of v in H
        yield v, len(n & m) / float(len(n | m))

由于你只考虑了 G 中的节点,并检查它们是否在 H 中,似乎不正确,因为你没有考虑 H 中不在 G 中的节点。所以函数的前两行需要是: def get_jaccard_coefficients(G, H): allnodes=list(set(list(G)+list(H))) for v in allnodes: if (v in H) and (v in G): - Haj Nasser

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接