基于树的集成方法:孤立森林(Isolation Forest)算法在异常检测中的隔离机制与森林构建过程
题目描述
孤立森林(Isolation Forest, iForest)是一种高效的无监督异常检测算法。与基于聚类或距离度量的算法不同,其核心思想是“隔离异常”,即异常点通常数量少且与正常点差异大,因此更容易在特征空间中被随机划分快速“孤立”出来。算法通过构建多棵孤立树(iTree)组成森林,并计算每个数据点的平均路径长度来度量其异常程度。本题将详细讲解其隔离机制、孤立树的构建、森林的集成以及异常得分的计算过程。
解题过程
步骤1:核心思想与假设
孤立森林基于两个关键观察:
- 异常点稀少:它们在数据集中只占很小比例。
- 异常点属性值差异大:它们的特征值通常与正常点有显著差异(例如,数值极大或极小)。
基于此,算法提出:异常点更容易被随机划分快速隔离。想象一下,如果你要在一片森林中随机砍树以找到一只特定的动物,一只稀有且行为特异的动物(异常点)会比常见的群居动物(正常点)更快被单独隔离出来。
步骤2:构建单棵孤立树(iTree)
孤立树是一种特殊的二叉搜索树,但其构建目标不是分类或回归,而是为了快速隔离数据点。
输入: 子采样数据集 \(X'\)(大小为 \(\psi\)),当前树高度限制 \(l\)(通常设为 \(\lceil \log_2(\psi) \rceil\)),当前树高 \(h\)。
递归构建过程:
-
终止条件: 如果满足以下任一条件,则返回一个外部节点(叶子节点):
- 当前树高 \(h\) 达到预设限制 \(l\)。
- 当前节点内的数据点个数 \(|X'| \leq 1\)。
- 当前节点内的所有数据点特征值完全相同。
- 在构建过程中,当选择一个特征进行划分时,如果该特征在当前节点的最大值和最小值相等,也会停止(这通常意味着数据不可分,属于终止条件的一种情况)。
叶子节点保存该节点包含的数据点数量 \(|X'|\)。
-
随机选择特征: 从所有特征中均匀随机选择一个特征 \(q\)。
-
随机选择分割值: 在当前节点数据中,找出特征 \(q\) 的最小值 \(\min(X'[q])\) 和最大值 \(\max(X'[q])\)。在区间 \([\min, \max]\) 内均匀随机选择一个分割点 \(p\)。
-
划分子节点:
- 将特征 \(q\) 上值小于 \(p\) 的数据点分配到左子节点。
- 将特征 \(q\) 上值大于或等于 \(p\) 的数据点分配到右子节点。
(这个划分规则是原论文定义的。注意,对于恰好等于p的点,通常统一放到右子节点,这只是一个实现上的约定,对结果影响不大,因为分割点p是随机选取的。)
-
递归构建: 用左、右子节点对应的数据集,树高设为 \(h+1\),递归调用步骤1-4,分别构建左子树和右子树。
示例: 假设有一个二维数据集,有一个点A(100, 100),其他点都集中在(0,0)附近。在构建iTree时,如果在第一层就随机选择了特征q=1,并随机选择了分割点p=50,那么点A将被分到右子节点(因为100>50),而大部分点分到左子节点。点A很可能在下一层就被单独隔离到叶子节点。
关键点:
- 随机性: 特征和分割点的选择都是完全随机的,这是算法高效和非参数的关键。
- 高度限制: 限制树的高度,一方面因为异常点预期路径短,无需深究;另一方面极大地提高了构建效率,防止树过深。
步骤3:构建孤立森林
为了获得稳定、可靠的异常度量,需要集成多棵iTree。
- 子采样: 对于每棵iTree的构建,从原始数据集 \(X\) 中随机不放回地抽取 \(\psi\) 个样本(例如,\(\psi = 256\))。这有两个好处:一是降低计算和内存开销;二是子采样模拟了“稀少”的情境,有助于增强异常点在子样本中的“可识别性”。
- 并行构建: 独立构建 \(t\) 棵iTree(例如,\(t = 100\))。这些树共同组成“孤立森林”。
步骤4:计算异常得分
这是算法的核心输出。对于数据集中的任意一个点 \(x\),其异常得分通过在所有iTree中的平均路径长度来定义。
-
计算点 \(x\) 在单棵iTree中的路径长度 \(h(x)\):
- 从根节点开始,根据每层节点的划分规则(特征q和分割点p),递归地走到叶子节点。
- 路径长度 \(h(x)\) 定义为从根节点到叶子节点所经过的边的数量。例如,根节点深度为0,其子节点深度为1,依此类推。
-
计算平均路径长度: 计算点 \(x\) 在所有 \(t\) 棵iTree中路径长度的平均值 \(E(h(x))\)。
-
计算归一化路径长度:
为了比较不同子采样大小下的路径长度,需要将其标准化。算法给出了一个在随机树(BST)中搜索不成功时的平均路径长度的估计公式 \(c(\psi)\):
\[ c(\psi) = \begin{cases} 2H(\psi - 1) - 2(\psi - 1)/\psi & \text{for } \psi > 2,\\ 1 & \text{for } \psi = 2,\\ 0 & \text{otherwise} \end{cases} \]
其中 $ H(i) $ 是调和数,可用 $ \ln(i) + 0.5772156649 $(欧拉常数)近似。$ c(\psi) $ 是给定样本数 $ \psi $ 时,路径长度的“基准值”。
- 计算最终异常得分 \(s(x)\):
\[ s(x) = 2^{-\frac{E(h(x))}{c(\psi)}} \]
* **得分解释**:
* 当 $ E(h(x)) \to 0 $ 时,$ s \to 1 $:路径极短,极有可能是异常点。
* 当 $ E(h(x)) \to c(\psi) $ 时,$ s \to 0.5 $:路径长度接近随机划分的平均长度,该点与大部分点无异。
* 当 $ E(h(x)) \to \psi-1 $ 时,$ s \to 0 $:路径极长,很可能是正常的内点(inlier)。
* **决策**: 通常设定一个阈值(如0.6或0.7)。得分高于阈值的点被判定为异常点。阈值的选择可以根据假阳性/假阴性的容忍度进行调整,或通过验证集确定。
总结
孤立森林算法通过巧妙利用“异常点易隔离”的直觉,构建大量随机的、有限深度的二叉划分树(iTree)。通过计算数据点在这些树中的平均路径长度,并将其标准化为介于0到1之间的异常得分,有效地区分出异常点。其核心优势在于线性时间复杂度和低内存需求,尤其适合处理大规模高维数据,且不依赖于距离或密度度量,对数据分布没有强假设。整个过程从随机划分(构建iTree)到集成平均(构建森林)再到分数归一化(计算得分),逻辑清晰,计算高效。