How to Perform Graph Analytics in Semantica: Centrality and Community Detection

Semantica's CentralityCalculator and CommunityDetector classes provide built-in graph analytics for node importance and community structure, with automatic NetworkX acceleration and pure-Python fallbacks.

The semantica-agi/semantica repository ships with dedicated engines for graph analytics that work out-of-the-box. Whether you need to rank nodes by influence or uncover hidden clusters, the framework handles adjacency conversion, progress tracking, and algorithm dispatch automatically. Both engines reside in the semantica.kg module and normalize diverse graph inputs into a standard format before running computations.

Centrality Analysis with CentralityCalculator

The centrality engine lives in semantica/kg/centrality_calculator.py and exposes a single class, CentralityCalculator, that computes degree, betweenness, closeness, eigenvector, and PageRank scores.

Supported Centrality Metrics

Each metric method returns a dictionary containing the raw score map, an ordered "rankings" list, and algorithm-specific metadata such as "max_degree" or "total_nodes". The helper calculate_all_centrality invokes every individual metric in sequence and aggregates them into one comprehensive report.

NetworkX Acceleration and Pure-Python Fallback

On initialization, the calculator attempts to import NetworkX and stores the result in self.use_networkx. When NetworkX is available, Semantica delegates to its high-performance implementations. If NetworkX is absent, the class falls back to pure-Python routines that run on an adjacency list built by the _build_adjacency helper. Every algorithm follows the same lifecycle: log the start via get_logger(), optionally wrap execution in a ProgressTracker session, normalize the raw scores, and return the result dictionary.

from semantica.kg import CentralityCalculator

graph = {
    "entities": [{"id": "A"}, {"id": "B"}, {"id": "C"}],
    "relationships": [
        {"source": "A", "target": "B"},
        {"source": "B", "target": "C"},
        {"source": "C", "target": "A"},
    ],
}

calc = CentralityCalculator()
all_centrality = calc.calculate_all_centrality(graph)

print("Degree centrality:", all_centrality["degree"]["centrality"])
print("PageRank:", all_centrality["pagerank"]["centrality"])

Community Detection with CommunityDetector

The second engine, defined in semantica/kg/community_detector.py, is CommunityDetector. It identifies tightly-connected clusters using multiple algorithms.

Available Algorithms

The public entry point detect_communities acts as a dispatcher: you supply an algorithm name (or the method alias), and it routes to the correct concrete implementation. Supported methods include Louvain, Leiden, overlapping k-clique, and label-propagation. With NetworkX installed, the dispatcher forwards to native routines such as greedy_modularity_communities and k_clique_communities. Without NetworkX, the class falls back to lightweight heuristics in _basic_community_detection and _basic_overlapping_detection.

The returned dictionary includes:

  • "communities": list of member sets.
  • "node_assignments": mapping from node to community ID.
  • "modularity": quality score of the partition.
  • "algorithm": name of the method used.

Additional helpers such as calculate_community_metrics and analyze_community_structure expose intra-community edge counts, inter-community edge statistics, and other structural quality indicators.

Chunked Processing for Large Graphs

For large graphs, label propagation supports chunked processing via the chunk_size parameter. When the node count exceeds the threshold, Semantica automatically processes the graph in chunks to keep memory usage bounded.

from semantica.kg import CommunityDetector

detector = CommunityDetector()
result = detector.detect_communities(graph, algorithm="louvain")

print("Found", len(result["communities"]), "communities")
print("Modularity:", result["modularity"])
print("Node assignments:", result["node_assignments"])
detector = CommunityDetector()
communities = detector.detect_communities(
    graph,
    algorithm="label_propagation",
    max_iterations=200,
    random_seed=42,
    chunk_size=5000,
)

print("Communities detected:", len(communities["communities"]))

Shared Infrastructure for Graph Analytics

Both engines rely on common utilities in the semantica.utils package to normalize inputs and monitor long-running tasks.

Adjacency Construction

The _build_adjacency method converts any supported graph representation—whether a dictionary with a "relationships" key, a custom object, or an existing NetworkX graph—into a simple {node: [neighbors]} map.

Progress Tracking and Logging

The get_progress_tracker() singleton, defined in semantica/utils/progress_tracker.py, can be enabled or disabled globally. Heavy steps start a tracking session with start_tracking and end with stop_tracking. Separately, semantica/utils/logging.py supplies get_logger(), which returns a module-specific logger (centrality_calculator or community_detector) for consistent debug and info output.

End-to-End Example: Combining Centrality and Community Data

Because both classes accept the same normalized graph format, you can pipe centrality scores into community contexts for richer downstream analytics. The following example extracts the top five highest-degree nodes and prints each node's assigned Louvain community:

centrality = CentralityCalculator().calculate_degree_centrality(graph)
communities = CommunityDetector().detect_communities(graph, algorithm="louvain")

top_nodes = centrality["rankings"][:5]
for entry in top_nodes:
    node = entry["node"]
    score = entry["score"]
    comm_id = communities["node_assignments"].get(node, None)
    print(f"Node {node}: degree={score:.3f}, community={comm_id}")

Summary

  • CentralityCalculator in semantica/kg/centrality_calculator.py computes degree, betweenness, closeness, eigenvector, and PageRank, with a single calculate_all_centrality call for bulk reports.
  • CommunityDetector in semantica/kg/community_detector.py supports Louvain, Leiden, k-clique, and label-propagation via the detect_communities dispatcher.
  • Both engines auto-detect NetworkX for acceleration and fall back to pure-Python adjacency-list implementations.
  • Shared utilities _build_adjacency, get_progress_tracker(), and get_logger() standardize input handling and observability across all graph analytics workflows.

Frequently Asked Questions

Does Semantica require NetworkX to run graph analytics?

No. Semantica attempts to import NetworkX at initialization, but every algorithm has a pure-Python fallback that operates on an internal adjacency list. You only need to pip install networkx if you want the faster accelerated path.

What graph formats does Semantica accept?

The _build_adjacency helper normalizes dictionaries with "relationships" arrays, custom graph objects, or existing NetworkX graphs into a uniform {node: [neighbors]} structure. This means most common representations work without manual conversion.

How do I monitor the progress of long-running centrality or community calculations?

Both engines integrate with the lightweight ProgressTracker singleton from semantica/utils/progress_tracker.py. Each heavy step automatically starts and stops tracking sessions, and you can enable or disable the tracker globally via get_progress_tracker().

Which community detection algorithm should I use for large graphs?

For large graphs, use label_propagation with the chunk_size parameter (for example, chunk_size=5000). This activates chunked processing that keeps memory usage bounded while still converging on community structure.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →