Skip to content

Run a Graph Algorithm

Graph algorithms are a powerful tool for deriving insights from the concepts and relationships in your semantic model. This guide shows you how to run a graph algorithm, work with its outputs, and presents all of the available algorithms in PyRel with links to their API reference docs.

To run a graph algorithm:

  1. Create a graph.

    Use the Graph class to create a graph object from your model and define its structure with nodes and edges:

    from relationalai.semantics import Model, Integer
    from relationalai.semantics.reasoners import graph
    m = Model("TransactionModel")
    # Declare the model's schema.
    Account = m.Concept("Account", identify_by={"id": Integer})
    Transaction = m.Concept("Transaction", identify_by={"id": Integer})
    Transaction.payer = m.Relationship(f"{Transaction} sent from {Account:payer}")
    Transaction.payee = m.Relationship(f"{Transaction} sent to {Account:payee}")
    # Define base facts.
    19 collapsed lines
    account_data = m.data([
    {"id": 1},
    {"id": 2},
    {"id": 3},
    ])
    m.define(Account.new(account_data.to_schema()))
    transaction_data = m.data([
    {"id": 100, "payer_id": 1, "payee_id": 2},
    {"id": 101, "payer_id": 1, "payee_id": 3},
    {"id": 102, "payer_id": 2, "payee_id": 3},
    ])
    m.define(
    Transaction.new(
    transaction_data.to_schema(exclude=["payer_id", "payee_id"]),
    payer=Account.filter_by(id=transaction_data.payer_id),
    payee=Account.ref().filter_by(id=transaction_data.payee_id)
    )
    )
    # Create a directed, unweighted graph.
    graph = graph.Graph(m, directed=True, weighted=False)
    Node, Edge = graph.Node, graph.Edge
    # Define edges from transactions.
    m.define(graph.Edge.new(src=Transaction.payer, dst=Transaction.payee))
    • A semantic model is built with Account and Transaction concepts that are connected by Transaction.payer and Transaction.payee relationships.
    • A directed, unweighted graph is created from the model with Graph(m, directed=True, weighted=False).
    • The graph’s edges are defined from the Transaction concept, connecting payer accounts to payee accounts.
  2. Call the algorithm’s method from the Graph object.

    Graph objects have methods for all available algorithms. For example, call .degree() to compute the degree of each node in the graph:

    from relationalai.semantics import Model, Number
    from relationalai.semantics.std import floats, graph
    m = Model("TransactionModel")
    # Declare the model's schema.
    Account = m.Concept("Account", identify_by="id")
    Transaction = m.Concept("Transaction", identify_by="id")
    Transaction.payer = m.Relationship(f"{Transaction} sent from {Account:payer}")
    Transaction.payee = m.Relationship(f"{Transaction} sent to {Account:payee}")
    # Define base facts.
    19 collapsed lines
    account_data = m.data([
    {"id": 1},
    {"id": 2},
    {"id": 3},
    ])
    m.define(Account.new(account_data.to_schema()))
    transaction_data = m.data([
    {"id": 100, "payer_id": 1, "payee_id": 2},
    {"id": 101, "payer_id": 1, "payee_id": 3},
    {"id": 102, "payer_id": 2, "payee_id": 3},
    ])
    m.define(
    Transaction.new(
    transaction_data.to_schema(exclude=["payer_id", "payee_id"]),
    payer=Account.filter_by(id=transaction_data.payer_id),
    payee=Account.ref().filter_by(id=transaction_data.payee_id)
    )
    )
    # Create a directed, unweighted graph.
    graph = graph.Graph(m, directed=True, weighted=False, node_concept=Account)
    Node, Edge = graph.Node, graph.Edge
    # Define edges from transactions.
    m.define(Edge.new(src=Transaction.payer, dst=Transaction.payee))
    # Compute the degree of each node and assign the resulting `Relationship`
    # object to a new `.degree` property on the `Node` concept.
    Node.degree = graph.degree()
    # View the degree of each node.
    m.select(Node.id, Node.degree).inspect()
    • graph.degree() computes the degree of each node in the graph and returns a Relationship object with the results.
    • The degree relationship is assigned to Node.degree for easy access in downstream queries and definitions.

The following tables describe all of the algorithms available to run on PyRel Graph objects, organized by category.

AlgorithmDescription
.num_nodes()Returns a unary relationship containing the number of nodes in the graph.
.num_edges()Returns a unary relationship containing the number of edges in the graph.
.num_triangles()Returns a unary relationship containing the total number of unique triangles in the graph.
AlgorithmDescription
.neighbor()Returns a binary relationship containing all neighbor pairs in the graph.
.inneighbor()Returns a binary relationship of all nodes and their in-neighbors.
.outneighbor()Returns a binary relationship of all nodes and their out-neighbors.
.common_neighbor()Returns a ternary relationship of common neighbor triplets.
AlgorithmDescription
.degree()Returns a binary relationship containing the degree of each node.
.indegree()Returns a binary relationship containing the indegree of each node.
.outdegree()Returns a binary relationship containing the outdegree of each node.
.weighted_degree()Returns a binary relationship containing the weighted degree of each node.
.weighted_indegree()Returns a binary relationship containing the weighted indegree of each node.
.weighted_outdegree()Returns a binary relationship containing the weighted outdegree of each node.
AlgorithmDescription
.degree_centrality()Returns a binary relationship containing the degree centrality of each node.
.eigenvector_centrality()Returns a binary relationship containing the eigenvector centrality of each node.
.betweenness_centrality()Returns a binary relationship containing the betweenness centrality of each node.
.pagerank()Returns a binary relationship containing the PageRank score of each node.
AlgorithmDescription
.jaccard_similarity()Returns a ternary relationship containing the Jaccard similarity for pairs of nodes.
.cosine_similarity()Returns a ternary relationship containing the cosine similarity for pairs of nodes.
AlgorithmDescription
.adamic_adar()Returns a ternary relationship containing the Adamic-Adar index for pairs of nodes.
.preferential_attachment()Returns a ternary relationship containing the preferential attachment score for pairs of nodes.
AlgorithmDescription
.infomap()Partitions nodes into communities using a variant of the Infomap algorithm.
.louvain()Partitions nodes into communities using the Louvain algorithm.
.label_propagation()Partitions nodes into communities using the Label Propagation algorithm.
AlgorithmDescription
.triangle()Returns a ternary relationship containing all triangles in the graph.
.unique_triangle()Returns a ternary relationship containing all unique triangles in the graph.
.triangle_count()Returns a binary relationship containing the number of unique triangles each node belongs to.
.local_clustering_coefficient()Returns a binary relationship containing the local clustering coefficient of each node.
.average_clustering_coefficient()Returns a unary relationship containing the average clustering coefficient of the graph.
AlgorithmDescription
.reachable()Returns a binary relationship of pairs of nodes (u, v) where v is reachable from u.
.weakly_connected_component()Returns a binary relationship that maps each node to its weakly connected component.
.is_connected()Returns a unary relationship containing whether the graph is connected.
AlgorithmDescription
.distance()Returns a ternary relationship containing the shortest path length between pairs of nodes.
.diameter_range()Estimates the graph diameter and returns it as a minimum and maximum bound.