将非常大的RDF三元组加载到iGraph中 - >快速顶点查找?

时间:2014-05-11 20:38:52

标签: python rdf igraph redland

我需要将一个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三倍。每个节点都是唯一的,但在三重文件中可以找到几次。因此,我需要在创建边缘之前执行查找。你能告诉我“find”方法是否正在使用索引进行查找(Hashtable,...)?顶点查找的复杂性是多少?你会怎么做?

非常感谢

1 个答案:

答案 0 :(得分:3)

已经回答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个预生成的随机三元组,所以我猜这会改善一些事情。