Null models

Note

Additional examples and a demonstration of the correctness of nullmodels submodule are presented in the examples subfolder in the github repo.

Exponential Random Graph Models (ERGM) with local constraints are such ERGMs in which sufficient statistics are defined at the level of individual nodes (or globally for the entire graph). In other words, their values for each node can be set independently. Unlike ERGMs with non-local constraints which are notoriously problematic (e.g. due to degenerate convergence and non-projectivity) they are analytically solvable. Prime examples of ERGMs with local constraints are configuration models which induce maximum entropy distributions over graphs with N nodes with arbitrary expected degree sequence and/or strength sequence constraints.

The pathcensus.nullmodels submodule implements several such ERGMs which are most appropriate for statistical calibration of strucutral coefficients. They can be applied to simple undirected and unweighted/weighted networks.

See also

ERGM

base class for ERGMs

pathcensus.nullmodels.ubcm

Undirected Binary Configuration Model (fixed expected degree sequence)

pathcensus.nullmodels.uecm

Undirected Enhanced Configuration Model (fixed expected degree and strength sequences assuming positive integer weights)

Note

The ERGM functionalities provided by pathcensus are simple wrappers around the NEMtropy package.

Undirected Binary Configuration Model (UBCM)

Undirected Binary Configuration Model (UBCM) induces a maximum entropy probability distribution over networks of a given size such that it has a specific expected degree sequence. It can be used to model undirected unweighted networks. See [VBM+21] for details.

See also

UBCM

UBCM class

Examples

>>> # Make simple ER random graph using `igraph`
>>> import random
>>> import igraph as ig
>>> random.seed(101)
>>> G = ig.Graph.Erdos_Renyi(20, p=.2)
>>> # Initialize UBCM directly from the graph object
>>> ubcm = UBCM(G)
>>> # Alternatively, initialize from degree sequence array
>>> D = np.array(G.degree())
>>> ubcm = UBCM(D).fit()
>>> # Check fit error
>>> round(ubcm.error, 6)
0.0
>>> # Mean absolute deviation of the fitted expected degree sequence
>>> # from the observed sequence
>>> (np.abs(ubcm.ED - ubcm.D) <= 1e-6).all()
True
>>> # Sample a single ensemble instance
>>> ubcm.sample_one()    
<20x20 sparse matrix of type '<class 'numpy.uint8'>'
    with ... stored elements in Compressed Sparse Row format>
>>> # Sample multiple instances (generator)
>>> for instance in ubcm.sample(10): pass

Undirected Enhanced Configuration Model (UECM)

Undirected Enhanced Configuration Model (UECM) induces a maximum entropy probability distribution over networks of a given size such that it has specific expected degree and strength sequences. It can be used to model undirected weighted networks with edge weights being positive integers (with no upper bound). See [VBM+21] for details.

See also

UECM

UECM class

Examples

>>> import random
>>> import igraph as ig
>>> # Make a ER random graph with random integer weights
>>> random.seed(27732)
>>> G = ig.Graph.Erdos_Renyi(20, p=.2)
>>> G.es["weight"] = np.random.randint(1, 11, G.ecount())
>>> # Initialize UECM from the graph object
>>> uecm = UECM(G)
>>> # Alternatively initialize from an array of sufficient statistics
>>> # 1st column - degree sequence; 2nd column - strength sequence
>>> D = np.array(G.degree())
>>> S = np.array(G.strength(weights="weight"))
>>> stats = np.column_stack([D, S])
>>> uecm = UECM(stats).fit()
>>> # Check fit error
>>> round(uecm.error, 6)
0.0
>>> # Mean absolute deviation of the fitted expected degree sequence
>>> # from the observed sequence
>>> (np.abs(uecm.ED - uecm.D) <= 1e-6).all()
True
>>> # Mean absolute deviation of the fitted expected strength sequence
>>> # from the observed sequence
>>> (np.abs(uecm.ES - uecm.S) <= 1e-6).all()
True
>>> # Sample a single instance
>>> uecm.sample_one()    
<20x20 sparse matrix of type '<class 'numpy.int64'>'
    with ... stored elements in Compressed Sparse Row format>
>>> # Sample multiple instances (generator)
>>> for instance in uecm.sample(10): pass