vtraag / leidenalg

Implementation of the Leiden algorithm for various quality functions to be used with igraph in Python.
GNU General Public License v3.0
616 stars 78 forks source link

Quality values of Leiden and Louvain #17

Closed gokceneraslan closed 5 years ago

gokceneraslan commented 5 years ago

When I compare the values returned by the quality() method of RBConfigurationVertexPartition in louvain and leiden packages, I see that the values outputted by louvain is always a lot higher.

For example in the network below, I ran louvain and leiden with resolution=1 and then I also ran leiden with resolution=0.44 to get the same number of partitions:

image

Although the partitions look very similar, the quality values for these three partitions are 45566.48, 16023.20 and 14271.00, respectively. I was wondering if the modularity values are reported in different scales or so.

Next, I ran louvain and leiden on the same network with different resolution parameters 10 times with same seeds and plotted quality values:

image

Here it seems like values do not depend much on the seed but there is still a huge difference between the two.

gokceneraslan commented 5 years ago

image

Here is how it looks like after dividing modularity by 2m (=g.ecount()).

gokceneraslan commented 5 years ago

With resolution=0, Leiden RBConfigurationVertexPartition reports 0.30242 (scaled) quality, this value however is 1.0 for Louvain RBConfigurationVertexPartition.

vtraag commented 5 years ago

First of all, the quality value returned by RBConfigurationVertexPartition is not scaled in either louvain or leidenalg. The quality value is scaled for ModularityVertexPartition (in both algorithms). Note however that the scaling is done by the total weight, which is only equal to 2*G.ecount() in the case of an unweighted undirected graph.

Just to be sure, if you do the following

part_louvain = louvain.find_partition(G, louvain.RBConfigurationVertexPartition)
part_leiden = leidenalg.RBConfigurationVertexPartition(G, initial_membership=part_louvain.membership)

you should find that part_louvain.quality() == part_leiden.quality(). Is this not the case for you?

Finally, if you do

part_leiden = leidenalg.find_partition(G, leidenalg.RBConfigurationVertexPartition)

you will find that often part_leiden.quality() >= part_louvain.quality().

Are you absolutely sure that you use the same graph, and also pass the weights, for both packages?

gokceneraslan commented 5 years ago

Ah, sorry. I was comparing a weighted graph with an unweighted graph. You can completely ignore this :)

gokceneraslan commented 5 years ago

An option to scale quality would be very cool though e.g. partition.quality(scale=True).

vtraag commented 5 years ago

No problem! Good to see it clarified. The quality value simply corresponds to what it written in the documentation and is consistent with the cited literature, so I probably won't add such an option.