反欺诈图谱概述与 SQL 实现可行性归纳总结

各位好。我是老赵,做反欺诈图谱做了将近八年。今天咱们聊一个很实在的问题——

反欺诈图谱到底是个啥?以及,能不能用 SQL 把它干出来?

很多人一听“图谱”两个字,脑子里立马蹦出 Neo4j、JanusGraph、Spark GraphX 这些大词。没错,它们很专业。但你在实际项目中会发现,很多中小团队连图数据库都还没上,或者上了但数据还在 Oracle/MySQL 里躺着。这时候,SQL 就成了最现实的武器。

1. 反欺诈图谱的本质

说白了,反欺诈图谱就是一个关系网。每个实体(用户、手机号、设备、IP、银行卡)是一个节点,它们之间的关联(登录、转账、同设备、同IP)是一条边。欺诈团伙往往通过共享设备、循环转账、空壳公司等方式形成异常密集的子图。

举个例子:
A 用户和 B 用户用同一台设备登录过,B 用户又和 C 用户共用同一个手机号,C 用户刚给 A 转账。这三个人本来毫无共同特征,但图谱一建起来,你就看到了一个“三角关系”。传统规则引擎根本抓不住这种模式。

关键点: 反欺诈图谱不是为了画图展示,而是为了在图拓扑上发现孤立点、密集子图、桥接节点、循环路径等异常结构。

我早期在电信反欺诈项目里,就是用 SQL 把用户-设备- IP 的关系做成一张带权邻接表,然后用自连接和递归 CTE 去查二度三度关联。效果出乎意料的好——当然前提是控制数据量。

2. 为什么可以考虑 SQL?

传统图数据库的优势在于原生图遍历、标签属性、复杂路径搜索。但 SQL 也有自己的杀手锏:

  • 零额外基础设施——大部分公司的数据仓库就是 Hive/ClickHouse/PostgreSQL,写 SQL 就能直接用。
  • 容易与现有特征工程整合——直接在查询里做聚合、窗口函数,生成衍生变量,一步到位。
  • 调试方便——出问题了,开发同学自己就能查中间结果,不用求 DBA 导图数据。

不过你也别开心太早,SQL 强推图谱有三道坎:递归深度限制、性能爆炸、图结构无法持久化。后面章节我们会逐一破解。

3. SQL 与图数据库对比:一张表看清楚

维度 原生图数据库 SQL 实现
数据模型 点/边/属性原生 邻接表/关系表+自连接
遍历深度 无限递归(BFS/DFS 内置) 受递归 CTE 层级限制(通常 100~1024)
性能 索引邻接表,毫秒级 多跳 JOIN 可能爆炸,需剪枝
易用性 需学习 Cypher/Gremlin SQL 通用,团队上手快
适用场景 实时图查询、深度分析 离线批量特征、小规模图谱
注意: 如果你的子图深度超过 6 跳,且每天处理亿级边,请老老实实用图数据库。SQL 只能作为前菜。

4. 一个典型的反欺诈图谱长什么样?

下面这张图展示了最核心的实体-关系骨架,我把它叫做“反欺诈五元组”。

反欺诈图谱核心五元组 用户 (User) 设备 (Device) 手机号 (Phone) IP 地址 银行卡 (Card) 登录 绑定 访问 交易 插卡 SQL 如何模拟? • 用户-设备:记录登录日志关联 • 用户-手机号:用户表关联phone_id • N度关系:递归CTE实现广度搜索 • 子图密度:COUNT(DISTINCT node)聚合

图里每个节点对应数据库里的一张事实表或维度表。边就是外键关联或行为日志的 JOIN 键。

为什么我把这五个实体当作“核心”?因为 90% 的欺诈模式都藏在它们之间的二度三度关联里。比如:

  • 同设备多用户——可能为薅羊毛或者团伙作案
  • 手机号与多卡绑定——可能是代付或洗钱
  • IP 与多用户关联——可能是代理池绕过

5. SQL 实现的可行性:我的经验总结

我自己在多个项目里验证过这条路线。拿最近的一个电商反欺诈来说,数据量每天 2 亿条行为日志,用户 5000 万,设备 1 亿,我们用 Hive + ClickHouse 做离线特征。核心流程如下:

  1. 建邻接表——把 user_id, device_id, ip, phone, card 打平成 src_type, src_id, dst_type, dst_id, edge_type 五列。一张表搞定所有关系。
  2. 递归 CTE 做广度优先遍历——限制深度 4 跳,每次 JOIN 邻接表,记录路径。
  3. 聚合子图指标——比如子图内节点数、边数、最大度、环检测。
  4. 衍生变量——把子图指标 JOIN 回用户表,作为特征喂给模型。

听起来很理想?但在实际投产中我踩过一个坑:

别忘了—— 不同的 SQL 数据库对递归 CTE 的实现差异很大。MySQL 8.0 的 WITH RECURSIVE 默认深度 1000,但 PostgreSQL 默认是 1024,Hive 3.x 才支持。写跨库代码时,请先查文档。

我曾经把一个跑在 PostgreSQL 上的递归 CTE 直接挪到 Hive,结果报错说WITH RECURSIVE不支持。最后只能改用 Spark 的 mapSide 方式处理,硬生生多花了两天时间。

6. 避坑总结

  • 不要试图用 SQL 做全图遍历——数据量超过 1 亿边时,递归 CTE 性能会断崖式下降。这时候应该用图数据库或 Spark GraphX。
  • 注意环路问题——欺诈图谱里经常出现 A→B→C→A 的环路,递归如果不加 visited 记录,会死循环。用 path[] 数组判断重复节点。
  • 特征衍生要提前聚合——不要每条边都做一次子图查询,应该在子图计算完成后批量生成变量,再 JOIN 回主表。
  • 内存溢出?加过滤条件——先通过 where 条件剪枝(比如只查近 7 天数据、只查高风险设备),再跑递归。
重要警告: 如果你在金融风控场景使用 SQL 图谱,务必做好数据脱敏。身份证号、银行卡号在邻接表中仅保留 hash 或 token,不要明文存储。