# Modularity (Q) based on the Louvain split, unexpected values

**URL:** <https://igraph.discourse.group/t/modularity-q-based-on-the-louvain-split-unexpected-values/159>\
**Category:** Usage\
**Tags:** Python\
**Created:** [29 March 2020 13:22 UTC](https://igraph.discourse.group/t/modularity-q-based-on-the-louvain-split-unexpected-values/159 "2020-03-29T13:22:06Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![makaros](https://avatars.discourse-cdn.com/v4/letter/m/b4bc9f/32.png) [@makaros](https://igraph.discourse.group/u/makaros)\
**Post date:** [29 March 2020 13:22 UTC](https://igraph.discourse.group/t/modularity-q-based-on-the-louvain-split-unexpected-values/159/1 "2020-03-29T13:22:06Z")

</div>

Hi igraph community,

I have a graph and I want to estimate the modularity (Q) based on the Louvain split of the graph.

In python I used igraph and to compare, I also estimated Q in Matlab.  
Based on igraph, the Q is negative (weird) whereas the Q based on the Matlab estimation is positive.

I would expect differences in the values but not by so far (+ shows modularity, - shows anti-modularity).  
Any idea why this happens?

Makis

———————————

My code and data ([https://gofile.io/?c=h24mcU](https://gofile.io/?c=h24mcU)):

**PYTHON**

```auto
import numpy as np
import scipy.io
from igraph import *

A = scipy.io.loadmat('A.mat')['A']

graph = Graph.Weighted_Adjacency(A.tolist(), mode=ADJ_UNDIRECTED, attr="weight", loops=False)
Louvain = graph.community_multilevel(weights=graph.es['weight'], return_levels=False)
Q = graph.modularity(Louvain)
print(Q)

-0.001847596203445795

```

**MATLAB (Brain Connectivity Toolbox)**  
using community\_louvain.m: Louvain community detection algorithm

```auto
clear all
load('A.mat')
[M,Q]=community_louvain(A);

Q =

   0.1466

```

**PYTHON** version of **community\_louvain.m:** [https://github.com/aestrivex/bctpy/blob/f9526a693a9af57051762442d8490dcdf2ebf4e3/bct/algorithms/modularity.py#L71](https://github.com/aestrivex/bctpy/blob/f9526a693a9af57051762442d8490dcdf2ebf4e3/bct/algorithms/modularity.py#L71),

```auto
import bct

split, Q = bct.community_louvain(A)
Q
0.14659657544165258

```

again I get approx. 0.1466 that matches the Matlab and Python BCT-based results but is far from the `igraph` output.

---

<div class="post-metadata">

**Author:** ![vtraag](https://yyz2.discourse-cdn.com/free1/user_avatar/igraph.discourse.group/vtraag/32/38_2.png) [@vtraag](https://igraph.discourse.group/u/vtraag)\
**Post date:** [29 March 2020 13:29 UTC](https://igraph.discourse.group/t/modularity-q-based-on-the-louvain-split-unexpected-values/159/2 "2020-03-29T13:29:05Z")

</div>

I am not immediately sure about the difference. One thought: you have to pass the weights to calculate the modularity in `igraph`. Perhaps this is not needed for the Brain Connectivity Toolbox? Perhaps if you pass the weights to the modularity calculations you do get the same modularity value?

---

<div class="post-metadata">

**Author:** ![szhorvat](https://yyz2.discourse-cdn.com/free1/user_avatar/igraph.discourse.group/szhorvat/32/3_2.png) [@szhorvat](https://igraph.discourse.group/u/szhorvat)\
**Post date:** [29 March 2020 14:03 UTC](https://igraph.discourse.group/t/modularity-q-based-on-the-louvain-split-unexpected-values/159/3 "2020-03-29T14:03:54Z")

</div>

I did a really quick try with the Mathematica interface and got 0.141 for the weighted version (0 for the unweighted one).

 ![image](https://global.discourse-cdn.com/free1/uploads/igraph/original/1X/69719480a6478704f8a97ac016a8d7e112728ae9.jpeg)

---

<div class="post-metadata">

**Author:** ![makaros](https://avatars.discourse-cdn.com/v4/letter/m/b4bc9f/32.png) [@makaros](https://igraph.discourse.group/u/makaros)\
**Post date:** [29 March 2020 14:04 UTC](https://igraph.discourse.group/t/modularity-q-based-on-the-louvain-split-unexpected-values/159/4 "2020-03-29T14:04:43Z")

</div>

Indeed that is the case. I expected igraph to understand this since I defined a weighted adjacency matrix but I need to **explicitly** pass the `weights` argument in `modularity()`.

```auto
import numpy as np
import scipy.io
from igraph import *
import bct

A = scipy.io.loadmat("A.mat")['A']
np.fill_diagonal(A,0.0)

# igraph
graph = Graph.Weighted_Adjacency(A.tolist(), mode=ADJ_UNDIRECTED, attr="weight", loops=False)
Louvain = graph.community_multilevel(weights=graph.es['weight'], return_levels=False)
Q = graph.modularity(Louvain, weights=graph.es['weight'])
print(Q)

#bctpy
com, q = bct.community_louvain(A)
print(q)

```

0.14133150351832535

0.14133150351832674

---

<div class="post-metadata">

**Author:** ![makaros](https://avatars.discourse-cdn.com/v4/letter/m/b4bc9f/32.png) [@makaros](https://igraph.discourse.group/u/makaros)\
**Post date:** [29 March 2020 14:06 UTC](https://igraph.discourse.group/t/modularity-q-based-on-the-louvain-split-unexpected-values/159/5 "2020-03-29T14:06:40Z")

</div>

I am happy to see the same Q value in your example. I found the culprit. See my post above. Thanks for the input !
