交易欺诈圈 - 节点版本

1. 建模

本节将展示在示例图上执行 Cypher 查询的示例。旨在说明查询的样式,并提供在实际设置中构建数据的指南。我们将在一个由多个节点以环形结构连接的小型交易网络图上进行演示。

示例图将基于以下数据模型

1.1. 数据模型

fs transaction ring data node version model

1.1.1 必填字段

以下是开始所需的字段

Account 节点

  • accountNumber:包含账户的名称。此字段可替换为您用于 Account 的任何其他标识符。

Transaction 节点

  • amount:包含账户之间转移的金额。

  • date:包含交易发生的日期。

PERFORMS 关系

  • 无需属性

BENEFITS_TO 关系

  • 无需属性

1.2. 演示数据

以下 Cypher 语句将在 Neo4j 数据库中创建示例图

// Create all accounts
CREATE (a1:Account {accountNumber: 1})
CREATE (a2:Account {accountNumber: 2})
CREATE (a3:Account {accountNumber: 3})
CREATE (a4:Account {accountNumber: 4})

// Create relationships between accounts
CREATE (a1)-[:PERFORMS]->(:TRANSACTION {amount: 1000, currency: "gbp", date: datetime()-duration({days: 3})})-[:BENEFITS_TO]->(a2)
CREATE (a2)-[:PERFORMS]->(:TRANSACTION {amount: 900, currency: "gbp", date: datetime()-duration({days: 2})})-[:BENEFITS_TO]->(a3)
CREATE (a3)-[:PERFORMS]->(:TRANSACTION {amount: 810, currency: "gbp", date: datetime()-duration({days: 1})})-[:BENEFITS_TO]->(a4)
CREATE (a4)-[:PERFORMS]->(:TRANSACTION {amount: 729, currency: "gbp", date: datetime()})-[:BENEFITS_TO]->(a1)

1.3. Neo4j 模式

// Show neo4j scheme
CALL db.schema.visualization()

它将提供以下响应

fs transaction ring node version schema

摄入数据后,Neo4j 会解释图模式。在该模式中,我们可以观察到通过一个 Transaction 节点以及 PERFORMSBENEFITS_TO 两个关系,一个 Account 节点连接到另一个 Account 节点。

2. Cypher 查询

2.1. 简单交易环

在此查询中,我们将识别一个满足以下要求的环

  • 账户节点应通过 PERFORMSBENEFITS_TO 关系连接。

  • 确保遵循交易方向(非双向查询)。

  • 查找长度大于三次交易但小于七次的环。

此 Cypher 查询兼容 Neo4j 5.9+ 版本。

// Neo4j Compatability: v5.9+
// Identify simple transaction ring
MATCH path=(a:Account)(()-[:PERFORMS]->()-[:BENEFITS_TO]->()){3,6}(a)
RETURN path

2.2. 不含重复账户的交易环

在此查询中,我们将识别一个满足以下要求的环

  • 账户节点应通过 PERFORMSBENEFITS_TO 关系连接。

  • 确保遵循交易方向(非双向查询)。

  • 查找长度大于三次交易但小于七次的环。

  • 确保环由唯一账户组成。

此 Cypher 查询兼容 Neo4j 5.9+ 版本。

// Neo4j Compatability: v5.9+
// Identify transaction ring with no duplicate accounts
MATCH path=(a:Account)((a_i)-[:PERFORMS]->(tx)-[:BENEFITS_TO]->(a_j)){3,6}(a)
// Here we ensure that one path has unique people involved in the chain
WHERE size(apoc.coll.toSet(a_i)) = size(a_i)
// Return all paths
RETURN path

2.3. 具有时间顺序交易的交易环

在此查询中,我们将识别一个满足以下要求的环

  • 账户节点应通过 PERFORMSBENEFITS_TO 关系连接。

  • 确保遵循交易方向(非双向查询)。

  • 查找长度大于三次交易但小于七次的环。

  • 确保环由唯一账户组成

  • 确保 Transaction 节点按时间顺序排列

此 Cypher 查询兼容 Neo4j 5.9+ 版本。

// Neo4j Compatability: v5.9+
// Identify transaction ring where dates are in chronological order​
MATCH path=(a:Account)-[:PERFORMS]->(first_tx)
    // Relationship validation
    ((tx_i)-[:BENEFITS_TO]->(a_i)-[:PERFORMS]->(tx_j)
        // Ensures the dates are in chronological order
        WHERE tx_i.date < tx_j.date
    )*
    (last_tx)-[:BENEFITS_TO]->(a)
// Here we ensure that one path has unique people involved in the chain
WHERE size(apoc.coll.toSet([a]+a_i)) = size([a]+a_i)
// Return all paths
RETURN path

2.4. 交易环中金额扣减 20%

当资金通过欺诈环流通时,账户之间转移的金额通常会被扣除高达 20% 的费用。为解决此问题,我们的查询将允许每笔交易减少高达 20% 的金额。

在此查询中,我们将识别一个满足以下要求的环

  • 账户节点应通过 PERFORMSBENEFITS_TO 关系连接。

  • 确保遵循交易方向(非双向查询)。

  • 查找长度大于三次交易但小于七次的环。

  • 确保环由唯一账户组成

  • 确保 Transaction 节点按时间顺序排列

  • 检查 Trasnction 节点金额是否在前一个 Transaction 金额的 20% 以内。

此 Cypher 查询兼容 Neo4j 5.9+ 版本。

// Neo4j Compatability: v5.9+
// Identify transaction ring where dates are in chronological order​
MATCH path=(a:Account)-[:PERFORMS]->(first_tx)
    // Relationship validation
    ((tx_i)-[:BENEFITS_TO]->(a_i)-[:PERFORMS]->(tx_j)
        // Ensures the dates are in chronological order
        WHERE tx_i.date < tx_j.date
        // Checks that there is less than a 20% difference from the last `TRANSACTION` amount to the next
        AND 0.80 <= tx_i.amount / tx_j.amount <= 1.00
    )*
    (last_tx)-[:BENEFITS_TO]->(a)
// Here we ensure that one path has unique people involved in the chain
WHERE size(apoc.coll.toSet([a]+a_i)) = size([a]+a_i)
// Return all paths
RETURN path

2.4.1. 此查询的作用是什么?

给定的 Cypher 查询旨在识别图数据库中账户通过交易连接的可疑交易环。该查询会查找符合特定条件的交易循环,然后返回这些循环。让我们逐步分析此查询。

1 - 识别交易链的起点和终点

MATCH path=(a:Account)<-[:PERFORMS]-(first_tx)
      (last_tx)-[:BENEFITS_TO]->(a)

这部分识别了涉及账户 (a:Account) 的交易链的起点和终点。first_tx 是链中的第一笔交易,last_tx 是最后一笔。

2 - 关系验证和中间交易

((tx_i)-[:BENEFITS_TO]->(a_i)<-[:PERFORMS]-(tx_j)
      WHERE tx_i.date < tx_j.date
      AND 0.80 <= tx_i.amount / tx_j.amount <= 1.00
)*

查询的这一部分指定了链中中间交易的条件。

(tx_i)-[:BENEFITS_TO]->(a_i)<-[:PERFORMS]-(tx_j)

指定交易 tx_i 进入账户 a_i,且 tx_j 来自该账户。

(tx_i.date < tx_j.date)

这确保了交易按时间顺序排列。

0.80 <= tx_i.amount / tx_j.amount <= 1.00

还检查了交易中的金额是否在彼此的 20% 以内。

3 - 确保链中的账户是唯一的

WHERE size(apoc.coll.toSet([a]+a_i)) = size([a]+a_i)

这确保了链中的所有账户都是唯一的。

apoc.coll.toSet([a]+a_i)

将链中的账户列表转换为集合以删除重复项。

size([a]+a_i)

给出链中账户的总数。

4 - 返回匹配的链

RETURN path

最后,查询返回所有符合上述条件的路径。

总而言之,此查询是另一种通过查找具有特定特征的交易闭环来识别潜在可疑活动的方法。与第一个查询不同,此查询使用 PERFORMS 和 BENEFITS_TO 关系来描述账户之间的资金流向。

© . All rights reserved.