均值漂移累积监测算法(MDAM):原理、命名、用途及实现
算法原理、命名与用途
1. 算法原理
该算法MDAM全称为均值漂移累积监测算法(Mean Drift Accumulation Monitor),核心原理是通过统计数据序列中超出基准值偏移范围的样本比例,识别均值突变:
- 设定基准值μ、允许偏移量p,构建正常区间[μ-p, μ+p];
- 统计超出区间的样本:上偏移(>μ+p)记为cnt_up,下偏移(<μ-p)记为cnt_down;
- 计算异常比例(up_ratio = cnt_up/总样本数、down_ratio = cnt_down/总样本数),当任一比例超过阈值k时,判定为均值突变(正数表示上突,负数表示下突)。
2. 算法命名
规范命名为MDAM(Mean Drift Accumulation Monitor,均值漂移累积监测算法),既体现“均值漂移”的检测目标,也突出“累积统计”的核心逻辑,避免与现有算法混淆。
3. 主要用途
MDAM适用于需快速检测数据序列均值突变的场景,典型用途包括:
- 工业监控:生产线温度、压力等指标的异常波动检测;
- 网络安全:识别DDoS攻击等流量突增/突减异常;
- 医疗监测:生命体征(如心率、血压)的异常漂移预警;
- 金融风控:交易金额、频次的突变模式识别;
- 环境监测:空气质量、水质指标的均值突变检测。
Python详细函数示例(优化版)
以下是结合向量化计算和动态基准更新的优化函数,支持批量数据检测和抗干扰参数调整:
import numpy as np
from typing import Union, Tuple, Optionaldef mdam_detect(data: Union[list, np.ndarray],base_window: int, # 用于计算基准值μ的历史数据窗口大小p: float, # 允许偏移量k: float = 0.8, # 异常比例阈值(0-1)detect_window: int = 100 # 每次检测的滑动窗口大小
) -> Tuple[np.ndarray, np.ndarray]:"""MDAM算法:检测数据序列中的均值突变参数:data: 输入数据序列(list或numpy数组)base_window: 计算基准值μ的历史窗口大小(如前100个数据)p: 允许的偏移量(如2倍标准差)k: 异常比例阈值(默认0.8,即80%数据超范围则判定突变)detect_window: 滑动检测窗口大小(每次检测最近N个数据)返回:突变标记数组:1表示上突,-1表示下突,0表示无突变异常比例数组:对应每个检测窗口的上突/下突比例(正数为上,负数为下)"""# 数据预处理data = np.asarray(data, dtype=np.float64)if len(data) < base_window + detect_window:raise ValueError("数据长度需大于基准窗口+检测窗口")# 初始化结果数组n_windows = len(data) - base_window - detect_window + 1突变标记 = np.zeros(n_windows, dtype=int)异常比例 = np.zeros(n_windows, dtype=np.float64)for i in range(n_windows):# 动态计算基准值μ(当前窗口前的base_window个数据的均值)base_data = data[i : i + base_window]mu = np.mean(base_data)# 待检测窗口数据detect_data = data[i + base_window : i + base_window + detect_window]# 计算上/下偏移比例up_mask = detect_data > (mu + p)down_mask = detect_data < (mu - p)cnt_up = np.sum(up_mask)cnt_down = np.sum(down_mask)total = len(detect_data)up_ratio = cnt_up / totaldown_ratio = cnt_down / total# 判定突变if up_ratio > k:突变标记[i] = 1异常比例[i] = round(up_ratio, 3)elif down_ratio > k:突变标记[i] = -1异常比例[i] = -round(down_ratio, 3)else:突变标记[i] = 0异常比例[i] = 0.0return 突变标记, 异常比例# 示例:检测模拟数据中的突变
if __name__ == "__main__":# 生成模拟数据:前500正常,中间300上突,后200下突np.random.seed(42)normal_data = np.random.normal(loc=10, scale=1, size=500) # 基准均值10up_data = np.random.normal(loc=15, scale=1, size=300) # 上突(均值15)down_data = np.random.normal(loc=5, scale=1, size=200) # 下突(均值5)data = np.concatenate([normal_data, up_data, down_data])# 调用算法检测(基准窗口100,检测窗口50,偏移量p=3,阈值k=0.7)突变标记, 异常比例 = mdam_detect(data=data,base_window=100,p=3,k=0.7,detect_window=50)# 输出结果(打印前20个和后20个窗口的检测结果)print("突变标记(1=上突,-1=下突,0=正常):")print(突变标记[:20], "...", 突变标记[-20:])print("\n异常比例:")print(异常比例[:20], "...", 异常比例[-20:])
与现有集中趋势检测算法的对比
特性 | MDAM算法 | 传统集中趋势检测(如CUSUM、Mann-Kendall) |
---|---|---|
检测目标 | 均值突变(离散、突发) | 微小漂移(CUSUM)、趋势变化(Mann-Kendall) |
参数复杂度 | 低(3个核心参数) | 中高(CUSUM需2个阈值,Mann-Kendall需多个统计量) |
计算效率 | O(n)(支持向量化) | CUSUM为O(n),Mann-Kendall为O(n²) |
方向敏感性 | 支持(区分上突/下突) | CUSUM支持,Mann-Kendall不直接支持 |
抗噪性 | 强(比例阈值过滤偶发异常) | 较弱(易受连续小波动干扰) |
实时性 | 优秀(适合嵌入式/实时系统) | 良好(CUSUM)/较差(Mann-Kendall) |
MDAM的核心优势在于参数简单、计算高效、抗噪性强,尤其适合需要快速响应突发均值突变的场景,弥补了传统算法在实时性和抗干扰性上的不足。