def infomap_communities(graph): node2i = bidict({n: i for i, n in enumerate(graph.nodes)}) if len(node2i) == 0: return {} infomapWrapper = Infomap() for (n1, n2) in graph.edges(): infomapWrapper.addLink(node2i[n1], node2i[n2]) infomapWrapper.run() to_return_temp = infomapWrapper.getModules() to_return = {} for n, c in to_return_temp.items(): to_return[node2i.inv[n]] = c return to_return
def run_infomap_alt(g): from infomap import Infomap n2num = {u: num for num, u in enumerate(g)} num2u = sorted(n2num, key=lambda x: n2num[x]) g_num = nx.Graph() for n, n1 in g.edges(): g_num.add_edge(n2num[n], n2num[n1]) im = Infomap("--undirected") for n, n1 in g_num.edges(): im.addLink(n, n1) im.run() part = {num2u[i]: m for i, m in im.getModules().items()} return part
def eval_map_equation(g, partitionobj): """Return the map equation score for a given partition.""" g1 = nx.convert_node_labels_to_integers(g, label_attribute="name") scoremapeq = 0 partition = partitionobj.communities part = dict() for i in range(len(partition)): for ind in partition[i]: part[ind] = i im = Infomap("--silent --no-infomap") # Don't change the partition. for e in g1.edges(): im.addLink(e[0], e[1]) im.initial_partition = part im.run() scoremapeq = im.codelength return scoremapeq
def info_map(mob_date, od_df=od_df, include_internal=False, silent=True): date = mob_date['date'].unique()[0] mob_date = od_df(mob_date).reset_index(drop=True) if not include_internal: mob_date = mob_date.loc[mob_date['from'] != mob_date['to'], :] mob_date = mob_date.reset_index(drop=True) #quadkeys exceed C max values - map nodes to an int value unique_qks = np.unique(mob_date['from'].astype('int').tolist() + mob_date['to'].astype('int').tolist()) qk_ref = {} for i, qk in enumerate(unique_qks): qk_ref[qk] = i qk_ref_inv = {v: k for k, v in qk_ref.items()} if silent: im_str = "--two-level --directed --seed 1000 --silent" else: im_str = "--two-level --directed --seed 1000" im = Infomap(im_str) for i in range(0, len(mob_date['to'])): row = mob_date.loc[i, :] im.addLink(qk_ref[int(row['from'])], qk_ref[int(row['to'])], row['weight']) im.run() clusters = [] for node in im.tree: if node.is_leaf: clusters.append({ 'date': date, 'quadkey': qk_ref_inv[node.node_id], 'cluster': node.module_id, 'flow': node.flow }) return (pd.DataFrame(clusters))
def findCommunitiesInfomap(G, v_mentions=False): im = Infomap("--two-level --flow-model directed") if v_mentions: read_mentions(DATA_PATH, G) return 0 user_node = dict() node_user = [] l = 0 for i, n in enumerate(G.nodes): l = i user_node[n] = l node_user.append(n) last_l = l if not v_mentions: for e in G.edges: im.addLink(user_node[e[0]], user_node[e[1]]) else: for k, v in x_mentions.items(): for m in v: if not user_node.get(m): user_node[m] = l + 1 node_user.append(m) im.addLink(user_node[k], user_node[m]) im.run() print("Found %d top modules with codelength: %f" % (im.numTopModules(), im.codelength)) communities = {} for node_id, module_id in im.modules: if not node_id > last_l: communities[node_user[node_id]] = module_id nx.set_node_attributes(G, communities, 'community') return im.numTopModules()
class MyInfomap: def __init__(self): self.handler = Infomap("--two-level") def add_network_edge(self, first_id, second_id, weight=1.00): self.handler.addLink(first_id, second_id, weight) def detect_communities(self): self.handler.run() communities = {} for node in self.handler.iterTree(): if node.isLeaf(): if node.moduleIndex() in communities: communities[node.moduleIndex()].append(node.physicalId) else: communities[node.moduleIndex()] = [node.physicalId] return communities
def INFOMAP(g, weights=None): X = Infomap("--two-level") if 'weight' not in g.es.attribute_names(): g.es['weight'] = [1.] * g.vcount() D = dict(zip(g.get_edgelist(), g.es['weight'])) if not weights else dict( zip(g.get_edgelist(), weights)) F = Infomap("--two-level") for a, b in D: F.addLink(a, b, D[(a, b)]) F.run() T = F.tree M = {node.physIndex: node.moduleIndex() for node in T.leafIter()} L = max(M.values()) isolated = set(range(g.vcount())).difference(M.keys()) i = 1 for n in isolated: M[n] = L + i i += 1 g.vs['c'] = [M[i] for i in xrange(g.vcount())] return igraph.VertexClustering.FromAttribute(g, 'c')
def communities_im(mob, silent=True): mob = od_df(mob).reset_index(drop=True) #quadkeys exceed C max values - map nodes to an int value unique_qks = np.unique(mob['from'].astype('int').tolist() + mob['to'].astype('int').tolist()) qk_ref = dict(zip(unique_qks, range(0, len(unique_qks)))) qk_ref_i = {v: k for k, v in qk_ref.items()} im_str = "--two-level --directed --seed 1000" if silent: im_str = im_str + " --silent" im = Infomap(im_str) for i in range(0, len(mob['to'])): row = mob.loc[i, :] im.addLink(qk_ref[int(row['from'])], qk_ref[int(row['to'])], row['weight']) im.run() clusters = [] for node in im.tree: if node.is_leaf: clusters.append({ 'quadkey': qk_ref_i[node.node_id], 'cluster': node.module_id, 'flow': node.flow }) return (pd.DataFrame(clusters))
def _apply_infomap(self): """Partition network with infomap algorithm Annotates node with community_id and returns number of communities found""" infomapWrapper = Infomap("--two-level --directed") print("Building Infomap network from a NetworkX graph...") for e in self.graph.edges(): infomapWrapper.addLink(*e) print("Find communities with Infomap...") infomapWrapper.run() print("Found %d top modules with codelength: %f" % (infomapWrapper.numTopModules(), infomapWrapper.codelength())) communities = {} for node in infomapWrapper.iterTree(): if node.isLeaf(): communities[node.physicalId] = node.moduleIndex() nx.set_node_attributes(self.graph, name='community', values=communities) self.graph = nx.relabel.relabel_nodes(self.graph, self.catalog, copy=True) self.num_modules = infomapWrapper.numTopModules() self.community_labels = set( nx.get_node_attributes(self.graph, "community").values())
def infomap_communities(node_idx_neighbors, node_idx_distances, counts, weight_exponent, distance_metric, verbose): """Two-level partition of single-layer network with Infomap. Parameters ---------- node_index_neighbors : array of arrays Example: `array([array([0]), array([1]), array([2]), ..., array([9997]), array([9998]), array([9999])], dtype=object)`. Returns ------- out : dict (node-community hash map). """ # Tracking if verbose: progress = tqdm else: progress = pass_func # Initiate two-level Infomap network = Infomap("--two-level") # Add nodes (and reindex nodes because Infomap wants ranked indices) if verbose: print(" ... adding nodes:") name_map, name_map_inverse = {}, {} singleton_nodes = [] infomap_idx = 0 for n, neighbors in progress(enumerate(node_idx_neighbors), total=len(node_idx_neighbors)): if len(neighbors) > 1: network.addNode(infomap_idx) name_map_inverse[infomap_idx] = n name_map[n] = infomap_idx infomap_idx += 1 else: singleton_nodes.append(n) # if verbose: # print(f" --> added {len(name_map)} nodes (found {len(singleton_nodes)} singleton nodes)") # Raise exception if network is too sparse. if len(name_map) == 0: raise Exception( "No edges added because `r2` < the smallest distance between any two points." ) # Add links if verbose: n_edges = 0 print(" ... adding edges") if node_idx_distances is None: for node, neighbors in progress(enumerate(node_idx_neighbors), total=len(node_idx_neighbors)): for neighbor in neighbors[neighbors > node]: network.addLink(name_map[node], name_map[neighbor], max(counts[node], counts[neighbor])) if verbose: n_edges += 1 else: for node, (neighbors, distances) in progress( enumerate(zip(node_idx_neighbors, node_idx_distances)), total=len(node_idx_neighbors)): for neighbor, distance in zip(neighbors[neighbors > node], distances[neighbors > node]): if distance_metric == "haversine": distance *= 6371000 network.addLink( name_map[node], name_map[neighbor], max(counts[node], counts[neighbor]) * distance**(-weight_exponent)) if verbose: n_edges += 1 # if verbose: # print(f" --> added {n_edges} edges") # Run infomap # if verbose: print(" ... running Infomap...", end=" ") network.run() # if verbose: print("done") # Convert to node-community dict format partition = dict([(name_map_inverse[infomap_idx], module) for infomap_idx, module in network.modules]) # if verbose: # print(f"Found {len(set(partition.values()))-1} stop locations") return partition, singleton_nodes
# G = nx.generators.erdos_renyi_graph(10, 0.5) # G = nx.generators.cubical_graph() # G = generator.planted_partition_graph(5,50, p_in=0.3, p_out=0.01) G, pos = generate_benchmark_graph(500,0.1) # G = tmp_G pos = nx.spring_layout(G) im = Infomap() # G = nx.Graph() # G.add_node(1) # G.add_node(2) # G.add_edge(1,2) for e in G.edges(data='weight', default=1): # print(e) im.addLink(e[0], e[1], e[2]) im.run() print(f"Found {im.num_top_modules} modules with codelength: {im.codelength}") print("\n#node module") result = {node.node_id: node.module_id-1 for node in im.tree if node.is_leaf} infomap_partition = dict(sorted(result.items())) # infomap_partition = dict(sorted(result.items())) codelength, index_codelength, module_codelength = map_equation(G, infomap_partition) print("") print("Result") print(f"Calculated {codelength} = {index_codelength} + {module_codelength}") print(f"Correct is {im.codelengths[0]} = {im.index_codelength} + {im.module_codelength}") print(f"Difference is {im.codelengths[0]-codelength}")