Computes a comprehensive structural-statistics suite for a net_hypergraph: node-level, hyperedge-level, and global measures. All measures are derived in a few BLAS calls on the incidence matrix.
Usage
hypergraph_measures(hg)
# S3 method for class 'hypergraph_measures'
print(x, ...)Arguments
- hg
A
net_hypergraph(frombuild_hypergraph()orbipartite_groups()).- x
A
hypergraph_measuresobject.- ...
Additional arguments (ignored).
Value
An object of class hypergraph_measures (a named list) with
components:
- Node-level (length
n_nodes) hyperdegreeNumber of hyperedges containing each node.
node_strengthTotal participation: for node \(i\), \(\sum_{e \ni i} |e|\). A node in many large hyperedges has high strength.
max_edge_sizeSize of the largest hyperedge containing each node.
co_degreen_nodesxn_nodesmatrix:co_degree[i, j] = |{e : i, j in e}|(number of hyperedges co-containing nodes \(i\) and \(j\)). Diagonal is zero.- Hyperedge-level (length
n_hyperedgesor m x m) edge_sizesHyperedge sizes \(|e|\).
edge_pairwise_overlapmxmmatrix:|e_i intersect e_j|. Diagonal is zero.overlap_coefficientmxm:|e_i and e_j| / min(|e_i|, |e_j|). Measures how much the smaller hyperedge is contained in the larger.jaccardmxm: symmetric overlap index|e_i and e_j| / |e_i union e_j|.- Global (scalars)
densityFor
k-uniform hypergraphs:m / choose(n, k). For mixed sizes:sum(|e|) / (n * m)(mean fraction of nodes per hyperedge).avg_edge_sizeMean of
edge_sizes.size_distributionTabulation of hyperedge sizes (passed through from
hg).intersection_profileDistribution of pairwise hyperedge intersection sizes - useful for spotting whether hyperedges overlap mostly trivially or share substantial cores (Do et al. 2020).
pairwise_participationFraction of node pairs co-appearing in at least one hyperedge.
n_nodes,n_hyperedgesConvenience scalars.
The input x invisibly.
Details
All measures are computed via standard matrix operations on the binary incidence \(B = (b_{ij})\) where \(b_{ij} = 1\) iff node \(i\) is in hyperedge \(j\):
hyperdegree = rowSums(B),edge_sizes = colSums(B)co_degree = tcrossprod(B)(with zero diagonal)edge_pairwise_overlap = crossprod(B)(with zero diagonal)overlap_coefficient[i, j] = overlap[i, j] / min(edge_sizes[i], edge_sizes[j])jaccard[i, j] = overlap[i, j] / (edge_sizes[i] + edge_sizes[j] - overlap[i, j])
Empty hypergraph (n_hyperedges == 0) returns trivial zeros and
empty matrices.
References
Lee, G., Choe, M., & Shin, K. (2024). A survey on hypergraph representation, learning and mining. Data Mining & Knowledge Discovery 37, 1-39.
Do, M. T., Yoon, S., Hooi, B., & Shin, K. (2020). Structural patterns and generative models of real-world hypergraphs. arXiv:2006.07060.
Examples
df <- data.frame(
player = c("A", "B", "C", "A", "B", "D", "C", "D"),
session = c("S1", "S1", "S1", "S2", "S2", "S3", "S3", "S3")
)
hg <- bipartite_groups(df, "player", "session")
m <- hypergraph_measures(hg)
print(m)
#> Hypergraph measures: 4 nodes, 3 hyperedges
#> Density: 0.5833
#> Mean edge size: 2.33
#> Pairwise participation: 0.6667
#>
#> Hyperdegree: min=1 med=2.0 max=2
#> Node strength: min=2.0 med=5.0 max=5.0
#> Edge sizes: min=2 med=2.0 max=3
#>
#> Intersection profile (pair counts by overlap size):
#> overlap_0 : 1
#> overlap_1 : 1
#> overlap_2 : 1
m$hyperdegree # how many sessions each player joined
#> A B C D
#> 2 2 2 1
m$co_degree # pairwise co-membership counts
#> A B C D
#> A 0 2 1 0
#> B 2 0 1 0
#> C 1 1 0 1
#> D 0 0 1 0
m$jaccard # symmetric overlap between sessions
#> S1 S2 S3
#> S1 0.0000000 0.6666667 0.25
#> S2 0.6666667 0.0000000 0.00
#> S3 0.2500000 0.0000000 0.00