Modularity calculation examples

🚨 This page is a work in progress.

We’ve given an intuition for the quality function modularity that is defined as follows with two equivalent formulas:

Also recall the definition of and :

Let’s see it in action with some examples and go through the calculations step by step. You can also verify the results in Desmos.

Weighted graph with singleton communities

Consider the following graph

Weighted test graph
A simple weighted test graph

Its adjacency matrix is given by:

Modularity evalutes to:

This is a pretty bad modularity and stems from the bad community assignment (every vertex in its own community).

We can also use the second equivalent formulation to get to the same result:

The difference between the two formulations is not apparent in this example as we only consider singleton communities here (every vertex is in its own community).

Weighted graph with other communities

Weighted test graph
The same weighted test graph as before with a different vertex-community assignment

The adjacency matrix is the same as above and we also have . But the vertex-community assignment differs. The partitioning shown in the figure is given by:

For the modularity, we therefore calculate:

In step , we’ve used the result from the weighted graph of the previous section. Note that while modularity is still not good, it has slightly improved.

With the equivalent formulation, we end up with – surprise, surprise – the same result:

If we somehow already know the values for and , i. e. the sum of the weights of edges inside the community and respectively the sum of the weights of edges incident to community vertices (aka vertex degrees), the second formula is the way to go as we can just plug our values in and are done in no time.

🎈 Task: Come up with your own graphs and calculate modularity by hand for those. Guess a good vertex-community assignment and see if modularity increases compared to a vertex-community assignment you feel is bad, e.g. when putting all vertices in one big community.




Here are some more examples of graphs used to test the code. The respective modularity values were calculated by hand in the same manner seen above.

Weighted graph 2 with singleton communities

TODO: Insert image of graph

Original Louvain paper graph

TODO: Insert image of graph

The graph is undirected, so we only need to consider the upper diagonal matrix of . We can also omit the diagonal since there are no self-loops in the graph (there are only s on the diagonal). Therefore, the sum of all entries in the upper diagonal matrix of corresponds to the total number of edges in the graph:

For the original node-community assignment where every node is in its own community, we have this clustering:

The initial modularity is therefore given by:

In the next level of the hierarchy, Louvain locally optimizes modularity. The new clustering is given by:

Finally, the second pass merges two communities together, so that we are left with a clustering into two communities in the end:

Notice the four edges , , , were inter-community edges, but are now intra-community edges as the two communities got merged together. The modularity increases to:

In the 3rd pass of Louvain, we find that we cannot locally increase modularity anymore. Therefore, this is the final assignment that a full Louvain run might return. Note that due to the randomness in the algorithm, different runs can return different assignments with different modularity values. For example, another run finds that is the highest modularity it can achieve.

🎈 Task: What is the corresponding clustering to this modularity value? Go to the project page, download the code and run it on the graph multiple times until you encounter a modularity value of in the final run. Use the hierarchy command to display the node-to-community assignment for the different levels. What is the reason for this behavior? Hint: Take a look at node .