[Avg. reading time: 8 minutes]
Fraud Detection
Step 1: Graph Data Modeling
Financial entities are modeled as Nodes (e.g., :Customer, :Account, :Transaction, :IPAddress, :PhoneNumber).
The connections between them are modeled as Relationships (e.g., :OWNS, :PERFORMED, :USED, :REGISTERED_AT).
Properties (attributes) are stored on both nodes and relationships (e.g., Customer.name, Transaction.amount, Transaction.timestamp).
This creates an explicit map of "who is connected to whom, and how."
Step 2: Data Ingestion
Data from various sources (customer records, transactions, application logs) is imported into Neo4j, creating the graph structure defined above.
Example: API, CSV, Streaming (Kafka)
Step 3: Pattern Detection via Cypher
Cypher queries to look for suspicious patterns that are indicators of fraud.
Common patterns include:
Shared Attributes: Multiple customers/accounts sharing non-unique identifiers (like an IP address or phone number) but having different personal details.6 This is a classic indicator of a "fraud ring" or synthetic identity fraud.
Circular Money Flow: Transactions forming a loop (money moving from A > B > C > A), often seen in money laundering.
Rapid Activity: A new account performing an unusually large number of transactions in a short time.
Step 4: Visualization and Action
The results are visualized using tools BI Tools.
The queries are executed as soon a new Transaction is added using Triggers.
// 1. Create a Shared IP Address - The fraud indicator
CREATE (ip:IPAddress {ip_address: '103.45.67.89'})
// 2. Create two suspicious customers and their accounts
CREATE (c1:Customer {id: 'C1001', name: 'Rachel'})
CREATE (a1:Account {account_number: 'A9001'})
CREATE (c1)-[:OWNS]->(a1)
CREATE (c1)-[:USED_IP {timestamp: 1730304000}]->(ip) // Rachel uses shared IP
CREATE (c2:Customer {id: 'C1002', name: 'Ross'})
CREATE (a2:Account {account_number: 'A9002'})
CREATE (c2)-[:OWNS]->(a2)
CREATE (c2)-[:USED_IP {timestamp: 1730304100}]->(ip) // Ross uses shared IP, close in time
// 3. Create a legitimate customer
CREATE (c3:Customer {id: 'C1003', name: 'Chandler'})
CREATE (a3:Account {account_number: 'A9003'})
CREATE (ip_c3:IPAddress {ip_address: '201.1.2.3'})
CREATE (c3)-[:OWNS]->(a3)
CREATE (c3)-[:USED_IP {timestamp: 1730304200}]->(ip_c3) // Chandler uses a unique IP
MATCH (c1:Customer)-[:USED_IP]->(ip:IPAddress)<-[:USED_IP]-(c2:Customer)
WHERE c1.id < c2.id // Ensures we only look at unique pairs (c1, c2)
WITH ip, collect(c1.name) + collect(c2.name) AS users, count(DISTINCT c1)+count(DISTINCT c2) AS connectedUsers
WHERE connectedUsers >= 2 // Find IP addresses shared by 2 or more distinct customers
RETURN ip.ip_address AS Shared_IP, users, connectedUsers
Very useful and informative video