Run a Graph Algorithm
Declare graph algorithm outputs as relationships in your semantic model so you can reuse them in model logic and query them after deployment. This guide uses a payment graph to calculate each account’s number of distinct counterparties, then shows how to query that property in Snowflake. It also lists the available graph algorithms.
- Prerequisites
- You know how to define graph nodes and edges. See Create a graph.
- You have access to a Snowflake environment where you can deploy a model and query its output.
Use a graph algorithm
Section titled “Use a graph algorithm”To use a graph algorithm to calculate a property in your model, first define the graph and call the Graph object’s method for the algorithm you want to use
Then deploy the model and query the results in Snowflake.
In the following example, the .degree() method is used to count how many other accounts each account in a payment graph exchanges payments with.
The model has four accounts. Account 1 pays account 2 twice, account 2 pays account 3, and account 4 has no payments. Account 2 also pays itself.
-
Define the model and graph algorithm.
Consider the following model of accounts and payments:
from relationalai.semantics import Integer, Modelfrom relationalai.semantics.reasoners.graph import Graphm = Model("AccountCounterparties")Account = m.Concept("Account", identify_by={"id": Integer})Payment = m.Concept("Payment", identify_by={"id": Integer})Payment.payer = m.Property(f"{Payment} sent from {Account:payer}")Payment.payee = m.Property(f"{Payment} sent to {Account:payee}")Account.counterparty_count = m.Property(f"{Account} has {Integer:counterparty_count} counterparties")21 collapsed linesaccount_data = m.data([{"id": 1},{"id": 2},{"id": 3},{"id": 4},])m.define(Account.new(account_data.to_schema()))payment_data = m.data([{"id": 100, "payer_id": 1, "payee_id": 2},{"id": 101, "payer_id": 1, "payee_id": 2},{"id": 102, "payer_id": 2, "payee_id": 3},{"id": 103, "payer_id": 2, "payee_id": 2},])m.define(Payment.new(id=payment_data.id,payer=Account.lookup(id=payment_data.payer_id),payee=Account.lookup(id=payment_data.payee_id),))graph = Graph(m,directed=False,weighted=False,aggregator="sum",node_concept=Account,)m.where(Payment.payer != Payment.payee).define(graph.Edge.new(id=Payment.id,src=Payment.payer,dst=Payment.payee,))degree = graph.degree()m.where(degree(Account, Integer)).define(Account.counterparty_count(Integer))node_concept=Accountmakes every account a node, even account 4, which has no payments.id=Payment.idgives each payment its own edge.aggregator="sum"combines edges between the same two accounts. Since the graph is unweighted, it counts each connection once, not each payment.Payment.payer != Payment.payeeleaves out payments an account makes to itself.graph.degree()defines each node’s degree: the number of connections it has. In this graph, that is the number of other accounts it exchanges payments with.- The final rule sets
Account.counterparty_countto the degree. After deployment, this property is a column in theACCOUNToutput.
-
Query the account counts in Snowflake.
After you have deployed the model, you can query the account counts in Snowflake. Wait for the model’s refresh to finish before you query it. The refresh updates the results.
Then you can query the
COUNTERPARTY_COUNTcolumn of theACCOUNToutput table:SELECT ID, COUNTERPARTY_COUNTFROM MY_DATABASE.MY_MODEL.ACCOUNTORDER BY ID;Output ID COUNTERPARTY_COUNT1 12 23 14 0Account 2 has two counterparties: accounts 1 and 3. Its two payments from account 1 count as one connection. Its payment to itself does not count. Account 4 has no payments, so its count is zero.
Available Algorithms
Section titled “Available Algorithms”The following tables describe all of the algorithms available to run on PyRel Graph objects, organized by category.
Basic Statistics
Section titled “Basic Statistics”| Algorithm | Description |
|---|---|
.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. |
Neighbors
Section titled “Neighbors”| Algorithm | Description |
|---|---|
.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. |
Degree
Section titled “Degree”| Algorithm | Description |
|---|---|
.degree() | Returns a binary relationship containing the degree of each node. Self-loops count twice. |
.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. Self-loops count twice. |
.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. |
Centrality Measures
Section titled “Centrality Measures”| Algorithm | Description |
|---|---|
.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. |
Similarity Measures
Section titled “Similarity Measures”| Algorithm | Description |
|---|---|
.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. |
Link Prediction
Section titled “Link Prediction”| Algorithm | Description |
|---|---|
.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. |
Community Detection
Section titled “Community Detection”| Algorithm | Description |
|---|---|
.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. |
Clustering
Section titled “Clustering”| Algorithm | Description |
|---|---|
.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. |
Connectivity
Section titled “Connectivity”| Algorithm | Description |
|---|---|
.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. |
To find paths that match a specific pattern, or to get the paths themselves (the sequence of nodes and edges), see Path reasoning.
Distance
Section titled “Distance”| Algorithm | Description |
|---|---|
.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. Not available for directed or weighted graphs. |