[英]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.