How LinkPredictor Uses Graph Structure to Predict Relationships in Semantica

LinkPredictor leverages raw graph topology—node degrees, neighbor set intersections, and existing edge patterns—to calculate relationship likelihood scores using established network science metrics.

The LinkPredictor class in the semantica-agi/semantica repository transforms static knowledge graph structure into actionable relationship forecasts. By querying structural properties such as node degrees and adjacency lists through a unified graph store interface, it applies mathematical proximity algorithms to identify missing connections. This architecture isolates graph traversal logic from scoring mathematics, enabling pure structure-based link prediction across diverse knowledge base implementations.

Graph Structure Extraction Pipeline

The prediction workflow follows a three-stage pipeline that extracts maximum signal from minimal structural queries.

Candidate Node Selection

The predictor begins by identifying which nodes participate in potential link candidates. When specific node_labels are provided, it queries the graph store using get_nodes_by_label or filters the complete node population via get_node_label checks. If no labels are specified, it retrieves the full node set through the _get_all_nodes method [link_predictor.py]. This step ensures that predictions respect entity type constraints while bounding the computational search space.

Existing Edge Exclusion

To focus computation on genuinely missing relationships, the predictor constructs a comprehensive set of current edges using the graph store's get_edges or edges methods when exclude_existing=True (the default) [link_predictor.py]. By filtering these pairs from the candidate set, the algorithm avoids trivial predictions of already-established connections and ensures results highlight new link opportunities.

Topological Scoring Algorithms

The core prediction logic relies on five graph-theoretic metrics implemented in link_predictor.py. Each algorithm uses only structural properties accessed via _get_node_degree and _get_node_neighbors, making them storage-agnostic.

Preferential Attachment

This method assumes that high-degree nodes have a higher probability of forming new connections. The implementation retrieves degrees for both nodes using _get_node_degree and multiplies the values to compute the score [link_predictor.py]. This reflects the "rich get richer" phenomenon observed in scale-free networks, favoring predictions between hub nodes.

Common Neighbors

The algorithm counts the intersection of neighbor sets returned by _get_node_neighbors, assigning higher scores to node pairs with substantial network overlap [link_predictor.py]. This metric captures the intuition that shared connections indicate higher relationship likelihood, regardless of global network structure.

Jaccard Coefficient

Normalizing the common neighbors count, this metric divides the intersection size by the union of both neighbor sets [link_predictor.py]. By accounting for node popularity, it prevents high-degree nodes from dominating predictions solely based on their extensive connection lists.

Adamic-Adar Index

This weighted common neighbor approach sums 1/log(degree) across shared neighbors, calculated using degree lookups via _get_node_degree [link_predictor.py]. The logarithmic penalty assigns higher importance to rare connections through low-degree intermediary nodes, capturing the intuition that specific mutual connections matter more than popular ones.

Resource Allocation Index

Similar to Adamic-Adar but using linear degree penalties, this metric sums 1/degree across shared neighbors to emphasize pathways through scarce structural resources [link_predictor.py]. This algorithm highlights node pairs connected through structural bottlenecks rather than popular highways.

Working with the Graph Store Interface

The predictor achieves storage abstraction through a minimal interface contract requiring only get_all_nodes (or nodes), get_neighbors (or neighbors), and degree methods. This design allows the same topological algorithms to operate across in-memory graphs, persistent triple stores, or distributed databases without modification, as long as the store can return adjacency lists and degree counts.

Code Examples


# Initialize the predictor with the desired algorithm

from semantica.kg import LinkPredictor
predictor = LinkPredictor(method="jaccard_coefficient")

# Predict the 15 most promising new links across the whole graph

top_links = predictor.predict_links(graph_store=my_graph, top_k=15)

# Score a single potential relationship

score = predictor.score_link(my_graph, "Customer:123", "Product:456")

# Get the top-5 recommendations for a particular node

node_rankings = predictor.predict_top_links(my_graph, "Customer:123", top_k=5)

# Bulk-score a list of node pairs (useful for downstream ranking)

pairs = [("A", "B"), ("C", "D"), ("E", "F")]
bulk_scores = predictor.batch_score_links(my_graph, pairs)

Summary

  • LinkPredictor extracts candidate nodes using _get_all_nodes or label-specific queries, then filters existing edges via get_edges to focus computation on missing links.
  • Five structural algorithms—preferential attachment, common neighbors, Jaccard coefficient, Adamic-Adar, and resource allocation—compute relationship likelihood using only degree products and neighbor set intersections.
  • The modular graph store interface requires only basic topology methods (degree, neighbors, edges), ensuring compatibility with diverse storage backends.
  • Results are ranked by score and returned as the top-k predictions (default 20) [link_predictor.py], isolating the most probable missing relationships.

Frequently Asked Questions

What graph properties does LinkPredictor require to make predictions?

The predictor requires only structural properties: node degrees via _get_node_degree and adjacency lists via _get_node_neighbors. It also queries existing edges through get_edges or similar methods to exclude known relationships from the candidate set, ensuring predictions focus on new links.

Can LinkPredictor work with custom graph databases?

Yes. As long as your graph store implements the required methods—get_all_nodes (or nodes), get_neighbors (or neighbors), and degree—the predictor will function correctly. The abstraction layer in link_predictor.py automatically resolves the appropriate API calls based on available methods.

Which scoring algorithm should I choose for my dataset?

Choose preferential attachment for scale-free networks where hub nodes drive connectivity. Use common neighbors for dense communities with high local clustering. Select Jaccard coefficient to normalize predictions against node popularity. Use Adamic-Adar or resource allocation when relationships through rare, specific intermediaries indicate stronger connection potential than paths through popular high-degree nodes.

How does LinkPredictor handle computational efficiency on large graphs?

The predictor leverages the graph store's native implementation for neighbor and degree lookups rather than loading entire graph structures into memory. By filtering existing edges early in the pipeline and supporting batch operations via batch_score_links, it minimizes memory overhead while processing large candidate sets, returning only the top-k results (default 20) to limit output size.

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 →