【问题标题】:Fast algorithm to compute Adamic-Adar计算 Adamic-Adar 的快速算法
【发布时间】:2015-04-27 02:33:41
【问题描述】:

我正在从事图形分析。我想计算一个 N × N 相似度矩阵,其中包含每两个顶点之间的 Adamic Adar 相似度。为了概述 Adamic Adar,让我从以下介绍开始:

给定无向图G 的邻接矩阵ACN 是两个顶点xy 的所有公共邻居的集合。两个顶点的公共邻居是两个顶点都有一条边/链接,即两个顶点对于A 中的相应公共邻居节点都有一个 1。 k_n 是节点n 的度数。

Adam-Adar 定义如下:

我的计算尝试是从A 获取xy 节点的两行,然后对它们求和。然后查找具有2 作为值的元素,然后获取它们的度数并应用等式。然而,计算确实需要很长时间。我尝试了一个包含 1032 个顶点的图,计算需要很长时间。它从 7 分钟开始,然后我取消了计算。所以我的问题是:有没有更好的算法来计算它?

这是我在 python 中的代码:

def aa(graph):

"""
    Calculates the Adamic-Adar index.

"""
N = graph.num_vertices()
A = gts.adjacency(graph)
S = np.zeros((N,N))
degrees = get_degrees_dic(graph)
for i in xrange(N):
    A_i = A[i]
    for j in xrange(N):
        if j != i:
            A_j = A[j]
            intersection = A_i + A_j
            common_ns_degs = list()
            for index in xrange(N):
                if intersection[index] == 2:
                    cn_deg = degrees[index]
                    common_ns_degs.append(1.0/np.log10(cn_deg))
            S[i,j] = np.sum(common_ns_degs)
return S 

【问题讨论】:

  • 您可以通过不构建 common_ns_degs 来节省一些计算,而是将 -log10(cn_deg) 添加到您现在调用 list() 的位置初始化为零的 S[i,j]。顺便说一句,它应该是 log10(1.0/cn_deg),而不是 1.0/log10(cn_deg)。
  • Adamic-Adar 指数的公式与提供的公式略有不同。它是公共邻居 k_n 的 sum(1/log(k_n))。代码似乎是正确的

标签: python algorithm math numpy graph


【解决方案1】:

我相信您使用的是相当缓慢的方法。最好恢复它-
- 用零初始化 AA (Adam-Adar) 矩阵
- 每个节点 k 得到它的度数 k_deg
- calc d = log(1.0/k_deg)(为什么 log10 - 重要还是不重要?)
- 将 d 添加到所有 AAij,其中 i,j - kth 行中的所有 1 对 邻接矩阵
编辑:
- 对于稀疏图,将第 kth 行中所有 1 的位置提取到列表中以达到 O(V*(V+E)) 复杂度而不是 O(V^3) 是有用的

AA = np.zeros((N,N))
for k = 0 to N - 1 do
    AdjList = []
    for j = 0 to N - 1 do
        if A[k, j] = 1 then
            AdjList.Add(j)
    k_deg = AdjList.Length
    d = log(1/k_deg)
    for j = 0 to AdjList.Length - 2 do
      for i = j+1 to AdjList.Length - 1 do
         AA[AdjList[i],AdjList[j]] = AA[AdjList[i],AdjList[j]] + d  
         //half of matrix filled, it is symmetric for undirected graph

【讨论】:

  • "将 d 添加到所有 AAij"?您需要找出节点对节点P 是一个共同的邻居。不也是 O(n^3) 吗?
  • 啊,我明白了。不错的方法,应该有一个非常低的常数因子
  • "对于稀疏图,提取所有 1 的位置很有用",是的,该怎么做?这就是为什么我要做交叉点的事情,以避免 O(V*3)
  • 能否请您为您的方法写一些伪代码?
  • @AlexTwain 你有没有稀疏图?因为如果这样做,为什么要使用邻接矩阵?
【解决方案2】:

由于您使用的是 numpy,因此您可以真正减少对算法中的每个操作进行迭代的需要。我的 numpy- 和 vectorized-fu 不是最好的,但在具有约 13,000 个节点的图表上,以下运行时间约为 2.5 秒:

def adar_adamic(adj_mat):    
    """Computes Adar-Adamic similarity matrix for an adjacency matrix"""

    Adar_Adamic = np.zeros(adj_mat.shape)
    for i in adj_mat:
        AdjList = i.nonzero()[0] #column indices with nonzero values
        k_deg = len(AdjList)
        d = np.log(1.0/k_deg) # row i's AA score

        #add i's score to the neighbor's entry
        for i in xrange(len(AdjList)):
            for j in xrange(len(AdjList)):
                if AdjList[i] != AdjList[j]:
                    cell = (AdjList[i],AdjList[j])
                    Adar_Adamic[cell] = Adar_Adamic[cell] + d

    return Adar_Adamic

与 MBo 的回答不同,这确实构建了完整的对称矩阵,但考虑到执行时间,效率低下(对我而言)是可以容忍的。

【讨论】:

    【解决方案3】:

    我没有看到降低时间复杂度的方法,但可以向量化:

    degrees = A.sum(axis=0)
    weights = np.log10(1.0/degrees)
    adamic_adar = (A*weights).dot(A.T)
    

    A 是一个常规的 Numpy 数组。看来您正在使用graph_tool.spectral.adjacency,因此A 将是一个稀疏矩阵。在这种情况下,代码将是:

    from scipy.sparse import csr_matrix
    
    degrees = A.sum(axis=0)
    weights = csr_matrix(np.log10(1.0/degrees))
    adamic_adar = A.multiply(weights) * A.T
    

    这比使用 Python 循环要快得多。不过有个小警告:使用这种方法,您确实需要确保主对角线上的值(Aadamic_adar)是您期望的值。此外,A 不得包含权重,而只能包含零和一。

    【讨论】:

    • 我真的很喜欢这种方法。如果您想将其应用于正确的公式,如above 所述。您可以将其更改为:from scipy.sparse import csr_matrixA = adjacency(graph)degrees = A.sum(axis=0)degrees[degrees == 1] = 0 #nodes with degree one cause errors and are not intermediate nodesweights = csr_matrix(1./np.log(degrees))adamic_adar = A.multiply(weights) * A.T
    【解决方案4】:

    我相信在R igraph 中定义的one 之类的函数在其python_igraph 以及节点相似度(也包括Adam_Adar)中都存在

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-17
      • 1970-01-01
      • 1970-01-01
      • 2017-06-15
      • 1970-01-01
      • 1970-01-01
      • 2019-11-18
      • 2011-04-13
      相关资源
      最近更新 更多