第四章:关联规则挖掘与审计应用
4.1 从购物篮到审计线索
关联规则挖掘,说白了就是找「共现关系」。
超市里发现「买尿布的人大概率也会买啤酒」,这就是经典的关联规则。但在金融审计里,我们找的不是尿布和啤酒,而是「同一笔交易里,A账户和B账户同时出现」或者「某个时间段内,供应商和客户IP地址相同」。
我刚开始做审计数据挖掘时,觉得这玩意儿挺玄乎。直到有一次,我用Apriori算法跑了一批采购数据,发现某个供应商和某个审批人的名字频繁出现在同一批订单里——频率高到不正常。后来一查,果然有利益输送。
嗯,从那以后,我再也不敢小看这个「找规律」的算法了。
核心思想:如果两个事件同时发生的概率,远高于它们各自发生的概率的乘积,那这里面很可能有猫腻。
4.2 Apriori算法原理:三步走
Apriori算法的逻辑其实不复杂。我习惯把它拆成三步:
- 找频繁项集——找出所有出现次数超过阈值的组合
- 剪枝——去掉那些「子集不频繁」的超集
- 生成规则——从频繁项集中提取强关联规则
你想想看,如果「A和B同时出现」的次数很少,那「A、B、C同时出现」的次数只会更少。所以我们可以先砍掉那些不频繁的项,减少计算量。这就是Apriori的「先验原理」。
我曾经在项目里遇到过数据量特别大的情况,几百万条交易记录。如果不做剪枝,算法跑一天都出不来结果。剪枝之后,半小时搞定。
避坑指南:我曾经把支持度阈值设得太低,结果跑出来几千条规则,根本看不过来。后来我学乖了——先设一个较高的阈值,跑出结果后再逐步降低。这样效率高得多。
4.3 三个关键指标
关联规则用三个指标来衡量:
| 指标 | 公式 | 含义 |
|---|---|---|
| 支持度 | P(A∩B) | A和B同时出现的概率 |
| 置信度 | P(B|A) | 出现A的情况下,B出现的概率 |
| 提升度 | P(B|A)/P(B) | A对B出现概率的提升程度 |
提升度大于1,说明A和B正相关。小于1,负相关。等于1,独立。
在审计场景里,我一般重点关注提升度大于3的规则。为什么?因为正常业务里,两个不相关的事件同时发生的概率很低。如果提升度很高,说明背后可能有某种「人为安排」。
4.4 虚假交易识别:实战案例
虚假交易有个典型特征:交易模式过于「完美」。
正常企业的交易是有波动的。但虚假交易往往呈现出高度规律性——比如每个月固定日期、固定金额、固定对手方。用关联规则一跑,这些「完美组合」就会现形。
我处理过一个案例:某公司的采购数据里,「供应商A」和「物料编码B」的关联规则支持度高达0.85,置信度0.95。但其他供应商和物料之间,支持度普遍在0.1以下。这明显不正常——正常采购应该是分散的。后来查实,供应商A和采购经理是亲戚关系。
注意:关联规则只能告诉你「有关系」,不能告诉你「有罪」。高关联度可能是巧合,也可能是正常业务模式。需要结合其他证据综合判断。
4.5 利益输送识别:关键模式
利益输送在数据层面有几个典型模式:
- 人员-供应商关联:员工和供应商出现在同一批交易中
- IP地址重合:不同公司的操作IP相同
- 时间模式异常:审批和付款时间高度集中
- 金额模式固定:刚好卡在审批权限上限
我个人习惯的做法是:先把这些维度做特征工程,然后跑关联规则。比如把「员工ID」「供应商ID」「交易时间」「交易金额」四个字段做笛卡尔积,生成候选集。然后看哪些组合频繁出现。
举个例子:如果「员工A」和「供应商B」同时出现的次数,占所有交易次数的30%以上,而其他员工和供应商的组合都在5%以下——这就是一个危险信号。
4.6 Python实战:关联规则挖掘
下面是一个完整的实战代码。我用的是mlxtend库,它封装了Apriori算法,用起来很方便。
import pandas as pd
from mlxtend.frequent_patterns import apriori, association_rules
# 加载交易数据
# 假设数据格式:每一行是一笔交易,每一列是一个商品/维度
df = pd.read_csv('transaction_data.csv')
# 转换为one-hot编码
# 比如:交易ID, 商品A, 商品B, 商品C
# 1, 1, 0, 1 表示这笔交易包含A和C
# 运行Apriori算法
frequent_itemsets = apriori(
df,
min_support=0.05, # 最小支持度
use_colnames=True
)
# 生成关联规则
rules = association_rules(
frequent_itemsets,
metric="lift", # 按提升度排序
min_threshold=1.5
)
# 筛选高提升度的规则
high_lift_rules = rules[rules['lift'] > 3]
# 输出结果
print(high_lift_rules[['antecedents', 'consequents', 'support', 'confidence', 'lift']])
实战技巧:我建议先跑一个小的样本数据,调好参数再全量跑。不然数据量一大,Apriori的计算量是指数级的。另外,记得把结果导出到Excel,方便审计人员查看。
4.7 知识体系总览
下面这张图,是我自己总结的关联规则挖掘在审计中的应用框架。你可以把它当作一个检查清单:
4.8 几点补充建议
最后,说几个我踩过的坑:
- 数据清洗很重要。有一次我跑出来的规则全是「NULL」和「未知」的组合——因为数据没做空值处理。白白浪费了半天时间。
- 不要只看提升度。提升度高但支持度低的规则,可能是偶然事件。我一般要求支持度至少0.01,置信度至少0.5。
- 结果需要业务验证。算法只是工具,最终判断还是要靠审计人员的经验。我曾经跑出一条「采购经理和某供应商」的高关联规则,结果人家是正常的长期合作——虚惊一场。
关联规则挖掘,说白了就是帮你在海量数据里「找不同」。那些不符合常规模式的关系,往往就是审计线索的起点。
公众号:蓝海资料掘金营,微信deep3321