The inference use a greedy algorithm to navigate between model size. For a given model size, the inference is done via a variational EM algorithm. The returned model is the one with the highest ICL criterion among all visited models.

By default the algorithm fits a single level SBM for each level, before inferring the generalized multilevel network. This step can be skipped by specifying an initial clustering with the init_clustering. Also, a given model size can be force by setting the parameters nb_clusters to a given value.

mlvsbm_estimate_generalized_network(
  gmlv,
  nb_clusters = NULL,
  init_clustering = NULL,
  nb_cores = NULL,
  init_method = "hierarchical",
  fit_options = list(ve = "joint")
)

Arguments

gmlv

A GenMLVSBM object, the network to be inferred.

nb_clusters

A vector of L integer, the model sizes. If left to NULL, the algorithm will navigate freely. Otherwise it will navigate between the specified model size and its neighbors.

init_clustering

A list of L vectors of integers of the same length as the number of node of each level. If specified, the algorithm will start from this clustering, then navigate freely.

nb_cores

An integer, the number of cores to use. Default to 1 for Windows and detectCores()/2 for Linux and MacOS

init_method

One of "hierarchical" (the default) or "spectral", "spectral" might be more efficient but can lead to some numeric errors. Not used when int_clustering is given.

fit_options

A named list to be passed to the VE-M inference algorithm.

Value

A FitGenMLVSBM object, the best inference of the network

Details

## fit_options ### ve : Using the default ve = "joint" will update all the block memberships of all levels at each VE step before performing a M step. Using ve = "sequential" will update the block memberships of one level at a time before performing a M step only on the concerned parameters. Use this option if the running time of the algorithm is too long and the number of levels is large.

Examples

my_genmlvsbm <- MLVSBM::mlvsbm_simulate_generalized_network(
  n = c(20,20), # Number of nodes for the lower level and the upper level
  Q = c(2,2), # Number of blocks for the lower level and the upper level
  pi = list(c(.3, .7),NULL), # Block proportion for the upper level, must sum to one
  gamma = list(matrix(c(.9, .2,   # Block proportion for the lower level,
                   .1, .8), # each column must sum to one
                 nrow = 2, ncol = 2, byrow = TRUE)),
  alpha = list(matrix(c(.8, .2,
                            .2, .1),
                          nrow = 2, ncol = 2, byrow = TRUE), # Connection matrix
               matrix(c(.99, .3,
                            .3, .1),
                          nrow = 2, ncol = 2, byrow = TRUE)),# between blocks
  directed = c(FALSE, FALSE), # Are the upper and lower level directed or not ?
  affiliation = "preferential",
  distribution = rep("bernoulli", 2)) # How the affiliation matrix is generated
fit <- MLVSBM::mlvsbm_estimate_generalized_network(
gmlv = my_genmlvsbm, nb_cores = 1)
#> 0/1: 

#> 0/1: 






#> 0/2: 

#> 0/2: 





#> [1] "Infering level 1:"
#> [1] "# blocks: 2, ICL = -95.8665176037591 !"
#> [1] "Infering level 2:"
#> [1] "# blocks: 2, ICL = -82.8923080740211 !"
#> [1] "======= # Blocks : 2, 2,  ICL : -173.150312448671========"
#> [1] "ICL for independent levels : -178.75882567778"
#> [1] "ICL for interdependent levels : -173.150312448671"
#> [1] "=====Interdependence is detected between levels!====="

# A more complex example. A 4 levels network with different structures and
# level direction.
n <- 100
L <- 4
alpha <- list(
  diag(.4, 3, 3) + .1, # Undirected assortative community
  -diag(.2, 3, 3) + .3, # Undirected disassortative
  matrix(c(.8, .2, .1, # Undirected core-periphery
           .4, .4, .1,
           .2, .1, .1), 3, 3),
  matrix(c(.3, .5, .5, # Directed mixt structure
           .1, .4, .5,
           .1, .3, .1), 3, 3)
)
gamma <- lapply(seq(3),
                function(m) matrix(c(.8, .1, .1,
                                     .1, .8, .1,
                                     .1, .1, .8), 3, 3, byrow = TRUE))
pi <- list(rep(1, 3)/3, NULL, c(.1, .3, .6), NULL)
 directed = c(FALSE, FALSE, FALSE, TRUE)
gmlv <- mlvsbm_simulate_generalized_network(n = rep(n, 4),
                                            Q = rep(3, 4),
                                            pi = pi,
                                            gamma = gamma,
                                            alpha = alpha,
                                            directed = directed,
                                            distribution = rep("bernoulli", 4))
if (FALSE) {
fit <- mlvsbm_estimate_generalized_network(gmlv,
              fit_options = list(ve = "joint"))
plot(fit)
fit2 <- mlvsbm_estimate_generalized_network(gmlv,
               fit_options = list(ve = "sequential"))
fitone <- mlvsbm_estimate_generalized_network(gmlv2, nb_clusters = rep(3, 4),
                 fit_options = list(ve = "sequential"))
fit_from_scratch <-  mlvsbm_estimate_generalized_network(
             gmlv,
             init_clustering = lapply(seq(4), function(x)rep(1, n)),
             init_method = "merge_split",
             fit_options = list(ve = "joint"))
}