【问题标题】:how to efficiently construct an affinity matrix from rows of transactions?如何有效地从交易行构造一个亲和矩阵?
【发布时间】:2017-06-09 06:42:57
【问题描述】:

给定一个(可能很大 ~ 2+GBs)json 文件中节点之间的事务,大约有百万个节点和大约 1000 万个事务,每个事务有 10-1000 个节点,例如

{"transactions":
 [
  {"transaction 1": ["node1","node2","node7"], "weight":0.41},
  {"transaction 2": ["node4","node2","node1","node3","node10","node7","node9"], "weight":0.67},
  {"transaction 3": ["node3","node10","node11","node2","node1"], "weight":0.33},...
  ]
}

将其转换为节点亲和度矩阵的最优雅和最有效的 Python 方法是什么,其中亲和度是节点之间加权事务的总和。

affinity [i,j] = weighted transaction count between nodes[i] and nodes[j] = affinity [j,i]

例如

affinity[node1, node7] = [0.41 (transaction1) + 0.67 (transaction2)] / 2 = affinity[node7, node1]

注意:亲和矩阵是对称的,因此仅计算下三角形就足够了。

值不代表***结构示例!

            节点1 |节点2 |节点3 |节点4 | ....
node1 1.4 .1 .9 ... Node2 .4 1.6。 .9          .3          .7 1    ...
...


【问题讨论】:

  • 嗨 D.S. 欢迎来到 Stackoverflow。您可以在发布问题时使用{} 按钮将一段文本格式化为代码块。代码块保留空格并使其更容易像 JSON 一样发布
  • 谢谢 Matti,我明白了,我相信当前的格式(虽然很难做到)看起来可读,你不同意吗?
  • 它是可读的,但正如您指出的那样需要完成相当多的工作。使用{} 按钮要容易得多
  • 您好,您能否提供一个节点亲和矩阵的定义,这会增加您获得答案的机会
  • 但是你的矩阵不是对称的。您能写出如何根据示例交易数据计算几个 i,j 的 A[i,j] 吗?

标签: python json graph affinity data-munging


【解决方案1】:

首先,我会清理数据并用整数表示每个节点,并从这样的字典开始

data=[{'transaction': [1, 2, 7], 'weight': 0.41},
      {'transaction': [4, 2, 1, 3, 10, 7, 9], 'weight': 0.67},
      {'transaction': [3, 10, 11, 2, 1], 'weight': 0.33}]

不确定这是否足够pythonic,但它应该是不言自明的

def weight(i,j,data_item):
    return data_item["weight"] if i in data_item["transaction"] and j in data_item["transaction"] else 0

def affinity(i,j):
    if j<i: # matrix is symmetric
        return affinity(j,i)
    else:
        weights = [weight(i,j,data_item) for data_item in data if weight(i,j,data_item)!=0]
        if len(weights)==0:
            return 0
        else:
            return sum(weights) / float(len(weights))

ln = 10 # number of nodes
A = [[affinity(i,j) for j in range(1,ln+1)] for i in range(1,ln+1)]

查看亲和度矩阵

import numpy as np
print(np.array(A))
    [[ 0.47  0.47  0.5   0.67  0.    0.    0.54  0.    0.67  0.5 ]
     [ 0.47  0.47  0.5   0.67  0.    0.    0.54  0.    0.67  0.5 ]
     [ 0.5   0.5   0.5   0.67  0.    0.    0.67  0.    0.67  0.5 ]
     [ 0.67  0.67  0.67  0.67  0.    0.    0.67  0.    0.67  0.67]
     [ 0.    0.    0.    0.    0.    0.    0.    0.    0.    0.  ]
     [ 0.    0.    0.    0.    0.    0.    0.    0.    0.    0.  ]
     [ 0.54  0.54  0.67  0.67  0.    0.    0.54  0.    0.67  0.67]
     [ 0.    0.    0.    0.    0.    0.    0.    0.    0.    0.  ]
     [ 0.67  0.67  0.67  0.67  0.    0.    0.67  0.    0.67  0.67]
     [ 0.5   0.5   0.5   0.67  0.    0.    0.67  0.    0.67  0.5 ]]

【讨论】:

  • 在这种情况下,您会将列标题存储为单独的列表以实现最佳存储吗?
  • 您还可以建议为此目的使用稀疏矩阵吗? docs.scipy.org/doc/scipy-0.19.0/reference/generated/…
  • 当你有可能有一百万个节点时会发生什么......你如何优化?
  • 如果矩阵是稀疏的,那么我会研究稀疏矩阵的有效数据结构,是的。您还可以研究更快的 Python 实现,例如 Pypy 或 Numba。也许您应该发布一个新问题,并附上一个具体示例,说明您将矩阵用于什么......
  • 是的,数据是稀疏的,正如问题百万节点和 1000 万个事务中提到的,每个事务大约有 10-100 个节点。如果您可以将节点用作字符串并将输入数据视为 json(已格式化),我也将不胜感激,因为单独遍历 json 会进一步增加复杂性和延迟,我更喜欢在遍历 json 时塑造数据跨度>
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-14
  • 1970-01-01
  • 2016-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多