使用NetworkX构建二部图后投影结果不符合预期该如何解决
问题成因
AmbiguousSolution报错原因:
不连通二部图的不同连通分量不存在全局统一的二部划分推断规则,直接调用nx.bipartite.sets(G)无法自动确定划分逻辑,因此抛出异常。你手动筛选带有bipartite=0属性的节点作为顶部节点的操作逻辑是正确的。- 投影结果不符合预期的原因:
你调用的nx.bipartite.projected_graph()是无权重简单投影,规则为两个顶部节点只要共享至少一个底部节点就生成连边。按照你的测试数据,John和Aron共同观看过电影A,因此二者之间存在连边;Jeny观看的Y、Z两部电影没有其他用户观看,因此Jeny为孤立节点,投影生成的图结构本身是正确的。你看到的视觉效果不符,核心原因是nx.draw()默认不渲染节点标签,且自动使用的布局每次运行位置不固定,导致你误以为结构错误。如果你预期的是边权重对应共同观看电影数量的加权投影,使用简单投影接口也无法满足需求。
调整方案
方案1:保留简单投影,修正绘图逻辑
如果你的需求就是简单投影,仅需调整绘图代码,显示节点标签并固定布局即可看到正确结构:
import matplotlib.pyplot as plt top_nodes = {n for n, d in G.nodes(data=True) if d["bipartite"] == 0} Z = nx.bipartite.projected_graph(G, top_nodes) # 固定布局种子避免每次运行节点位置变化,开启标签显示 pos = nx.spring_layout(Z, seed=42) nx.draw(Z, pos, with_labels=True, node_color='lightblue', node_size=1500) plt.show()
方案2:生成加权投影
如果你需要投影边体现共同观看的电影数量,使用加权投影接口即可:
import matplotlib.pyplot as plt top_nodes = {n for n, d in G.nodes(data=True) if d["bipartite"] == 0} # 生成加权投影,边的weight属性存储共享的底部节点数量 Z_weighted = nx.bipartite.weighted_projected_graph(G, top_nodes) pos = nx.spring_layout(Z_weighted, seed=42) nx.draw(Z_weighted, pos, with_labels=True, node_color='lightblue', node_size=1500) # 可选:显示边权重 edge_labels = nx.get_edge_attributes(Z_weighted, 'weight') nx.draw_networkx_edge_labels(Z_weighted, pos, edge_labels=edge_labels) plt.show()
内容的提问来源于stack exchange,提问作者Martan
相关产品推荐
相关产品推荐

