Skip to content

Commit

Permalink
Pull request #126: Hotfix/update modularity docs
Browse files Browse the repository at this point in the history
Merge in HYP/hypernetx from hotfix/update-modularity-docs to master

* commit '225f584fbcb10ec5fb2ba299b3adffd6c9e05183':
  bump: version 2.1.0 → 2.1.1
  Update modularity docs
  • Loading branch information
bonicim authored and brendapraggastis committed Nov 11, 2023
2 parents 93fee91 + 225f584 commit 69b2e49
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 32 deletions.
2 changes: 1 addition & 1 deletion .cz.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.commitizen]
name = "cz_conventional_commits"
version = "2.1.0"
version = "2.1.1"
version_files = [
"setup.py",
"docs/source/conf.py",
Expand Down
2 changes: 1 addition & 1 deletion docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import os


__version__ = "2.1.0"
__version__ = "2.1.1"


# If extensions (or modules to document with autodoc) are in another directory,
Expand Down
50 changes: 22 additions & 28 deletions docs/source/modularity.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ given partition of the vertices in a hypergraph. In general, higher modularity i
partitioning of the vertices into dense communities.

Two functions to generate such hypergraph
partitions are provided: **Kumar's** algorithm, and the simple **Last-Step** refinement algorithm.
partitions are provided: **Kumar's** algorithm, and the simple **last-step** refinement algorithm.

The submodule also provides a function to generate the **two-section graph** for a given hypergraph which can then be used to find
vertex partitions via graph-based algorithms.
Expand All @@ -33,55 +33,46 @@ Using the Tool
--------------


Precomputation
^^^^^^^^^^^^^^

In order to make the computation of hypergraph modularity more efficient, some quantities need to be pre-computed.
Given hypergraph H, calling::

HG = hmod.precompute_attributes(H)

will pre-compute quantities such as node strength (weighted degree), d-weights (total weight for each edge cardinality) and binomial coefficients.

Modularity
^^^^^^^^^^

Given hypergraph HG and a partition A of its vertices, hypergraph modularity is a measure of the quality of this partition.
Random partitions typically yield modularity near zero (it can be negative) while positive modularity is indicative of the presence
of dense communities, or modules. There are several variations for the definition of hypergraph modularity, and the main difference lies in the
weight given to different edges. Modularity is computed via::
weight given to different edges given their size $d$ and purity $c$. Modularity is computed via::

q = hmod.modularity(HG, A, wdc=linear)
q = hmod.modularity(HG, A, wdc=hmod.linear)

In a graph, an edge only links 2 nodes, so given partition A, an edge is either within a community (which increases the modularity)
or between communities.
where the 'wdc' parameter points to a function that controls the weights (details below).

With hypergraphs, we consider edges of size *d=2* or more. Given some vertex partition A and some *d*-edge *e*, let *c* be the number of nodes
that belong to the most represented part in *e*; if *c > d/2*, we consider this edge to be within the part.
Hyper-parameters *0 <= w(d,c) <= 1* control the weight
In a graph, an edge only links 2 nodes, so given partition A, an edge is either within a community (which increases the modularity)
or between communities. With hypergraphs, we consider edges of size $d=2$ or more. Given some vertex partition A and some $d$-edge $e$, let $c$ be the number of nodes
that belong to the most represented part in $e$; if $c > d/2$, we consider this edge to be within the part.
Hyper-parameters $0 \le w(d,c) \le 1$ control the weight
given to such edges. Three functions are supplied in this submodule, namely:

**linear**
$w(d,c) = c/d$ if $c > d/2$, else $0$.
**majority**
$w(d,c) = 1$ if $c > d/2$, else $0$.
**strict**
$w(d,c) = 1$ if $c == d$, else $0$.
$w(d,c) = 1$ iff $c = d$, else $0$.

The 'linear' function is used by default. More details in [2].
The 'linear' function is used by default. Other functions $w(d,c)$ can be supplied as long as $0 \le w(d,c) \le 1$ and $w(d,c)=0$ when $c \le d$.
More details can be found in [2].

Two-section graph
^^^^^^^^^^^^^^^^^

There are several good partitioning algorithms for graphs such as the Louvain algorithm and ECG, a consensus clustering algorithm.
There are several good partitioning algorithms for graphs such as the Louvain algorithm, Leiden and ECG, a consensus clustering algorithm.
One way to obtain a partition for hypergraph HG is to build its corresponding two-section graph G and run a graph clustering algorithm.
Code is provided to build such graph via::
Code is provided to build such a graph via::

G = hmod.two_section(HG)

which returns an igraph.Graph object.
which returns an igraph.Graph object.



Clustering Algorithms
^^^^^^^^^^^^^^^^^^^^^

Expand All @@ -92,8 +83,8 @@ from each part inside each edge. Given hypergraph HG, this is called as::
K = hmod.kumar(HG)

The other supplied algorithm is a simple method to improve hypergraph modularity directely. Given some
initial partition of the vertices (for example via Louvain on the two-section graph), move vertices between parts in order
to improve hypergraph modularity. Given hypergraph HG and initial partition A, this is called as::
initial partition of the vertices (for example via Louvain on the two-section graph), we move vertices between parts in order
to improve hypergraph modularity. Given hypergraph HG and an initial partition A, it is called as follows::

L = hmod.last_step(HG, A, wdc=linear)

Expand All @@ -103,8 +94,11 @@ where the 'wdc' parameter is the same as in the modularity function.
Other Features
^^^^^^^^^^^^^^

We represent a vertex partition A as a list of sets, but another conveninent representation is via a dictionary.
We provide two utility functions to switch representation, namely `A = dict2part(D)` and `D = part2dict(A)`.
We represent a vertex partition A as a list of sets, but another useful representation is via a dictionary.
We provide two utility functions to switch representation, namely::

A = dict2part(D)
D = part2dict(A)

References
^^^^^^^^^^
Expand Down
2 changes: 1 addition & 1 deletion hypernetx/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@
from hypernetx.utils import *
from hypernetx.utils.toys import *

__version__ = "2.1.0"
__version__ = "2.1.1"
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from setuptools import setup

__version__ = "2.1.0"
__version__ = "2.1.1"

setup(version=__version__)

0 comments on commit 69b2e49

Please sign in to comment.