使用SPARQL查询DBpedia并在Python中构建图的相关问题咨询
问题1:构建包含所有英文维基百科文章的巨型图是否具备可行性?
纯单机环境下全量构建不可行。目前DBpedia收录的英文维基百科文章对应600万+节点,页面跳转链接总共有15亿+条,全量拉取不仅会被DBpedia公共SPARQL端点拦截(单次查询有结果上限、超时限制),普通消费级电脑的内存也装不下这么大的图结构。
如果你是用来做BFS算法性能评估,完全没必要拉全量,拉取100万节点、千万级边的子图就足够覆盖性能特征。如果确实需要全量数据,直接下载DBpedia官方预处理好的离线转储文件即可,比自己调用SPARQL查询效率高几个量级。
问题2:如何将上述SPARQL查询导入Python中完成图的构建?
用SPARQLWrapper库调用DBpedia端点拉取查询结果,再用图计算库(推荐用igraph,性能远高于networkx)导入边列表即可,注意必须分页查询,否则单次查询会超时或者被拦截,示例代码如下:
# 先安装依赖:pip install sparqlwrapper igraph from SPARQLWrapper import SPARQLWrapper, JSON import igraph as ig import time # 初始化DBpedia公共端点 sparql = SPARQLWrapper("https://dbpedia.org/sparql") # 基础查询模板,插入分页参数 base_query = """ SELECT ?origin ?link WHERE { ?main a owl:Thing. ?linkto a owl:Thing. ?main dbo:wikiPageWikiLink ?linkto. ?main rdfs:label ?origin. ?linkto rdfs:label ?link. FILTER ( LANG ( ?origin) = 'en' ) FILTER ( LANG ( ?link) = 'en' ) } LIMIT %s OFFSET %s """ edges = [] page_size = 5000 offset = 0 while True: query = base_query % (page_size, offset) sparql.setQuery(query) sparql.setReturnFormat(JSON) results = sparql.query().convert() bindings = results["results"]["bindings"] # 结果为空说明拉取完成 if not bindings: break for item in bindings: u = item["origin"]["value"] v = item["link"]["value"] edges.append((u, v)) offset += page_size # 避免访问频率过高被封IP time.sleep(1) # 直接通过边列表构建无向图 g = ig.Graph.TupleList(edges, directed=False)
补充:DBpedia公共端点有总返回结果上限,如果需要拉取超过百万条边,建议直接下载离线转储的CSV文件,用pandas读取后直接导入图结构,效率更高。
问题3:双向边去重如何实现?
根据你的图类型需求分三种方案处理即可:
- 如果你要构建无向图:直接用无向图结构存储即可,比如igraph的
Graph(directed=False)、networkx的nx.Graph(),添加边时会自动把(A,B)和(B,A)识别为同一条边,自动去重无需额外处理。 - 如果你自己维护边列表:存边前统一对两个节点排序,比如
u, v = sorted([u, v]),再存入列表,之后用list(set(edges))就能快速去重;也可以用frozenset((u, v))作为边的唯一标识存入set,自动过滤重复边。 - 如果你需要保留有向图结构但要剔除双向重复边:遍历边列表时维护一个已存边的set,每次加边前先判断反向边
(v, u)是否在set中,不存在再添加当前边。
内容的提问来源于stack exchange,提问作者hainam
相关产品推荐
相关产品推荐

