Skip to content

Commit 1fb27aa

Browse files
committed
add: minor refactoring on significance and smaller note block in initial workflow
1 parent 0623371 commit 1fb27aa

File tree

4 files changed

+142
-169
lines changed

4 files changed

+142
-169
lines changed

doc/source/community_detection_guide.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ This documentation provides an overview of the notebooks available in the commun
5858
</a>
5959
</div>
6060

61-
.. grid-item-card:: Test Significance of Community
61+
.. grid-item-card:: Significance of Community Structure
6262
:link: community_detection_guide/notebooks/test_significance_of_community
6363
:link-type: doc
6464
:class-card: sd-card-hover card-yellow-orange

doc/source/community_detection_guide/notebooks/functions.ipynb

Lines changed: 67 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -26,35 +26,36 @@
2626
"metadata": {},
2727
"outputs": [],
2828
"source": [
29-
"def load_graph_from_gml_file(graph_file: str, weight_attribute_name: str = \"weight\"):\n",
30-
" import os\n",
31-
" # Check if the graph file exists\n",
32-
" if not os.path.exists(graph_file):\n",
33-
" print(f\"Error: Graph file '{graph_file}' not found.\")\n",
34-
" print(f\"Please ensure '{graph_file}' is a valid path to your 'lesmis.gml' file.\")\n",
35-
" print(\"You can typically find this file by searching for 'lesmis.gml network dataset'.\")\n",
36-
" return # Exit the function if file is not found\n",
37-
"\n",
38-
" try:\n",
39-
" # Load network from GML file\n",
40-
" # igraph.Graph.Read_GML will automatically load edge attributes like 'value'\n",
41-
" # if they are present in the GML file.\n",
42-
" graph = ig.Graph.Read_GML(graph_file)\n",
29+
"# def load_graph_from_gml_file(graph_file: str, weight_attribute_name: str = \"weight\"):\n",
30+
"# import os\n",
31+
"# # Check if the graph file exists\n",
32+
"# if not os.path.exists(graph_file):\n",
33+
"# print(f\"Error: Graph file '{graph_file}' not found.\")\n",
34+
"# print(f\"Please ensure '{graph_file}' is a valid path to your 'lesmis.gml' file.\")\n",
35+
"# print(\"You can typically find this file by searching for 'lesmis.gml network dataset'.\")\n",
36+
"# return # Exit the function if file is not found\n",
37+
"\n",
38+
"# try:\n",
39+
"# # Load network from GML file\n",
40+
"# # igraph.Graph.Read_GML will automatically load edge attributes like 'value'\n",
41+
"# # if they are present in the GML file.\n",
42+
"# graph = ig.Graph.Read_GML(graph_file)\n",
4343
" \n",
44-
" # Check if the graph has the correct weight attribute name\n",
45-
" if weight_attribute_name not in graph.edge_attributes():\n",
46-
" print(f\"Warning: Graph '{graph_file}' does not have a '{weight_attribute_name}' attribute. \"\n",
47-
" \"Community detection will proceed without explicit weights, or if the algorithm \"\n",
48-
" \"expects them, it might use default uniform weights.\")\n",
49-
" # If no 'value' attribute, assign a default uniform weight for visualization purposes\n",
50-
" graph.es[weight_attribute_name] = 1 \n",
44+
"# # Check if the graph has the correct weight attribute name\n",
45+
"# if weight_attribute_name not in graph.edge_attributes():\n",
46+
"# print(f\"Warning: Graph '{graph_file}' does not have a '{weight_attribute_name}' attribute. \"\n",
47+
"# \"Community detection will proceed without explicit weights, or if the algorithm \"\n",
48+
"# \"expects them, it might use default uniform weights.\")\n",
49+
"# # If no 'value' attribute, assign a default uniform weight for visualization purposes\n",
50+
"# graph.es[weight_attribute_name] = 1 \n",
5151
"\n",
52-
" return graph\n",
52+
"# return graph\n",
5353
"\n",
5454
"\n",
55-
" except Exception as e:\n",
56-
" print(f\"An error occurred while loading or processing the graph: {e}\")\n",
57-
" return\n",
55+
"# except Exception as e:\n",
56+
"# print(f\"An error occurred while loading or processing the graph: {e}\")\n",
57+
"# return\n",
58+
"\n",
5859
"\n",
5960
"def community_detection(graph: ig.Graph, community_detection_method: str = \"multilevel\", weight_attribute_name: str = \"weight\", \n",
6061
" params: dict = None):\n",
@@ -67,9 +68,7 @@
6768
" params[\"weights\"] = weight_attribute_name if weight_attribute_name in graph.edge_attributes() else None\n",
6869
" return graph.community_leiden(**params)\n",
6970
" elif community_detection_method == \"fastgreedy\":\n",
70-
" return graph.community_fastgreedy(weights=weight_attribute_name if weight_attribute_name in graph.edge_attributes() else None).as_clustering()\n",
71-
"\n",
72-
"\n"
71+
" return graph.community_fastgreedy(weights=weight_attribute_name if weight_attribute_name in graph.edge_attributes() else None).as_clustering()"
7372
]
7473
},
7574
{
@@ -80,18 +79,21 @@
8079
"## Functions useful to test community structure"
8180
]
8281
},
82+
{
83+
"cell_type": "markdown",
84+
"id": "6309417d-2705-4454-9e68-84cf34883c1b",
85+
"metadata": {},
86+
"source": [
87+
"### Method 1: Testing network structure with modularity"
88+
]
89+
},
8390
{
8491
"cell_type": "code",
8592
"execution_count": 3,
8693
"id": "1ab35a72-4bcd-4391-8f28-85b39c6a29ef",
8794
"metadata": {},
8895
"outputs": [],
8996
"source": [
90-
"\n",
91-
"def get_modularity_on_clustering(graph: ig.Graph, community_detection_method: str = \"multilevel\", params: dict = None):\n",
92-
" partition = community_detection(graph, community_detection_method, weight_attribute_name=None, params=params)\n",
93-
" return partition.modularity\n",
94-
"\n",
9597
"def rewire(graph: ig.Graph, community_detection_method: str = \"multilevel\", params: dict = None):\n",
9698
" num_randomizations = 500 # Number of randomized networks to generate\n",
9799
" modularity_random_networks = []\n",
@@ -101,13 +103,23 @@
101103
" for i in range(num_randomizations):\n",
102104
" # G.rewire() modifies the graph in-place, so we must work on a copy.\n",
103105
" graph_random = graph.copy()\n",
104-
" \n",
106+
"\n",
105107
" graph_random.rewire(n=num_swaps_for_randomization)\n",
106-
" \n",
107-
" modularity_random_networks.append(get_modularity_on_clustering(graph_random))\n",
108+
"\n",
109+
" partition = community_detection(graph, community_detection_method, weight_attribute_name=None, params=params)\n",
110+
" modularity_random_networks.append(partition.modularity)\n",
108111
"\n",
109112
" return modularity_random_networks\n",
110113
"\n",
114+
"\n",
115+
"def test_community_structure(graph: ig.Graph, graph_name: str = \"Karate Club Network\", community_detection_method: str = \"multilevel\", \n",
116+
" params: dict = None):\n",
117+
" partition = community_detection(graph, community_detection_method, weight_attribute_name=None, params=params)\n",
118+
" modularity_orig = partition.modularity\n",
119+
" modularity_random_networks = rewire(graph, community_detection_method, params)\n",
120+
" plot_histogram(modularity_orig, modularity_random_networks, graph_name)\n",
121+
" \n",
122+
"\n",
111123
"def plot_histogram(modularity_original: float, modularity_random_networks: list[float], graph_name: str=\"Karate Club Network\"):\n",
112124
" import matplotlib.pyplot as plt\n",
113125
" \n",
@@ -128,14 +140,15 @@
128140
" plt.legend()\n",
129141
" plt.grid(axis='y', alpha=0.75)\n",
130142
" plt.tight_layout()\n",
131-
" plt.show()\n",
132-
"\n",
133-
"\n",
134-
"def test_community_structure(graph: ig.Graph, graph_name: str = \"Karate Club Network\", community_detection_method: str = \"multilevel\", \n",
135-
" params: dict = None):\n",
136-
" modularity_orig = get_modularity_on_clustering(graph, community_detection_method, params)\n",
137-
" modularity_random_networks = rewire(graph, community_detection_method, params)\n",
138-
" plot_histogram(modularity_orig, modularity_random_networks, graph_name)\n"
143+
" plt.show()\n"
144+
]
145+
},
146+
{
147+
"cell_type": "markdown",
148+
"id": "7eba4c89-d320-4178-bf00-77966010d148",
149+
"metadata": {},
150+
"source": [
151+
"### Method 2: Testing network structure with NMI values"
139152
]
140153
},
141154
{
@@ -313,23 +326,22 @@
313326
" return pairwise_nmi_values\n"
314327
]
315328
},
329+
{
330+
"cell_type": "markdown",
331+
"id": "45c898fe-e73d-4b0d-aed2-6574df05132d",
332+
"metadata": {},
333+
"source": [
334+
"### Testing Significance of Community Structure on a Grid Graph"
335+
]
336+
},
316337
{
317338
"cell_type": "code",
318339
"execution_count": 5,
319340
"id": "0e018281-2fe7-4c7c-b608-c2e97e315e34",
320341
"metadata": {},
321342
"outputs": [],
322343
"source": [
323-
"def create_grid_graph(rows, cols, circular=False):\n",
324-
" \"\"\"\n",
325-
" Generates a 2D grid graph (lattice) without plotting.\n",
326-
" Returns the graph and its column count for later layout.\n",
327-
" \"\"\"\n",
328-
" G = ig.Graph.Lattice(dim=[rows, cols], nei=1, circular=circular)\n",
329-
" return G\n",
330-
"\n",
331-
"# --- Final version of cluster_and_plot_leiden with grid_cols ---\n",
332-
"def cluster_and_plot_leiden_on_grid(graph, grid_cols, title=\"Graph with Leiden Communities\", plot_size=(8, 8)):\n",
344+
"def plot_leiden_on_grid(graph, grid_cols, communities, title=\"Graph with Leiden Communities\", plot_size=(8, 8)):\n",
333345
" \"\"\"\n",
334346
" Clusters a graph using the Leiden algorithm and plots the result\n",
335347
" with vertices colored by their community, specifically for grid layouts.\n",
@@ -344,11 +356,6 @@
344356
" igraph.clustering.VertexClustering: The community detection result.\n",
345357
" \"\"\"\n",
346358
" import matplotlib.pyplot as plt\n",
347-
" \n",
348-
" print(f\"Clustering graph with {graph.vcount()} vertices and {graph.ecount()} edges using Leiden algorithm...\")\n",
349-
"\n",
350-
" resolution = 0.15\n",
351-
" communities = graph.community_leiden(objective_function=\"modularity\", resolution=resolution)\n",
352359
"\n",
353360
" # Assign colors based on community membership\n",
354361
" palette = ig.GradientPalette(\"red\", \"blue\", n=len(communities)) \n",
@@ -376,9 +383,7 @@
376383
" )\n",
377384
" ax.set_title(title)\n",
378385
" ax.axis('off')\n",
379-
" plt.show()\n",
380-
"\n",
381-
" return communities, resolution"
386+
" plt.show()"
382387
]
383388
},
384389
{

doc/source/community_detection_guide/notebooks/initial_workflow.ipynb

Lines changed: 31 additions & 44 deletions
Large diffs are not rendered by default.

doc/source/community_detection_guide/notebooks/test_significance_of_community.ipynb

Lines changed: 43 additions & 62 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)