最近做一个项目,主要是为了挖掘客户在银行中的洗钱线索。我们知道犯罪分子洗钱最常见的一种手法就是化零为整,犯罪分子“化零为整”的洗钱方式,旨在通过分散和混淆资金的来源,使其难以被追踪和识别。起往往具有如下一些特点:
1. 分散存款
- 小额存款:犯罪分子会将大额的非法所得拆分成多个小额现金,然后分散存入不同的银行账户中。这种方式可以避免因单笔大额存款而触发银行的反洗钱监控系统。
- 多次转账:通过多次转账操作,将分散存入的小额资金逐渐汇总到某个或某些特定账户中,最终完成资金的整合。
2. 利用多人操作
- 雇佣他人:犯罪分子会雇佣大量不知情或故意参与的“帮手”,让他们协助完成小额存款和转账操作。这样可以进一步分散注意力,降低被发现的风险。
- 身份掩护:使用假身份证或他人的身份信息开设多个银行账户,以增加洗钱活动的隐蔽性。
这里其实最重要的就是最终犯罪分子的钱在银行中的转账链路。当然项目比较复杂,有的也涉及客户隐私,我只能大概描述一下解决的思路。其实这里也是用到了知识图谱。知识图谱在解决网络问题确实非常强大,在挖掘资金转移路径时候也很具有优势。下面讲一下大致的解决思路,如下图所示是一个简易转账网络:
我们看到这个网络中有多人转账最终汇聚到f点,那么节点网络中这么多节点,我们这么挖掘出这类网络呢,其实主要是分两步走:
- 第一步是确认可疑的汇入节点,也就是怎么挖掘出f;
- 第二步是已知汇入节点,挖掘出流入汇入节点的的完整路线;
- 对挖掘路线进行分析;
首先我们看第一步怎么挖掘出汇入节点:这一步主要是去输出图中所有完整的链路, 通过neo4j 以下语句可以挖掘所有图中路径:
MATCH path = (x)-[:TRANSFERRED*]->(y)
WHERE id(x) <> id(y) AND length(path) >= 1
// 提取路径中每个关系的类型和属性
WITH x, y, path,
[r IN relationships(path) | {type: type(r), properties: properties(r)}] AS relationDetails,
[n IN nodes(path) | {properties: properties(n)}] AS nodeDetails
RETURN x.name as start,y.name as end,length(path) as path_length,relationDetails,nodeDetails
当然实际上运行这段语句时候会遇到一个问题,就是数据量大的时候跑起来特别慢,这个问题其实也好解决,主要是对筛选条件进行约束,一般有以下几种思路:
- 基于洗钱的账号特点(如洗钱账号长期不用,后频繁使用,转账金额有特殊性等)进行筛选
- 基于最后归集的账号进行大体上的筛选(如入度超过多少等)
- 可以筛选单独某一个分行/支行的数据进行建模等
我们查看最后输出的结果可以看到,输出内容包括开始节点,归集最终节点,路径长度,具体路径,以第二行a到f为例,我们看到路径长度为2,具体路径是a->d->f,我们对比上图确实存在这样的路径。
有了具体的每一条路径之后,就是怎么筛选合理的归集节点,我们可以加一个判断,譬如文中网络限制最后归集的洗钱节点有要求超过3个账号经过至少2阶的长度进入,可以用如下语句判断,
我们看到只有f点满足要求,然后再给予f点筛选出全体的路径即可,当然这里有些短路径是包含在长路径里面的,这个也好解决,只要遍历每条路径做一下比较就可以了。
总结:
1. 筛选所有节点之间传播路径
2. 基于洗钱节点汇入特点,筛选后确认可疑的汇入节点;
3. 第二步是已知汇入节点,挖掘出流入汇入节点的的完整路线;
4. 对挖掘路线进行分析;