EWMA、加权平均与一次低通滤波的对比与选型

文章目录

EWMA、加权平均与一次低通滤波的对比与选型

三者解决的共同问题

三者都用于把"抖动/噪声较大"的观测序列变成更稳定的信号,从而更适合做展示、阈值判断、控制调节等。其共同代价是:越平滑,越容易产生滞后(变化被延迟反映)。(维基百科)


用"权重形状"理解原理与异同点

加权平均

对一组样本按权重求和(一次性计算),不要求时间连续,也不内置"上一时刻状态"的概念:

y = ∑ i = 0 N − 1 w i x i ∑ i = 0 N − 1 w i \] \[ y=\\frac{\\sum_{i=0}\^{N-1} w_i x_i}{\\sum_{i=0}\^{N-1} w_i} \] \[y=∑i=0N−1wi∑i=0N−1wixi

  • 权重 (w_i) 可任意设计(线性、分段、业务权重等)
  • 需要拿到整组样本(或至少拿到一个窗口内的样本)

移动平均/加权移动平均(FIR 思路)

在固定窗口内做平均或加权平均,窗口之外权重为 0,因此是典型 FIR(有限冲激响应) :冲激响应在有限长度后严格为 0。(维基百科)

"移动平均滤波"是最典型的 FIR 例子之一,用于降低随机噪声。(analog.com)

FIR 的通用差分方程

长度为 (M) 的因果 FIR 滤波器可用"有限卷积"表示:

y \[ n \] = ∑ k = 0 M − 1 b k , x \[ n − k \] \] \[ y\[n\]=\\sum_{k=0}\^{M-1} b_k,x\[n-k\] \] \[y\[n\]=k=0∑M−1bk,x\[n−k\]

其中 ( b 0 , ... , b M − 1 ) ({b_0,\dots,b_{M-1}}) (b0,...,bM−1) 就是 FIR 系数(也等同于有限冲激响应 ( h [ k ] ) (h[k]) (h[k]))。

EWMA(指数加权移动平均)

EWMA 采用递推更新,只保留一个状态值,用指数衰减方式"记住历史":

S t = α x t + ( 1 − α ) S t − 1 \] \[ S_t=\\alpha x_t+(1-\\alpha)S_{t-1} \] \[St=αxt+(1−α)St−1

NIST 的"简单指数平滑(Single Exponential Smoothing)"给出了同类递推形式,并直接把平滑序列称为 EWMA。(NIST)

一次低通滤波(First-order Low-pass)

在离散实现中,一次低通常写为:

y t = y t − 1 + α ( x t − y t − 1 ) ⇒ y t = α x t + ( 1 − α ) y t − 1 \] \[ y_t=y_{t-1}+\\alpha(x_t-y_{t-1}) \\Rightarrow y_t=\\alpha x_t+(1-\\alpha)y_{t-1} \] \[yt=yt−1+α(xt−yt−1)⇒yt=αxt+(1−α)yt−1

该差分形式与 EWMA 在数学上等价,只是命名与参数语义更偏"滤波/控制"。一些工程资料也直接将该类指数滤波称为 EWMA/指数平滑,并指出其是"一阶滞后/一阶惯性"的离散等价。(gregstanleyandassociates.com)


核心差异总结

维度 加权平均 (加权)移动平均 FIR EWMA 一次低通
结构 一次性求和 有限窗口卷积 递推 + 反馈 递推 + 反馈
记忆 仅样本集合 严格只看最近 N 个 指数衰减,无"硬截断" 与 EWMA 等价
存储 需要样本集合 需保存 N 个样本 仅 1 个状态 仅 1 个状态
更新开销 O(N) 通常 O(N) O(1) O(1)
响应/滞后 取决于权重 窗口越大越滞后 (\alpha) 越小越滞后 (\alpha)/(\tau) 越大越滞后
稳定性 非滤波器概念 FIR 天然稳定 IIR 取决于系数 IIR 取决于系数
  • FIR 的"有限冲激响应/有限记忆"特征:窗口外影响严格为 0。(维基百科)
  • IIR 的"无限冲激响应"来自对历史输出的依赖(反馈),冲激响应理论上不会在有限时间完全变为 0。(维基百科)
  • FIR 通常具有更直观的稳定性特征(讲义中给出 FIR 稳定性结论)。(ETH Zürich)

优劣势与使用场景

加权平均

优势

  • 权重可完全按业务语义设计(例如对不同来源、不同质量样本赋权)
  • 输出解释直观:就是"按权重的平均"

劣势

  • 流式场景需要缓存样本或维护窗口,无法天然 O(1) 在线更新
  • 需要明确"平均对象是什么"(一批样本、一个窗口、一个周期)

适用场景

  • 分数融合、指标合成、一次性评估(离线/批处理)
  • 明确知道要综合的样本集合(例如一次请求内多个子结果合并)

加权移动平均(FIR)

优势

  • "只看最近 N 个"的语义清晰,窗口之外完全遗忘
  • 对某些 FIR 结构可获得线性相位等性质(在信号处理里常见)

劣势

  • 需要保存 N 个样本;N 大时内存与计算成本明显
  • 对突变同样会滞后,且窗口越大滞后越明显

适用场景

  • 需要严格窗口定义(最近 60 秒、最近 100 次)
  • 对滤波器性质(如线性相位)有明确要求的 DSP 场景
  • 更新频率较低或窗口较小的在线平滑

EWMA

优势

  • 只维护一个状态,单次更新 O(1),非常适合热路径/实时路径
  • 对噪声抑制强,且"近期样本权重更大"符合很多趋势判断需求(指数衰减)

劣势

  • 没有"硬窗口边界",旧数据影响只会渐近变小而非突然归零
  • 平滑引入滞后;(\alpha) 选得过小会导致对变化过迟钝

适用场景

  • 压力/拥塞/忙碌度趋势(队列长度、重试率、丢包率、负载)
  • 动态控制:用平滑后的信号调节并发度、批量大小、速率
  • 指标展示:吞吐、延迟、利用率等需要更稳定的曲线(指数平滑常被视为低通去高频噪声)。(维基百科)

一次低通滤波(与 EWMA 等价)

优势

  • 与 EWMA 同样是 O(1) 状态、O(1) 更新
  • 参数可以用"时间常数 (\tau)"表达,便于在采样间隔变化时保持语义一致(按真实时间衰减)

劣势

  • 与 EWMA 相同:必然滞后
  • 若采样间隔变化但仍固定 ( α ) (\alpha) (α),滤波语义会漂移(需要时间归一化)

适用场景

  • 传感器信号、控制量平滑(工程上常以"一阶惯性/一阶低通"描述)
  • 采样周期不恒定的事件驱动更新(用 ( τ ) + ( Δ t ) (\tau) + (\Delta t) (τ)+(Δt) 动态算系数)

示例 C 代码

1) 加权平均(一次性计算)

c 复制代码
#include <stddef.h>

double weighted_average(const double *x, const double *w, size_t n) {
    double num = 0.0;
    double den = 0.0;

    for (size_t i = 0; i < n; i++) {
        num += w[i] * x[i];
        den += w[i];
    }

    return (den == 0.0) ? 0.0 : (num / den);
}

2) 加权移动平均(FIR,线性权重示例)

  • 最新样本权重最大,越旧权重越小
  • 需要环形缓冲区保存窗口内样本
c 复制代码
#include <stddef.h>

typedef struct {
    double *buf;
    size_t cap;   // window size
    size_t idx;   // next write position
    size_t len;   // current filled length
} wma_t;

void wma_push(wma_t *w, double x) {
    w->buf[w->idx] = x;
    w->idx = (w->idx + 1) % w->cap;
    if (w->len < w->cap) w->len++;
}

double wma_eval_linear(const wma_t *w) {
    if (w->len == 0) return 0.0;

    double num = 0.0, den = 0.0;

    // newest -> oldest
    for (size_t k = 0; k < w->len; k++) {
        size_t pos = (w->idx + w->cap - 1 - k) % w->cap;
        double weight = (double)(w->len - k); // len, len-1, ..., 1
        num += weight * w->buf[pos];
        den += weight;
    }
    return num / den;
}

3) EWMA(递推,固定 ( α ) (\alpha) (α))

NIST 的简单指数平滑属于同类递推结构。(NIST)

c 复制代码
typedef struct {
    double s;
    int initialized;
} ewma_t;

double ewma_update(ewma_t *e, double x, double alpha) {
    // alpha in (0, 1]
    if (!e->initialized) {
        e->s = x;
        e->initialized = 1;
        return e->s;
    }
    e->s = alpha * x + (1.0 - alpha) * e->s;
    return e->s;
}

4) 一次低通(时间常数 ( τ ) (\tau) (τ) 版本,采样间隔可变)

该写法常用于把"滤波强度"用时间常数表达,并按 ( Δ t ) (\Delta t) (Δt) 做指数衰减;工程资料也将其视为离散的一阶滞后/指数滤波。(gregstanleyandassociates.com)

c 复制代码
#include <math.h>
#include <stdint.h>

typedef struct {
    double y;
    uint64_t last_ts;   // timestamp, same unit as tau
    int initialized;
} lp1_t;

// now_ts 与 tau 使用同一时间单位(例如都用 ns 或都用 ms)
// 编译时若使用 GCC/Clang,可能需要链接 -lm
double lowpass1_update(lp1_t *f, double x, uint64_t now_ts, double tau) {
    if (!f->initialized) {
        f->y = x;
        f->last_ts = now_ts;
        f->initialized = 1;
        return f->y;
    }

    uint64_t dt_u = now_ts - f->last_ts;
    double dt = (double)dt_u;

    // alpha = 1 - exp(-dt/tau)
    double alpha = 1.0 - exp(-dt / tau);

    f->y = alpha * x + (1.0 - alpha) * f->y;
    f->last_ts = now_ts;
    return f->y;
}

选型速记

  • 必须严格只看最近 N 个样本 :选(加权)移动平均(FIR),窗口语义明确。(维基百科)
  • 必须 O(1) 在线更新,且只需要趋势 :选 EWMA / 一次低通(本质等价)。(NIST)
  • 采样间隔不稳定但仍想保持"按时间"衰减语义 :选"一次低通的 (\tau)+(\Delta t)"动态系数版本。(gregstanleyandassociates.com)
相关推荐
Hello_Embed2 小时前
STM32F030CCT6 开发环境搭建
笔记·stm32·单片机·嵌入式·freertos
longxibo2 小时前
【Ubuntu datasophon1.2.1 二开之六:解决CLICKHOUSE安装问题】
大数据·linux·clickhouse·ubuntu
何中应2 小时前
Jenkins如何注册为CentOS7的一个服务
linux·运维·jenkins·开发工具
yttandb2 小时前
linux的基础命令
linux·运维·服务器
之歆2 小时前
Linux 系统安装、故障排除、sudo、加密、DNS 与 Web 服务整理
linux·运维·前端
以太浮标2 小时前
华为eNSP综合实验之- 通过SSH远程登陆设备
服务器·网络·ssh
D_C_tyu2 小时前
HTML | 简易水排序游戏求解器 第二版
游戏
蒸蒸yyyyzwd2 小时前
os 计网学习笔记
笔记·学习
Katecat996633 小时前
织物疵点检测与分类:Cascade-Mask-RCNN_RegNetX实验笔记
笔记·数据挖掘