如何进行分组异常检测?

数据挖掘 机器学习 算法 异常检测
2022-03-06 09:56:21

我目前有大量数据流,有诸如 HTTP 请求/响应代码(200、404、500 等)之类的点。本质上,我想在收到太多不是 200 的信号时执行异常检测。这意味着要分析的信号取决于数据点的分组(即,表明发送了 404 的单个数据点还不够好,只有在时间上靠近的一组 404 才有意义)。

有没有好的算法/方法来解决这个问题?我之前考虑过使用之前代码的移动窗口计数器并以此为基础,但我觉得例如窗口大小是非常主观的,我不知道如何调整它。

2个回答

查看速率而不是单个请求。

可能存在“通常”的不成功代码频率。如果你观察到一个不寻常的频率,你就有一个事件。

如果您想要一个简单的算法:假设您观察到的比率远高于 5%,则您想发出警报。

要添加一些余量,将其增加到 0.1,并且阈值约为 10 个错误“太多”。

使用计数器 x,最初为 0,使用更新

xt+1{max(0,xt0.1)if request successfulxt+1if request causes an error
如果此值达到 10,则发出警报。

似乎您的解决方案不必在数据分析的上下文中包含“异常检测”,但可以通过假设数据的时间顺序通过向量迭代更容易解决(您没有提到任何其他功能,所以问题是一维的)。

我会建议以下方法:

1) 遍历向量,如果连续发现 N > 阈值非 2xx 响应,则标记“簇”的起始索引。

    vector<int> status, indices;
    int threshold = 10, counter = 0, flag = 0;
    status = read_data("data.csv");
    for(int i = 0; i < status.size(); i++) {
            if (status[i] < 200 && status[i] > 299) {
                    if (++counter >= threshold && !flag) {
                            indices.push_back(i - counter);
                            flag = 1;
                    }
            } else {
                    counter = 0;
                    flag = 0;
            }
    }
    return indices;

2)一旦你跨越了一些非 2xx 的例子,将权重初始化为,比如说 0.0(零)。对于每个新的负例,减去,例如 0.2,对于正例,添加 0.05 或其他值,如果最终低于 -2.0 或高于 2.0,请重置过程,如果它小于 -2.0,则返回起始索引。你可以玩给定的数字。

3)一些更复杂的策略?

但是,是的,您的解决方案不必包括机器,尝试从更简单的事情开始,它将引导您朝着正确的方向前进。