def test_move_nodes(self):
   G = ig.Graph.Full(100);
   partition = louvain.CPMVertexPartition(G, resolution_parameter=0.5);
   self.optimiser.move_nodes(partition, consider_comms=louvain.ALL_NEIGH_COMMS);
   self.assertListEqual(
       partition.sizes(), [100],
       msg="CPMVertexPartition(resolution_parameter=0.5) of complete graph after move nodes incorrect.");
Exemple #2
0
def multilayer_louvain(G_intralayer,
                       G_interlayer,
                       layer_vec,
                       gamma,
                       omega,
                       optimiser=None,
                       return_partition=False):
    # RBConfigurationVertexPartitionWeightedLayers implements a multilayer version of "standard" modularity (i.e.
    # the Reichardt and Bornholdt's Potts model with configuration null model).
    check_multilayer_louvain_capabilities()

    if 'weight' not in G_intralayer.es:
        G_intralayer.es['weight'] = [1.0] * G_intralayer.ecount()

    if 'weight' not in G_interlayer.es:
        G_interlayer.es['weight'] = [1.0] * G_interlayer.ecount()

    if optimiser is None:
        optimiser = louvain.Optimiser()

    intralayer_part = louvain.RBConfigurationVertexPartitionWeightedLayers(
        G_intralayer,
        layer_vec=layer_vec,
        weights='weight',
        resolution_parameter=gamma)
    interlayer_part = louvain.CPMVertexPartition(G_interlayer,
                                                 resolution_parameter=0.0,
                                                 weights='weight')
    optimiser.optimise_partition_multiplex([intralayer_part, interlayer_part],
                                           layer_weights=[1, omega])

    if return_partition:
        return intralayer_part
    else:
        return tuple(intralayer_part.membership)
 def test_optimiser(self):
   G = reduce(ig.Graph.disjoint_union, (ig.Graph.Tree(10, 3, mode=ig.TREE_UNDIRECTED) for i in range(10)));
   partition = louvain.CPMVertexPartition(G, resolution_parameter=0);
   self.optimiser.consider_comms=louvain.ALL_NEIGH_COMMS;
   self.optimiser.optimise_partition(partition);
   self.assertListEqual(
       partition.sizes(), 10*[10],
       msg="After optimising partition failed to find different components with CPMVertexPartition(resolution_parameter=0)");
 def test_neg_weight_bipartite(self):
   G = ig.Graph.Full_Bipartite(50, 50);
   G.es['weight'] = -0.5;
   partition = louvain.CPMVertexPartition(G, resolution_parameter=-0.5, weights='weight');
   self.optimiser.consider_comms=louvain.ALL_COMMS;
   self.optimiser.optimise_partition(partition);
   self.assertListEqual(
       partition.sizes(), 2*[50],
       msg="After optimising partition failed to find bipartite structure with CPMVertexPartition(resolution_parameter=-0.1)");
def multilayer_louvain(G_intralayer,
                       G_interlayer,
                       layer_vec,
                       gamma,
                       omega,
                       optimiser=None,
                       return_partition=False):
    r"""Run the Louvain modularity maximization algorithm at a single (:math:`\gamma, \omega`) value.

    :param G_intralayer: intralayer graph of interest
    :type G_intralayer: igraph.Graph
    :param G_interlayer: interlayer graph of interest
    :type G_interlayer: igraph.Graph
    :param layer_vec: list of each vertex's layer membership
    :type layer_vec: list[int]
    :param gamma: gamma (intralayer resolution parameter) to run Louvain at
    :type gamma: float
    :param omega: omega (interlayer resolution parameter) to run Louvain at
    :type omega: float
    :param optimiser: if not None, use passed-in (potentially custom) louvain optimiser
    :type optimiser: louvain.Optimiser
    :param return_partition: if True, return a louvain partition. Otherwise, return a community membership tuple
    :type return_partition: bool
    :return: partition from louvain
    :rtype: tuple[int] or louvain.RBConfigurationVertexPartitionWeightedLayers
    """

    # RBConfigurationVertexPartitionWeightedLayers implements a multilayer version of "standard" modularity (i.e.
    # the Reichardt and Bornholdt's Potts model with configuration null model).
    check_multilayer_louvain_capabilities()

    if 'weight' not in G_intralayer.es:
        G_intralayer.es['weight'] = [1.0] * G_intralayer.ecount()

    if 'weight' not in G_interlayer.es:
        G_interlayer.es['weight'] = [1.0] * G_interlayer.ecount()

    if optimiser is None:
        optimiser = louvain.Optimiser()

    intralayer_part = louvain.RBConfigurationVertexPartitionWeightedLayers(
        G_intralayer,
        layer_vec=layer_vec,
        weights='weight',
        resolution_parameter=gamma)
    interlayer_part = louvain.CPMVertexPartition(G_interlayer,
                                                 resolution_parameter=0.0,
                                                 weights='weight')
    optimiser.optimise_partition_multiplex([intralayer_part, interlayer_part],
                                           layer_weights=[1, omega])

    if return_partition:
        return intralayer_part
    else:
        return tuple(intralayer_part.membership)
 def test_diff_move_node_optimality(self):
   G = ig.Graph.Erdos_Renyi(100, p=5./100, directed=False, loops=False);
   partition = louvain.CPMVertexPartition(G, resolution_parameter=0.1);
   while 0 < self.optimiser.move_nodes(partition, consider_comms=louvain.ALL_NEIGH_COMMS):
     pass;
   for v in G.vs:
     neigh_comms = set(partition.membership[u.index] for u in v.neighbors());
     for c in neigh_comms:
       self.assertLessEqual(
         partition.diff_move(v.index, c), 1e-10, # Allow for a small difference up to rounding error.
         msg="Was able to move a node to a better community, violating node optimality.");
 def maximize_modularity(intralayer_resolution, interlayer_resolution):
     # RBConfigurationVertexPartitionWeightedLayers implements a multilayer version of "standard" modularity (i.e.
     # the Reichardt and Bornholdt's Potts model with configuration null model).
     G_interlayer.es['weight'] = interlayer_resolution
     intralayer_part = \
         louvain.RBConfigurationVertexPartitionWeightedLayers(G_intralayer, layer_vec=layer_vec, weights='weight',
                                                              resolution_parameter=intralayer_resolution)
     interlayer_part = louvain.CPMVertexPartition(G_interlayer,
                                                  resolution_parameter=0.0,
                                                  weights='weight')
     optimiser.optimise_partition_multiplex(
         [intralayer_part, interlayer_part])
     return intralayer_part
def multilayer_louvain_part(G_intralayer, G_interlayer, layer_membership):
    if 'weight' not in G_intralayer.es:
        G_intralayer.es['weight'] = [1.0] * G_intralayer.ecount()

    if 'weight' not in G_interlayer.es:
        G_interlayer.es['weight'] = [1.0] * G_interlayer.ecount()

    intralayer_part = louvain.RBConfigurationVertexPartitionWeightedLayers(
        G_intralayer, layer_vec=layer_membership, weights='weight')
    interlayer_part = louvain.CPMVertexPartition(G_interlayer,
                                                 resolution_parameter=0.0,
                                                 weights='weight')
    return intralayer_part, interlayer_part
Exemple #9
0
def louvain(i, j, val, dim, partition_method, initial_membership, weights,
            resolution, node_sizes, seed, verbose):
    import louvain
    import igraph as ig
    import numpy
    from scipy.sparse import csc_matrix
    data = csc_matrix((val, (i, j)), shape=dim)
    # vcount = max(data.shape)
    sources, targets = data.nonzero()
    edgelist = zip(sources.tolist(), targets.tolist())
    G = ig.Graph(edges=list(edgelist))

    # G = ig.Graph.Adjacency(data.tolist())

    if partition_method == 'ModularityVertexPartition':
        partition = louvain.CPMVertexPartition(
            G, initial_membership=initial_membership, weights=weights)
    elif partition_method == 'RBConfigurationVertexPartition':
        partition = louvain.CPMVertexPartition(
            G,
            initial_membership=initial_membership,
            weights=weights,
            resolution_parameter=resolution)
    elif partition_method == 'RBERVertexPartition':
        partition = louvain.CPMVertexPartition(
            G,
            initial_membership=initial_membership,
            weights=weights,
            node_sizes=node_sizes,
            resolution_parameter=resolution)
    elif partition_method == 'CPMVertexPartition':
        partition = louvain.CPMVertexPartition(
            G,
            initial_membership=initial_membership,
            weights=weights,
            node_sizes=node_sizes,
            resolution_parameter=resolution)
    elif partition_method == 'SignificanceVertexPartition':
        partition = louvain.CPMVertexPartition(
            G, initial_membership=initial_membership, node_sizes=node_sizes)
    elif partition_method == 'SurpriseVertexPartition':
        partition = louvain.CPMVertexPartition(
            G,
            initial_membership=initial_membership,
            weights=weights,
            node_sizes=node_sizes)
    else:
        raise ValueError('partition_method ' + partition_method +
                         ' is NOT supported.')

    if seed != None:
        louvain.set_rng_seed(seed)

    optimiser = louvain.Optimiser()
    diff = optimiser.optimise_partition(partition)

    # ig.plot(partition)
    return partition
def plot_manual_CHAMP(G_intralayer, G_interlayer, layer_vec, partitions):
    """Run an inefficient method to plot optimal modularity partititions across the (gamma, omega) plane to check
    consistency of the CHAMP implementation"""

    if 'weight' not in G_intralayer.es:
        G_intralayer.es['weight'] = [1.0] * G_intralayer.ecount()
    if 'weight' not in G_interlayer.es:
        G_interlayer.es['weight'] = [1.0] * G_interlayer.ecount()

    def part_color(membership):
        membership_val = hash(sorted_tuple(membership))
        return tuple((membership_val / x) % 1.0
                     for x in [157244317, 183849443, 137530733])

    denser_gammas = np.linspace(0, GAMMA_END, 250)
    denser_omegas = np.linspace(0, OMEGA_END, 250)

    intralayer_part = louvain.RBConfigurationVertexPartitionWeightedLayers(
        G_intralayer, layer_vec=layer_vec, weights='weight')
    G_interlayer.es['weight'] = [1.0] * G_interlayer.ecount()
    interlayer_part = louvain.CPMVertexPartition(G_interlayer,
                                                 resolution_parameter=0.0,
                                                 weights='weight')

    # best_partitions = List(quality, partition, gamma, omega)
    best_partitions = [[(-inf, ) * 4] * len(denser_omegas)
                       for _ in range(len(denser_gammas))]
    for p in partitions:
        intralayer_part.set_membership(p)
        interlayer_part.set_membership(p)
        interlayer_base_quality = interlayer_part.quality(
        )  # interlayer quality at omega=1.0
        for g_index, gamma in enumerate(denser_gammas):
            intralayer_quality = intralayer_part.quality(
                resolution_parameter=gamma)
            for o_index, omega in enumerate(denser_omegas):
                # omega * interlayer.quality() matches CPMVertexPartition.quality()
                # with omega as interlayer edge weights (as of 7/2)
                Q = intralayer_quality + omega * interlayer_base_quality
                if Q > best_partitions[g_index][o_index][0]:
                    best_partitions[g_index][o_index] = (Q, p, gamma, omega)

    gammas, omegas, colors = zip(*[(x[2], x[3], part_color(x[1]))
                                   for row in best_partitions for x in row])
    plt.scatter(gammas, omegas, color=colors, s=1, marker='s')
    plt.xlabel("gamma")
    plt.ylabel("omega")
Exemple #11
0
#%% Do community detection
print('\nDoing community detection...')
n_repl = 100
resolutions = [0.6, 1.1, 1.7]
for resolution in resolutions:
    memberships = []
    print('Detecting communities using resolution parameter {0}'.format(resolution))
    for itr in range(n_repl):
      print('\tRun {0:02d}'.format(itr))

      partition_intraslice = [louvain.RBConfigurationVertexPartition(H, weights='weight',
                                                resolution_parameter=resolution)
                              for H in G_intraslice]
      partition_interslice = louvain.CPMVertexPartition(G_interslice,
                                                        weights='weight',
                                                        node_sizes=G_interslice.vs['node_size'], 
                                                        resolution_parameter=0)
      
      ##%% Optimise partitions
      opt = louvain.Optimiser()
      opt.consider_comms = louvain.ALL_NEIGH_COMMS
      opt.optimise_partition_multiplex(partition_intraslice + [partition_interslice])

      # The membership in all partitions will be identical, so simply
      # consider the membership for the interslice partition and graph.
      memberships.append(partition_interslice.membership)
    
    ##%% Write results to file
    cluster_df = pd.DataFrame({attr: G_interslice.vs[attr] for attr in 
                               G_interslice.vertex_attributes()}, index=[v.index for v in G_interslice.vs])
    membership_df = pd.DataFrame.from_records(zip(*memberships), columns=['run_{0}'.format(itr) for itr in range(n_repl)]);