第4章:连通分量分析——连通图与强连通图、连通分量算法(Union-Find)、团伙发现初筛

各位同学,咱们今天聊点硬核的。团伙欺诈识别,说白了就是要在海量用户里找出那些「抱团作案」的家伙。你想想看,一个正常用户和另一个正常用户之间,顶多是点赞之交。但欺诈团伙呢?他们之间往往有密集的资金往来、设备共用、IP共享。怎么把这些「小团体」揪出来?连通分量分析就是第一把刀。

4.1 连通图与强连通图:团伙的两种形态

先搞清楚两个基本概念。我个人习惯把图想象成一张社交网络,节点是人,边是关系。

  • 连通图:任意两个节点之间,至少有一条路径能走通。比如A认识B,B认识C,那A和C就算不直接认识,也能通过B搭上线。这种图就是连通图。
  • 强连通图:更严格了。不仅A能到C,C也能回到A。说白了就是双向奔赴。在反欺诈场景里,强连通图往往意味着更紧密的团伙——比如互相转账、互相担保的那种。

我在项目中遇到过一种情况:一个团伙用同一批手机号注册了大量账号,这些账号之间互相转账、互相点赞。用连通图分析,它们全在一个大团里。但用强连通图分析,你会发现有些账号只收钱不转出,它们其实是「资金归集账户」。嗯,这里要注意,强连通分量往往对应着团伙的核心层。

核心区别一句话:连通图看「能不能走到」,强连通图看「能不能走回来」。团伙初筛用连通图就够了,深挖核心成员才需要强连通。

4.2 连通分量算法:Union-Find 的实战用法

讲算法之前,我先问大家一个问题:给你100万个节点和200万条边,你怎么快速找出所有连通分量?用BFS/DFS当然可以,但每次都要遍历全图,太慢了。

Union-Find(并查集)就是干这个的。它的核心思想就三个字:找爸爸

  • Find:找到某个节点的根节点(团伙老大)。
  • Union:把两个节点合并到同一个团伙里。
  • 路径压缩:每次找爸爸的时候,顺手把路径上的节点直接挂到根节点下面。这样下次找就快了。

我曾经踩过一个坑:用Union-Find处理设备指纹数据时,忘了做路径压缩。结果数据量一上来,Find操作变成了O(n),跑了一个小时没跑完。后来加上路径压缩,10秒搞定。所以记住:路径压缩不是优化,是必需品

class UnionFind:
    def __init__(self, n):
        self.parent = list(range(n))
        self.rank = [0] * n  # 按秩合并,进一步优化

    def find(self, x):
        # 路径压缩:让x直接指向根节点
        if self.parent[x] != x:
            self.parent[x] = self.find(self.parent[x])
        return self.parent[x]

    def union(self, x, y):
        root_x = self.find(x)
        root_y = self.find(y)
        if root_x == root_y:
            return
        # 按秩合并:把矮的树挂到高的树上
        if self.rank[root_x] < self.rank[root_y]:
            self.parent[root_x] = root_y
        elif self.rank[root_x] > self.rank[root_y]:
            self.parent[root_y] = root_x
        else:
            self.parent[root_y] = root_x
            self.rank[root_x] += 1

    def get_components(self):
        # 返回每个连通分量的节点列表
        comp = {}
        for i in range(len(self.parent)):
            root = self.find(i)
            comp.setdefault(root, []).append(i)
        return list(comp.values())

避坑指南:我曾经在Union-Find里用递归实现Find,结果Python递归深度不够,直接栈溢出。后来改成迭代版本才搞定。如果你用Python,建议用while循环代替递归。

4.3 团伙发现初筛:从边到团伙

有了Union-Find,团伙初筛就简单了。流程大概是这样的:

  1. 构建关系图:把用户之间的关联(同设备、同IP、同手机号、转账关系等)作为边。
  2. 运行Union-Find:把所有有关系的用户合并到同一个连通分量里。
  3. 提取团伙:每个连通分量就是一个候选团伙。
  4. 过滤噪声:去掉那些只有两三个人的小团伙(可能是正常社交关系),只保留规模较大的团伙。

你想想看,一个正常用户最多和几十个人有强关联。但一个欺诈团伙呢?可能几百上千个账号共用同一批设备。用连通分量一筛,这些「异常大团」就全暴露了。

下面这张图展示了整个流程的逻辑:

团伙发现初筛流程 原始数据 用户ID、设备、IP、转账 构建关系图 节点=用户,边=关联 Union-Find 合并连通分量 提取团伙 每个分量=候选团伙 过滤噪声 去掉小团伙,保留大团 输出嫌疑团伙 进入人工审核或深度分析

4.4 实战中的几个关键点

光讲理论没意思,我分享几个实战中踩过的坑:

场景 问题 解决方案
设备指纹关联 一台设备可能被几百个账号使用,导致超大连通分量 设置阈值,比如同一设备关联超过50个账号才视为异常
IP关联 公共IP(如学校、公司)会把大量正常用户连在一起 对IP进行聚类,只保留「异常密集」的IP段
时间窗口 两个用户半年前共用过设备,现在早没关系了 只考虑近30天内的关联,过期边自动失效
内存爆炸 千万级节点,Union-Find的parent数组太大 用字典存储,只保存有关系的节点,稀疏图下内存节省90%

注意:连通分量分析只是初筛,不是最终结论。我见过一个案例,某个连通分量里包含了2000多个账号,看起来像团伙。结果一查,是某个电商平台的刷单群,全是真人,只是共用了一个优惠券分享链接。所以初筛之后,一定要结合其他特征(如行为序列、资金流向)做二次判断。

4.5 小结

连通分量分析,说白了就是「物以类聚,人以群分」。Union-Find算法虽然简单,但在反欺诈领域是真正的利器。我个人建议,每次拿到新数据,先跑一遍连通分量,看看有没有异常大团。这步操作成本极低,但往往能发现最明显的团伙。

嗯,今天就到这里。记住:团伙发现的第一步,永远是「找关系、画圈子」。连通分量就是帮你画圈子的那把尺子。


专注资料整理