Package: pathcensus
Welcome to the documentation ofpathcensuspackage.
It is a Python (3.8+) implementation ofstructural similarity and
complementarity coefficientsfor undirected (un)weighted networks based
on efficient counting of 2- and 3-paths (triples and quadruples)
and 3- and 4-cycles (triangles and quadrangles).Structural coefficients are graph-theoretic
measures of the extent to which relations at different levels
(of edges, nodes or entire networks) are driven by similarity or
complementarity between different nodes. Even though they are defined
in purely combinatorial manner they are motivated by geometric arguments
which link them to the family of latent space/random geometric graph models.
In particular, the geometric view allow the identification of network motifs
charactersitic for similarity (triangles) and complementarity (quadrangles).
They can be seen as a generalization of the well-known
local and global clustering coefficients which summarize the structure
of a network in terms of density of ego subgraph(s).Even though it is a Python packagepathcensusis performant as its main
workhorse functions are just-in-time (JIT) compiled to efficient C code
thanks to thenumbalibrary. It is compatible withnumpyarrays andscipysparse matrices making it easy to use in practice.
Moreover, it allows registering graph classes implemented by different
third-party packages such asnetworkxso they can be converted
automatically to sparse matrices. Conversion methods fornetworkx,igraphandgraph-toolare registered automatically
provided the packages are installed.NOTEpathcensususes theA_{ij} = 1convention to indicate
that a nodeisends a tie to a nodej. Functions converting
graph-like objects to arrays / sparse matrices need to be aware
of that.NOTEpathcensusis compatible only with Python versions supported
bynumba. In practice it means that it is compatible with all
versions (starting from 3.8) except for the latest one, which usually
starts to be supported bynumbawith some (often significant)
delay.For the sake of conveniencepathcensusalso provides implementations
of most appropriate null models for statistical calibration of structural
coefficients which are simple wrappers around the excellentNEMtropypackage. It also defines thepathcensus.inferencesubmodule with
utility class for facilitating approximate statistical inference based on
sampling from null models.Seeexamplessubfolder and the main documentation for more details.At the command line via pip:# Install from PyPI
pip install pathcensusThe current development version (not guaranteed to be stable)
can be installed directly from thegithub repopip install git+ssh://git@github.com/sztal/pathcensus.gitHow to cite?You find the package useful? Please cite our work properly.Main theory paperTalaga, S., & Nowak, A. (2022). Structural measures of similarity and complementarity
in complex networks.Scientific Reports, (in press).UsageNOTEMain internal functions for calculating path census are JIT-compiled
when used for the first time. Thus, the first initialization of aPathCensusobject may be quite slow as its execution time will include
the time required for compilation. However, this happens only once.We will useigraphto generate graphs used in examples. However, even though
it is automatically integrated withpathcensus,igraphis not
a dependency and needs to be installed separately.# Main imports used in the examples belowimportrandomimportnumpyasnpimportigraphasigfrompathcensusimportPathCensus# Set random and numpy rng seedsrandom.seed(303)np.random.seed(101)More detailed examples can be found in the official documentation.Path census & structural coefficientsPath census is a set of counts of different paths and cycles per edge, node
or in the entire graph. The counts are subsequently used to calculate different
kinds of structural coefficients.# Generate simple undirected ER random graphG=ig.Graph.Erdos_Renyi(100,p=.05,directed=False)# Initialize path census object.# it precomputed path/cycle counts at the level of edges.# Other counts are derived from them.P=PathCensus(G)# Get edge-level censusP.census("edges")# Get node-level censusP.census("nodes")# or just P.census()# Get global censusP.census("global")# Column definitions?P.definitionsOnce path census is computed it can be used to calculate structural
coefficients.# Similarity coefficientsP.tclust()# triangle-clustering equivalent to local clustering coefficientP.tclosure()# triangle-closure equivalent to local closure coefficientP.similarity()# structural similarity (weighted average of clustering and closure)# Edge-wise similarityP.similarity("edges")# Global similarity (equivalent to global clustering coefficient)P.similarity("global")The figure below sums up the design of structural similarity coefficients,
their geometric motivation and some of the main properties.# Complementarity coefficientsP.qclust()# quadrangle-based clusteringP.qclosure()# quadrangle-based closureP.complementarity()# structural complementarity (weighted average of clustering and closure)# Edge-wise complementarityP.complementarity("edges")# Global complementarityP.complementarity("global")The figure below sums up the design and the geometric motivation of
complementarity coefficients as well as their main properties.Similarity and/or complementarity coefficients may be calculated in one
go using appropriate methods as shown below.# Similarity + corresponding clustering and closure coefsP.simcoefs()# node-wiseP.simcoefs("global")# global# Complementarity + corresponding clustering and closure coefsP.compcoefs()# node-wiseP.compcoefs("global")# global# All coefficientsP.coefs()# All coefficients + full path censusP.coefs(census=True)Weighted coefficientsBelow we create an ER random graph with random integer edge weights
between 1 and 10. As long as edge weights are assigned to an edge property
of the standard name ("weight") they should be detected automatically
andpathcensuswill calculate weighted census. However, unweighted census
may be enforced by usingweighted=False.G=ig.Graph.Erdos_Renyi(100,p=0.05,directed=False)G.es["weight"]=np.random.randint(1,11,G.ecount())P=PathCensus(G)P.weighted# True# Get all coefficients and full path censusP.coefs(census=True)# Use unweighted censusP=PathCensus(G,weighted=False)P.weighted# FalseP.coefs(census=True)Below is the summary of the construction of weighted coefficients.ParallelPathCensusalgorithmPathCensusobjects may be initialized using parallelized algorithms
by usingparallel=True.NOTEParallel algorithms require an extra compilation step so the first
timeparallel=Trueis used there will be a significant extra
overhead.NOTETheparallel=Trueargument may not work and lead to segmentation
faults on some MacOS machines.# By default all available threads are usedP=PathCensus(G,parallel=True)# Use specific number of threadsP=PathCensus(G,parallel=True,num_threads=2)Other featuresOther main features ofpathcensusare:Null models based on the ERGM family.Utilities for conducting statistical inference based on null models.Integration with arbitrary classes of graph-like objects.All these features are documented in the official documentation.TestingThe repository with the package source code can be cloned easily
from thegithub repo.git clone git@github.com:sztal/pathcensus.gitIt is recommended to work within an isolated virtual environment.
This can be done easily for instance usingconda.
Remember about using a proper Python version (i.e. 3.8+).conda create --name my-env python=3.8
conda activate my-envAfter entering the directory in whichpathcensusrepository
was cloned it is enough to install the package locally.pipinstall.# Or in developer/editable modepipinstall--editable.In order to run tests it is necessary to install also test dependencies.pipinstall-r./requirements-tests.txt# Now tests can be runpytest# Or alternativelymaketest# And to run lintermakelintAnd similarly for building the documentation from source.pipinstall-r./requirements-docs.txt# Now documentation can be builtmakedocsTests targeting different Python versions can be run usingtoxtest
automation framework. You may first need to installtox(e.g.pip install tox).maketest-all# Or alternativelytoxTest coverageUnit test coverage report can be generated easily.make coverage
# Report can be displayed again after running coverage
make cov-reportFeedbackIf you have any suggestions or questions aboutPath censusfeel free to email me
atstalaga@protonmail.com.If you encounter any errors or problems withPath census, please let me know!
Open an Issue at the GitHubhttp://github.com/sztal/pathcensusmain repository.AuthorsSzymon Talaga <stalaga@protonmail.com>