【问题标题】:Loading very large RDF triples into iGraph -> Fast vertices lookup?将非常大的 RDF 三元组加载到 iGraph -> 快速顶点查找?
【发布时间】:2014-05-11 20:38:52
【问题描述】:

我需要将 DBPedia 图的一个子集加载到 iGraph 中,以便计算一些图统计信息(例如节点中心性,...)。我使用 Redlands libRDF python 库加载 DBPedia 三元组。每个节点都与一个 URI(唯一标识符)相关联。

我在将图表加载到 iGraph 时遇到了一些问题。我就是这样做的:

1) 读三行(主语、谓语、宾语)

2) 使用以下算法获取或创建顶点(带属性)

def add_or_find_vertex (self, g, uri):
    try:
        return g.vs.find(name=uri)
    except (KeyError, ValueError):
        g.add_vertex(name=uri)
        return g.vs.find(name=uri)

subjVertex = self.add_or_find_vertex(self.g, subject)
objVertex = self.add_or_find_vertex(self.g, object)
self.g.add_edge(subjVertex, objVertex, uri=predicate)

问题是我的脚本很慢,我需要加载 25M 三元组。每个节点都是唯一的,但在三重文件中多次找到。因此,我需要在创建边缘之前执行查找。您能告诉我“查找”方法是否使用索引进行查找(哈希表,...)?顶点查找的复杂性是多少?你会怎么做?

非常感谢

【问题讨论】:

  • 加载列表中的所有边并通过一次调用创建图形。
  • 非常感谢@GaborCsardi。事实上,瓶颈是add_edge() 调用,我一次调用每个关系。相反,我们在 Python 列表中创建了一个边列表,并在最后用add_edges(list) 刷新了该列表。现在,它超级快!

标签: python rdf igraph redland


【解决方案1】:

已经回复here。为了完整起见,我也在此处复制我的答案:

顶点查找通常是 O(|V|),因为默认情况下顶点属性不被索引 - 除了 name 顶点属性,它被索引。但是,g.vs.find 仅在您执行此操作时才使用此索引:g.vs.find(url),但在您执行此操作时不会使用此索引:g.vs.find(name=url)。这是一种错误,因为索引可以在这两种情况下使用。另请参阅邮件列表中的yesterday's thread

但是,请注意 igraph 的数据结构针对静态图进行了优化,因此 g.add_vertex(我假设您也使用 g.add_edge)也可能是一个瓶颈。在内部,igraph 使用索引边列表来存储图形,并且每次更改图形时都必须重新构建索引,因此在可能的情况下批量添加顶点和边会更有效。

由于您似乎已经有了一个迭代器,它以(subject, predicate, object) 的形式生成图的边,也许使用Graph.DictList 一次构建图更容易,因为它还负责将顶点 ID 存储在name 属性,在有意义的地方批量添加边,并从您的三元组中添加 predicate 属性:

>>> g = Graph.DictList(vertices=None, edges=({"source": subject,
...         "target": object, "predicate": predicate}
...         for subject, predicate, object in your_iterator))

Graph.DictList 在我的机器上在 1.63 秒内处理 100000 个预先生成的随机三元组,所以我想这会稍微改善一些情况。

【讨论】:

  • 太棒了,我更了解 iGraph 数据结构现在是如何工作的。也许,值得在文档中添加注释,让潜在用户了解此类操作的复杂性。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多