4. Isolation Forest核心思想
在异常交易检测中,我们面对的数据往往极度不平衡:正常交易占绝大多数,欺诈、洗钱、盗刷等异常样本稀少且形态多变。传统监督模型需要大量标注样本,而Isolation Forest(孤立森林)走了一条完全不同的路——它不学习“正常长什么样”,而是直接学习“怎样把每个点快速孤立出来”。这一节我们把它的四个核心概念讲透:孤立机制、随机划分、路径长度、异常分数计算直觉。
一、孤立机制:异常点更容易被“切”出来
孤立森林的基本假设非常朴素:异常点是少数且与众不同的,因此它们更容易被随机划分快速隔离。想象你在一张桌子上撒了很多正常交易的点,它们密集地聚在一起;而异常交易的点往往远离主群体,或者落在稀疏区域。现在你随机选一个特征、随机选一个切分阈值,把数据一分为二。对于密集区域,你需要切很多刀才能把某个正常点单独隔离;而对于远离群体的异常点,可能一两刀就把它单独切出来了。
这就是“孤立”的含义:孤立一个样本所需的划分次数越少,它越可能是异常。注意,这里没有用到任何标签,也没有假设数据服从某种分布,完全由随机划分的几何效果驱动。
二、随机划分:一棵孤立树的生长过程
孤立森林由多棵“孤立树”(iTree)组成。每棵树的构建过程如下:
- 从训练集中随机抽取一个子样本(通常不需要全部数据,子采样反而能增强随机性并降低淹没效应)。
- 随机选择一个特征。
- 在该特征当前取值范围内,随机选择一个切分点。
- 按切分点把数据分成左右两支。
- 递归执行,直到满足停止条件:节点只剩一个样本,或所有样本取值相同,或达到树的最大深度。
与决策树不同,孤立树不追求信息增益最大,也不做剪枝,它完全随机。正是这种随机性,使得单棵树可能不稳定,但多棵树平均后,异常点的“短路径”特征会稳定显现。
# 孤立树构建伪代码
function iTree(X, depth, max_depth):
if len(X) <= 1 or depth >= max_depth:
return LeafNode(size=len(X))
feature = random_choice(features)
split = random_uniform(min(X[feature]), max(X[feature]))
X_left = X[X[feature] < split]
X_right = X[X[feature] >= split]
return InternalNode(feature, split,
iTree(X_left, depth+1, max_depth),
iTree(X_right, depth+1, max_depth))
三、路径长度:异常分数的原材料
当一棵孤立树建好后,我们把一个样本从根节点走到叶子节点,经过的边数就是它的路径长度。但这里有一个细节:如果样本落在叶子节点时,该叶子节点里还有多个样本(因为达到最大深度或取值相同而停止),我们需要对路径长度做一个修正。常用做法是加上一个基于叶子节点样本数的调整项,使得路径长度更平滑。
多棵树会给出多个路径长度,取平均后得到该样本的平均路径长度 E(h(x))。平均路径长度越短,样本越容易被孤立,异常可能性越高。
为了把路径长度转换成一个可比较的分数,孤立森林引入了一个归一化因子:给定样本数 n,随机二叉搜索树中失败查找的平均路径长度 c(n)。它的近似公式为:
c(n) = 2 * (ln(n - 1) + 0.5772156649) - 2 * (n - 1) / n
其中 0.5772156649 是欧拉常数。当 n 较大时,c(n) 增长缓慢,起到尺度归一化的作用。
四、异常分数计算直觉
异常分数 s(x, n) 的定义为:
s(x, n) = 2 ^ ( - E(h(x)) / c(n) )
这个公式的直觉可以这样理解:
- 如果平均路径长度 E(h(x)) 很短,指数部分接近 0,s 接近 1,表示高度异常。
- 如果平均路径长度 E(h(x)) 接近 c(n),指数部分接近 -1,s 接近 0.5,表示难以判断。
- 如果平均路径长度 E(h(x)) 很长,指数部分为较大的负数,s 接近 0,表示非常正常。
因此,异常分数天然落在 0 到 1 之间,且以 0.5 为大致分界。实际业务中,我们通常不直接卡 0.5,而是根据历史告警量、人工审核成本等,选取一个更高的阈值,比如 0.65 或 0.7,只把最异常的 top-k 交易送进人工审核。
| 平均路径长度 | 异常分数 s | 业务含义 | 建议动作 |
|---|---|---|---|
| 很短 | 接近 1 | 极易被孤立,高度可疑 | 立即拦截或人工审核 |
| 较短 | 0.6 ~ 0.8 | 较可疑 | 进入观察名单或二次验证 |
| 中等 | 0.4 ~ 0.6 | 难以判断 | 结合规则引擎综合判断 |
| 较长 | 接近 0 | 与群体一致,正常 | 放行 |
五、案例场景:信用卡交易中的孤立森林
假设我们有一批信用卡交易,特征包括交易金额、交易时间、商户类别、距上次交易时间间隔等。正常交易集中在白天、金额中等、商户类别稳定;而盗刷可能发生在凌晨、金额异常大、商户类别突变。孤立森林在随机划分时,盗刷交易因为金额或时间维度上的“离群”,往往在很浅的深度就被单独切出,平均路径长度显著短于正常交易。
实际部署时,我们通常先对特征做标准化或归一化,避免量纲差异导致随机切分偏向某些特征。同时,子采样比例和树的数量是两个关键参数:树越多,分数越稳定,但计算成本上升;子采样越小,单棵树越轻,但可能丢失全局结构。经验上,树的数量取 100 到 300,子采样取 256 或 512,在多数交易场景下已经足够。
六、常见误区与复盘
误区二:认为异常分数越高越好。如果阈值设得太高,会漏掉大量真实异常;设得太低,人工审核会被淹没。必须结合业务成本曲线来定阈值。
误区三:忽略特征尺度。随机切分是在特征取值范围内均匀选点,如果某个特征数值范围极大,它会主导切分过程,导致其他特征失效。
误区四:用全量数据训练。全量数据会让正常点过于密集,异常点被“淹没”,子采样反而能提升异常点的可分离性。
复盘时,建议把每笔交易的异常分数、平均路径长度、以及它在各棵树中的路径长度分布都记录下来。如果某笔交易分数很高但路径长度波动很大,说明它只在少数树上被孤立,可能是噪声而非真实异常。结合路径长度的方差,可以进一步过滤掉不稳定的告警。
总结一下:孤立森林的核心就是“随机切、快速孤立、路径短则异常”。它不依赖标签、计算高效、对高维稀疏数据友好,非常适合作为异常交易检测的第一道无监督防线。理解孤立机制、随机划分、路径长度和异常分数这四个概念,你就掌握了它的全部直觉。