Exploration for appropriate coupling strengths and resolution parameters

The objective is to jointly explore coupling strengths (omega) and resolution parameters (gamma) that lead to a reasonable network modular configuration by visualizing the two parameters pair in a heatmap presentation. In this example, the value ranges for gamma were between 1 and 1.5 and
omega were between 0.2 and 0.5, with increments of 0.05 for each parameter.

Since the algorithm may produce stochastic result, we repeat the CPMVertexPartition for 100 times.

I am planning to evaluate the best omega-gamma pair that fulfilled the criteria: 1) having highest average quality value (average of the the 100 iteration), 2) yielded similar partitions across optimizations. Hence, for each for the 100 optimizations for each parameters pair, I would like to keep the quality value (Q), and the community membership for each node. While not shown in the code snippet below, but these value will be further processed to come out with a heatmap representation

The following code was drafted to answer the above objective. However, I am not sure, whether in general this is considered best practice?, or, there are build-in class that I am not aware of to achieved the same objective.

Apart from that, may I know which value should one considere as representative of a Quality of partition. With reference to the code below, this can be 1) interslice_partition.q , or 2) diff. From the documentation, diff is defined as Improvement in quality function. Due to this, I am confuse which one should be considered if one is desire to evaluate the best gamma-omega pair.

import leidenalg as la
import igraph as ig
import numpy as np
from itertools import product
from tqdm import tqdm

repeatation_leid=100
gamma_r = np.arange(1, 1.5, 0.05)
omega_r = np.arange(0.2, 0.5, 0.05)


# Create first slice graph
G1 = ig.Graph.Formula('A-B-D-C-A, D-E-G-F-D')
# Make a copy, remove edge between C and F
G2 = G1.copy(); G2.add_edge('C', 'F'); G3 = G1.copy();G3.delete_vertices('A')


qval_per_pair=[]
membership_per_pair=[]

# Iterate for each gamma-omega pair
for gamma,omega in tqdm(product(gamma_r, omega_r)):
  qval_per_iti=[]
  membershp_per_iti=[]
  for n_iter in range (0,repeatation_leid):
    # Convert from slices to layers
    G_layers, G_interslice, G = la.time_slices_to_layers([G1, G2, G3], interslice_weight=omega,
                                                         slice_attr='slice', vertex_id_attr='name',
                                                         edge_type_attr='type', weight_attr='weight' )
    # Create partitions
    partitions = [la.CPMVertexPartition(H, node_sizes='node_size',weights='weight',
                                        resolution_parameter=gamma) for H in G_layers]
    interslice_partition = la.CPMVertexPartition(G_interslice, resolution_parameter=0,
                                                 node_sizes='node_size', weights='weight')
    
    
    # Detect communities
    optimiser = la.Optimiser()
    diff = optimiser.optimise_partition_multiplex(partitions + [interslice_partition],n_iterations=-1)
    
    partition_all = ig.VertexClustering(G, partitions[0].membership)
    
    membership_slice = {}
    for v, m in zip(G.vs, partitions[0].membership):
      if v['slice'] not in membership_slice:
        membership_slice[v['slice']] = {}
      membership_slice[v['slice']][v['name']] = m
      
    qval_per_iti.append(interslice_partition.q)
    membershp_per_iti.append(membership_slice)

  qval_per_pair.append(qval_per_iti)
  membership_per_pair.append(membershp_per_iti)

Expected heatmap

Snap 2021-11-07 at 01.33.58

appreciate for your comment on this. @vtraag