The attached is a complete example with the input simulated data and the python scripts. The main code is shown below as well, it's mainly one "load edges to graph" function and "minimize_nested_blockmodel_dl".
Thank you!
import os
import numpy as np
import pandas as pd
import pickle
import warnings
from collections import defaultdict
import graph_tool.all as gt
def load_edges_to_graph(tidy_edges,verbose = True):
# Grab lists of unique nodes for both types
node_a_names = tidy_edges['node_a'].unique()
n_node_a = len(node_a_names)
node_b_names = tidy_edges['node_b'].unique()
n_node_b = len(node_b_names)
# create a graph-tool graph
g = gt.Graph(directed=False)
# Setup and pull out node property vectors for easy setting
name = g.vp["name"] = g.new_vp("string")
kind = g.vp["kind"] = g.new_vp("int")
# Dictionaries for adding and grabbing nodes from either class
node_a_add = defaultdict(lambda: g.add_vertex())
node_b_add = defaultdict(lambda: g.add_vertex())
num_edges, _ = tidy_edges.shape
# Start by adding all unique node_a's to make sure nodes are not jumbled by type
if(verbose): print(f'Adding all unique node As to model nodes')
for node_a_name in node_a_names:
node_a = node_a_add[node_a_name]
name[node_a] = node_a_name
kind[node_a] = 0
# Next do node b's
if(verbose): print(f'Adding all unique node Bs to model nodes')
for node_b_name in node_b_names:
node_b = node_b_add[node_b_name]
name[node_b] = node_b_name
kind[node_b] = 1
# Now go edge by edge and add the model.
five_percent = np.ceil(num_edges/20)
for edge_num in range(num_edges):
if((edge_num%five_percent == 0) and verbose):
print(f'{np.round((edge_num/num_edges)*100, decimals=1)}% done | {edge_num}/{num_edges}')
node_a_name, node_b_name = tidy_edges.iloc[edge_num,:]
# Grab the nodes for each end of the edge.
node_a = node_a_add[node_a_name]
node_b = node_b_add[node_b_name]
# Add the edge to the model
edge = g.add_edge(node_a, node_b)
return g
# Load network edges (aka phenome vectors)
tidy_edges = pd.read_csv("bisbm_sim_edge_complex.csv", dtype = 'str')
g = load_edges_to_graph(tidy_edges, verbose = True)
node_types = g.vp['kind']
niter = 1
beta = 1
# mcmc
state = gt.minimize_nested_blockmodel_dl(
g,
state_args = dict(deg_corr = True,clabel=node_types),
multilevel_mcmc_args = dict(niter=niter,beta=beta))