繁体   English   中英

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

[英]Loading very large RDF triples into iGraph -> Fast vertices lookup?

我需要将一个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,...)? 顶点查找的复杂性是多少? 你会怎么做?

非常感谢你

在这里回答。 为了完整起见,我也在这里复制我的答案:

顶点查找通常为O(| V |),因为默认情况下不对顶点属性建立索引 - 除了 name vertex属性的索引。 但是, g.vs.find仅在您执行此操作时才使用此索引: g.vs.find(url)但如果执行此操作则不会: g.vs.find(name=url) 这是一种错误,因为索引可以在两种情况下使用。 还可以从邮件列表中查看昨天的帖子

但请注意,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秒的Graph.DictList处理100000个预生成的随机三元组,所以我猜这会改善一些事情。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM