跳转到内容

滑动窗口异常检测

滑动窗口异常检测

学习目标

读完本章后,你将能够:

  • 理解基于均值-标准差的滑动窗口异常检测算法
  • 实现时间序列的分组统计与多维度检测
  • 设计峰值冷却间隔避免重复告警
  • 处理冷启动问题和窗口大小选择

核心概念

异常检测的本质

异常检测回答一个简单问题:当前值是否显著偏离了正常模式

算法步骤

对于每个新到的数据点 x_t:
1. 将 x_t 加入滑动窗口
2. 计算窗口内数据的均值 μ 和标准差 σ
3. 如果 x_t > μ + N × σ:
标记为异常
4. 清理窗口中过期的数据点

标准差倍数(N)的选择

N 值灵敏度误报率适用场景
2较高(约 5%)快速检测、允许误报
3低(约 0.3%)平衡检测
4+极低只关注极端异常

实现细节

均值与标准差的在线计算

def stats_for(data, skip_last: 0)
data = data[0...(data.length - skip_last)]
length = data.length.to_f
return [0, 0] if length == 0
# 计算均值
mean = data.sum / length
# 计算标准差(总体标准差)
variance = data.sum { |v| (v - mean)**2 } / length
std_dev = Math.sqrt(variance)
[mean, std_dev]
end

skip_last 的作用:检测当前值是否异常时,排除当前值本身——用历史数据建立”正常”基线,再判断当前值是否偏离。

滑动窗口管理

窗口清理策略:

def cleanup(group)
newest_time = memory['data'][group].last.last
cutoff = newest_time - window_duration
memory['data'][group].reject! { |_value, time| time <= cutoff }
end

高级功能

分组检测

当事件流包含多个维度的数据时,按维度分组独立检测:

分组的价值:不同组可能有不同的”正常”基线。北京的温度在 35°C 可能是正常的,而哈尔滨的 35°C 就是异常。

峰值冷却

冷却策略:在峰值发生后的一段时间内不再检测新峰值,避免连续告警。

def check_for_peak(group, event)
# 如果上次峰值距今小于冷却间隔,跳过检测
if memory['peaks'][group].last < event.created_at.to_i - peak_spacing
# 执行检测...
end
end

冷启动保护

def check_for_peak(group, event)
# 数据点不足时不检测,避免冷启动误报
return if memory['data'][group].length <= min_events
# 执行检测...
end
min_events行为
4(默认)至少 4 个数据点后才开始检测
10+更保守,需要更多历史数据

陷阱与对策

陷阱一:非正态分布

均值-标准差方法假设数据近似正态分布。对于偏态分布(如请求延迟),误报率会显著上升。

对策

  • 使用对数变换(log(x))将偏态分布转换为近似正态
  • 改用百分位方法(如 P99)替代均值-标准差
  • 使用 ESD(Extreme Studentized Deviate)检验处理多异常值问题

陷阱二:窗口大小选择

窗口太小窗口太大
基线不稳定,波动大对变化的”正常”模式反应迟钝
误报率高漏报率高

经验法则:窗口应覆盖至少一个完整的周期(如 24 小时、7 天),以便捕捉周期性变化。

陷阱三:多异常值问题

当窗口内存在多个异常值时,它们会拉高均值和标准差,导致后续异常无法被检测。

对策

  • 峰值冷却间隔限制已检测峰值的影响
  • 使用 skip_last: 1 排除当前值再计算统计量
  • 使用迭代方法:检测并移除最显著异常,重新计算

设计取舍

均值-标准差 vs 其他方法

方法复杂度适用分布多异常值在线计算
均值-标准差O(n)近似正态
中位数-MADO(n)任意
百分位O(n log n)任意
ESDO(k×n)近似正态部分
Isolation ForestO(n log n)任意

均值-标准差的优势:实现简单、计算高效、对于大多数 Agent 场景(Twitter 提及量、API 调用频率等)足够有效

滑动窗口 vs 指数衰减

维度滑动窗口指数衰减
内存O(窗口大小)O(1)
响应速度快(旧数据突然消失)平滑(旧数据逐渐减弱)
实现复杂度
适用场景有明确周期性的数据无固定周期的数据

参考来源