一位同事和我正在尝试检测大型数据集中的异常情况。我们想尝试不同的算法(LOF、OC-SVM、DBSCAN 等),但我们目前正在使用 IsolationForest。
我们的数据集目前形状如下。它是每个用户每天记录的事件类型数量的计数,包含 > 300.000 条记录:
日期 | 用户 | 事件 | 数数 |
---|---|---|---|
2021 年 6 月 1 日 | user_a | 打开 | 2 |
2021 年 6 月 2 日 | user_a | 打开 | 4 |
2021 年 6 月 1 日 | 用户b | 调整 | 3 |
2021 年 6 月 2 日 | 用户b | 打开 | 5 |
2021 年 6 月 2 日 | 用户b | 删除 | 2 |
2021 年 6 月 3 日 | 用户b | 打开 | 7 |
2021 年 6 月 5 日 | 用户b | 移动 | 4 |
2021 年 6 月 4 日 | 用户 c | 调整 | 3 |
2021 年 6 月 4 日 | 用户 c | 移动 | 6 |
我们的目标是自动检测每个用户的异常事件计数。例如,通常每天记录 5 到 10 个“打开”事件的用户,计数为 400 将是异常值。我和我的同事正在讨论我们应该如何为 IsolationForest 算法准备数据集。
我们中的一个人说我们应该删除日期字段并标记其余数据 => 用整数编码所有字符串,让 IF 计算每个记录的异常值。
另一种观点认为不应该进行标签编码,因为无法用整数替换分类数据。然而,数据应该被缩放,用户列应该被删除(或设置为索引),并且事件列中的数据应该被旋转以生成更多维度(下面的示例显示了他想要做什么):
日期 | 用户 | event_Open | event_Modify | 事件_删除 | event_Move |
---|---|---|---|---|---|
2021 年 6 月 1 日 | user_a | 2 | 钠 | 钠 | 钠 |
2021 年 6 月 2 日 | user_a | 4 | 钠 | 钠 | 钠 |
2021 年 6 月 1 日 | 用户b | 钠 | 3 | 钠 | 钠 |
2021 年 6 月 2 日 | 用户b | 5 | 钠 | 2 | 钠 |
2021 年 6 月 3 日 | 用户b | 7 | 钠 | 钠 | 钠 |
2021 年 6 月 5 日 | 用户b | 钠 | 钠 | 钠 | 4 |
2021 年 6 月 4 日 | 用户 c | 钠 | 3 | 钠 | 6 |
所以我们在几点上存在分歧。我将在下面列出它们并包括我对它们的想法:
问题 | 评论 |
---|---|
标签编码 | 是必须的,并且不影响数据集的分类性质 |
缩放 | IsolationForest 本质上对缩放不敏感,因此缩放是多余的 |
删除数据列 | 日期实际上不是数据集中的一个特征,因为日期与每个用户每个事件类型的计数的异常性没有任何相关性 |
删除用户列 | 用户实际上是一个(关键)特性,不应被丢弃 |
枢轴事件列 | 这会生成一个备用矩阵,这可能是不好的做法。它还引入了数据中实际上不存在的关系(例如 user_b 在 2.6 月记录了 5 个打开事件和 2 个删除事件,但这些被认为不相关,因此不应形成单个记录) |
我很好奇你对这些问题的看法。在使用 IsolationForest 算法进行异常检测时,关于上述问题的最佳实践是什么?