Banking Use Cases
Banking Use Cases
Apply graph algorithms to real-world banking scenarios
What You'll Learn
- Use Case 1 - Shared Account Network Analysis with PageRank
- Use Case 2 - Community Detection for AML with Louvain
- Use Case 3 - Path Analysis for Customer Due Diligence
# Cell 1 — ParametersUSERNAME = "_FILL_ME_IN_" # Set your email before running# Cell 2 — Connectfrom graph_olap import GraphOLAPClientclient = GraphOLAPClient(username=USERNAME)
# Cell 3 — Provisionfrom notebook_setup import provisionpersonas, conn = provision(USERNAME)analyst = personas["analyst"]admin = personas["admin"]ops = personas["ops"]client = analyst
print(f"Connected | {conn.query_scalar('MATCH (n) RETURN count(n)')} nodes")Use Case 1: Shared Account Network Analysis
Identify central customers using PageRank
Scenario: The compliance team needs to identify which customers are most central in the shared-account network. Central customers connect to many others through joint accounts and are natural starting points for investigations.
Approach: Run PageRank to score every customer by their structural importance, then rank them. Customers with the highest scores act as hubs in the network — changes to their accounts ripple through many connections.
# Use Case 1: PageRank to find central customersresult = conn.algo.pagerank( node_label="Customer", property_name="pr_score", edge_type="SHARES_ACCOUNT",)print(f"PageRank: {result.status} ({result.nodes_updated} nodes updated)")
# Rank customers by centralityranked = conn.query(""" MATCH (c:Customer) RETURN c.id AS name, round(c.pr_score, 4) AS score ORDER BY c.pr_score DESC""")
print("\nFinding: LAU and KWONG are equally central (degree 3 each).")print("These two customers should be reviewed first in any network investigation.")
ranked.show()Use Case 2: Community Detection for AML
Group related customers with Louvain for Anti-Money Laundering review
Scenario: AML analysts need to identify clusters of customers who are closely linked through shared accounts. Each cluster may represent a network of related parties that should be reviewed together rather than individually.
Approach: Run Louvain community detection. Each community is a group of customers more densely connected to each other than to the rest of the network. Analysts can then treat each community as a single investigation package.
# Use Case 2: Louvain community detection for AML clusteringresult = conn.algo.louvain( node_label="Customer", property_name="aml_community", edge_type="SHARES_ACCOUNT",)print(f"Louvain: {result.status} ({result.nodes_updated} nodes updated)")
# Report communitiescommunities = conn.query(""" MATCH (c:Customer) RETURN c.aml_community AS comm, collect(c.id) AS members ORDER BY comm""")
print(f"\nFinding: All {result.nodes_updated} customers form a single community.")print("In production with thousands of customers, Louvain typically finds")print("many smaller communities that can be assigned to individual analysts.")
communities.show()Use Case 3: Path Analysis for Due Diligence
Trace connection chains between customers for KYC review
Scenario: During enhanced due diligence (EDD), an analyst needs to understand how two specific customers are connected. Are they directly linked through a shared account, or is the connection indirect through intermediary customers?
Approach: Use shortest-path analysis to find the chain of connections between two customers. The path length tells the analyst whether the relationship is direct (1 hop) or indirect (2+ hops), and the intermediaries on the path may warrant their own review.
# Use Case 3: Shortest path for due diligence# First get node IDsnodes = conn.query(""" MATCH (c:Customer) RETURN id(c) AS nid, c.id AS name""")node_map = {row['name']: row['nid'] for row in nodes}
# Find path between two customerssrc_name = "21804633"tgt_name = "8984822"
result = conn.algo.shortest_path( source_id=node_map[src_name], target_id=node_map[tgt_name], relationship_types=["SHARES_ACCOUNT"], max_depth=5,)
print(f"Due Diligence: {src_name} \u2192 {tgt_name}")
# AlgorithmExecution has .status and .result (a dict or None), not .path_lengthif result.result is not None: path_data = result.result path_length = path_data.get("path_length", len(path_data.get("path_node_ids", [])) - 1) path_node_ids = path_data.get("path_node_ids", [])
print(f"\nPath length: {path_length} hop(s)")
# Resolve path to names if path_node_ids: id_list = ", ".join(str(i) for i in path_node_ids) path_rows = conn.query(f""" MATCH (c:Customer) WHERE id(c) IN [{id_list}] RETURN id(c) AS nid, c.id AS name """) id_to_name = {row['nid']: row['name'] for row in path_rows} ordered = [id_to_name[nid] for nid in path_node_ids] print(f"Connection chain: {' \u2192 '.join(ordered)}")
if path_length == 1: print("\nAnalysis: Direct connection \u2014 these customers share an account.") else: intermediaries = ordered[1:-1] print(f"\nAnalysis:") print(f" - These customers are NOT directly linked (no shared account)") print(f" - They connect through intermediary: {', '.join(intermediaries)}") print(f" - The intermediary should also be included in the EDD review")else: print("\nNo path found between these customers.")Key Takeaways
- PageRank for network analysis — quickly identifies the most structurally important customers to prioritise for review
- Louvain for AML — groups related customers into investigation packages that analysts can work through systematically
- Shortest path for EDD — traces the chain of connections between customers, revealing intermediaries worth investigating
- These algorithms work on the same graph data — results accumulate as node properties and can be combined in a single query
- In production, scale these patterns from 5 customers to millions while keeping the same SDK API calls