【发布时间】:2021-10-30 12:03:00
【问题描述】:
当我尝试在 123212 个节点和 329512 个边的网络上运行 NetworkX 的 greedy_modularity_communities 社区查找算法时,我不断收到上述错误。
simpledatasetNX 这里是一个 NetworkX Graph 对象。这是我最近运行的:
greedy_modularity_communities(simpledatasetNX)
以及输出了什么:
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-6-a3b0c8705138> in <module>()
----> 1 greedy_modularity_communities(simpledatasetNX)
2 frames
/usr/local/lib/python3.7/dist-packages/networkx/algorithms/community/modularity_max.py in greedy_modularity_communities(G, weight, resolution)
98 if j != i
99 }
--> 100 for i in range(N)
101 }
102 dq_heap = [
/usr/local/lib/python3.7/dist-packages/networkx/algorithms/community/modularity_max.py in <dictcomp>(.0)
98 if j != i
99 }
--> 100 for i in range(N)
101 }
102 dq_heap = [
/usr/local/lib/python3.7/dist-packages/networkx/algorithms/community/modularity_max.py in <dictcomp>(.0)
96 - 2 * resolution * k[i] * k[j] * q0 * q0
97 for j in [node_for_label[u] for u in G.neighbors(label_for_node[i])]
---> 98 if j != i
99 }
100 for i in range(N)
AttributeError: 'NoneType' object has no attribute 'get'
在多次尝试解决这个问题后,我已经多次遇到这个确切的错误。这是我开始的地方,以及我为解决它所做的事情:
- 首先,我从一个数据集中构造了一个 NetworkX MultiDiGraph 对象,我需要将其转换为一个 Graph 对象以运行该算法。我看着只是在做
desired_graph_object = nx.Graph(multidigraphobject)
它似乎在我制作的一个更简单的测试图上做了我想要它做的事情,所以我做了这个然后尝试运行算法,得到了上述错误。
- 我对问题可能是什么感到困惑。然后我记得我构造多向图对象的方式涉及边缘上的许多属性(这个原始对象上有接近 500,000 条边)所以当我试图将它简化为一个图形对象时,可能发生了一些奇怪的事情相同的两个节点之间的多个边被组合在一起,因为我没有做任何事情来解释这一点。例如,其中一些属性是整数,有些是字符串。这似乎是一个足够简单的解决方法:我所要做的就是从我的数据集中构造一个新的图形对象,并只保留一个用于与 greedy_modularity_communities 算法相关的分析的属性。所以我这样做了,但最终还是出现了完全相同的错误。
我现在怀疑我构建这两个图的方式有问题,因为无论我是在简化的多向图对象上还是在图形对象上运行算法,错误的性质都是相同的。
这是我构建图形对象的代码;用于构建多向图对象的代码基本上是复制粘贴并稍作调整以进行此操作,因此我认为没有必要包含它。据我所知,这段代码构造的图形对象和前面讨论的多向图对象看起来都是我想要的。
%%time
for index, row in df.iterrows(): # *Go through our dataframe row by row*
if row["link_id"] != row["parent_id"]: # *Check that the current row is a response to someone else*
link_id_df = link_id_dataframe_dict[row["link_id"]] # *Get the desired thread's dataframe*
for index2, row2 in link_id_df.iterrows(): # *Iterate through the thread dataframe's rows (comments)*
if (row2["id"] in row["parent_id"]) and ( (row["author"],row2["author"]) not in nx.edges(G) ): # *Go until we find the comment whose id matches our original comment's parent_id, AND check that our current potential edge isn't already an edge*
G.add_edge(row["author"],row2["author"]) # *Add the desired edge.*
if row["subreddit"] == ("Daddit" or "daddit"): # *This line and the next three, add the necessary edge attributes.*
nx.set_edge_attributes(G,{(row["author"],row2["author"]): {"daddit": 1, "mommit": 0}})
else:
nx.set_edge_attributes(G,{(row["author"],row2["author"]): {"daddit": 0, "mommit": 1}})
elif (row2["id"] in row["parent_id"]) and ( (row["author"],row2["author"]) in nx.edges(G) ): # *If the edge already exists, ie these two users have interacted before, increase appropriate comment quantity*
if row["subreddit"] == ("Daddit" or "daddit"):
G[row["author"]][row2["author"]]["daddit"] += 1
else:
G[row["author"]][row2["author"]]["mommit"] += 1
一些额外的背景:我的原始数据集是一个庞大的数据框,我想从中构建我的网络。每行代表社交媒体网站上的评论或帖子。它涉及将 cmets 的 id 链接到回复第一条评论的 cmets 的 parent_id。 link_id_dataframe_dict 是一个字典,其中键是给定线程,与该键关联的对象是该线程中所有 cmets 的子数据帧(即,具有该 link_id)。
我们的想法是,我们逐行遍历整个数据框,识别该行/评论所属的线程/link_id,然后在关联的 link_id 数据框中搜索该行的另一行/评论/comment 我们正在考虑是对的回应。当我们这样做时,我们在两个节点之间添加一条边,这条边代表评论,这两个节点是发布回复的用户和被回复的评论。我们还通过添加标记为该社区的属性 1 来记录该评论回复发生在哪个社区,并为其他社区添加零,以跟踪这些用户在哪里进行交互。对于此版本的代码,如果这些用户之前进行过交互,我们也会通过在表示发生新交互的社区的属性中添加一个来记录这一点。
更新:
我从图中删除了自环,但不幸的是仍然遇到同样的错误。
【问题讨论】:
-
你能告诉我们
simpledatasetNX是什么数据类型吗? -
是的 - 它是一个 NetworkX Graph 对象。我会用这个更新帖子。
-
您能否分享一小部分数据样本,以便我们重现错误?
-
非常感谢您提供尽可能多的文本信息,就像您在帖子中所做的那样。但我认为为了让人们帮助你解决这个问题,minimal reproducible example(包括一些测试数据)会很棒!
-
您的任何边是否有一个名为
'weight'的属性? [我不明白这将如何导致您的问题,但我认为如果将'weight'用作属性名称,我认为我在greedy_modularity_communities代码中发现了一个可能的错误]
标签: python networkx social-networking directed-graph network-analysis