1. 指数加权平均的定义
指数加权平均是一种对时间序列数据进行平滑处理的方法。它的核心思想是对历史数据赋予指数衰减的权重,最近的观测值权重较大,而较早的观测值权重逐渐减小。
假设有一系列观测值 x 1 , x 2 , ... , x t x_1, x_2, \dots, x_t x1,x2,...,xt,希望计算这些数据的指数加权平均值 v t v_t vt。
2. 递推公式的推导
2.1 基本形式
指数加权平均的递推公式定义为:
v t = β ⋅ v t − 1 + ( 1 − β ) ⋅ x t v_t = \beta \cdot v_{t-1} + (1 - \beta) \cdot x_t vt=β⋅vt−1+(1−β)⋅xt
其中:
- v t v_t vt 是当前时刻的指数加权平均值。
- v t − 1 v_{t-1} vt−1 是上一时刻的指数加权平均值。
- x t x_t xt 是当前时刻的观测值。
- β \beta β 是衰减率,通常取值在 [ 0 , 1 ) [0, 1) [0,1) 之间。
2.2 递推展开
假设初始值 v 0 = 0 v_0 = 0 v0=0,则有:
v 1 = β ⋅ v 0 + ( 1 − β ) ⋅ x 1 = ( 1 − β ) ⋅ x 1 v 2 = β ⋅ v 1 + ( 1 − β ) ⋅ x 2 = β ⋅ ( 1 − β ) ⋅ x 1 + ( 1 − β ) ⋅ x 2 v 3 = β ⋅ v 2 + ( 1 − β ) ⋅ x 3 = β 2 ⋅ ( 1 − β ) ⋅ x 1 + β ⋅ ( 1 − β ) ⋅ x 2 + ( 1 − β ) ⋅ x 3 ⋮ v t = ( 1 − β ) ⋅ x t + β ⋅ ( 1 − β ) ⋅ x t − 1 + β 2 ⋅ ( 1 − β ) ⋅ x t − 2 + ⋯ + β t − 1 ⋅ ( 1 − β ) ⋅ x 1 \begin{aligned} v_1 &= \beta \cdot v_0 + (1 - \beta) \cdot x_1 = (1 - \beta) \cdot x_1 \\ v_2 &= \beta \cdot v_1 + (1 - \beta) \cdot x_2 = \beta \cdot (1 - \beta) \cdot x_1 + (1 - \beta) \cdot x_2 \\ v_3 &= \beta \cdot v_2 + (1 - \beta) \cdot x_3 = \beta^2 \cdot (1 - \beta) \cdot x_1 + \beta \cdot (1 - \beta) \cdot x_2 + (1 - \beta) \cdot x_3 \\ &\ \, \vdots \\ v_t &= (1 - \beta) \cdot x_t + \beta \cdot (1 - \beta) \cdot x_{t-1} + \beta^2 \cdot (1 - \beta) \cdot x_{t-2} + \dots + \beta^{t-1} \cdot (1 - \beta) \cdot x_1 \end{aligned} v1v2v3vt=β⋅v0+(1−β)⋅x1=(1−β)⋅x1=β⋅v1+(1−β)⋅x2=β⋅(1−β)⋅x1+(1−β)⋅x2=β⋅v2+(1−β)⋅x3=β2⋅(1−β)⋅x1+β⋅(1−β)⋅x2+(1−β)⋅x3 ⋮=(1−β)⋅xt+β⋅(1−β)⋅xt−1+β2⋅(1−β)⋅xt−2+⋯+βt−1⋅(1−β)⋅x1
从展开式中可以看出, v t v_t vt 是历史观测值 x 1 , x 2 , ... , x t x_1, x_2, \dots, x_t x1,x2,...,xt 的加权和,权重系数为 ( 1 − β ) ⋅ β t − i (1 - \beta) \cdot \beta^{t-i} (1−β)⋅βt−i,其中 i i i 是观测值的时间步。
2.3 权重分析
权重系数 ( 1 − β ) ⋅ β t − i (1 - \beta) \cdot \beta^{t-i} (1−β)⋅βt−i 满足以下性质:
- 权重衰减 :随着时间步 i i i 的减小(即观测值越早),权重 β t − i \beta^{t-i} βt−i 越小。
- 权重归一化 :所有权重之和为 1,即:
∑ i = 1 t ( 1 − β ) ⋅ β t − i = 1 − β t \sum_{i=1}^t (1 - \beta) \cdot \beta^{t-i} = 1 - \beta^t i=1∑t(1−β)⋅βt−i=1−βt
这是因为:
∑ i = 1 t β t − i = 1 − β t 1 − β \sum_{i=1}^t \beta^{t-i} = \frac{1 - \beta^t}{1 - \beta} i=1∑tβt−i=1−β1−βt
因此:
∑ i = 1 t ( 1 − β ) ⋅ β t − i = ( 1 − β ) ⋅ 1 − β t 1 − β = 1 − β t \sum_{i=1}^t (1 - \beta) \cdot \beta^{t-i} = (1 - \beta) \cdot \frac{1 - \beta^t}{1 - \beta} = 1 - \beta^t i=1∑t(1−β)⋅βt−i=(1−β)⋅1−β1−βt=1−βt
3. 偏差校正
3.1 偏差的来源
在初始阶段( t t t 较小时),由于 v 0 = 0 v_0 = 0 v0=0,递推公式中的 v t v_t vt 会偏向 0,导致估计值偏低。这是因为初始时刻的权重分配不均匀。
3.2 偏差校正公式
为了校正这种偏差,我们可以将 v t v_t vt 除以权重之和 1 − β t 1 - \beta^t 1−βt,得到校正后的指数加权平均值 v ^ t \hat{v}_t v^t:
v ^ t = v t 1 − β t \hat{v}_t = \frac{v_t}{1 - \beta^t} v^t=1−βtvt
校正后的 v ^ t \hat{v}_t v^t 能够更好地反映真实的加权平均值。
4. PyTorch 实现
以下是 PyTorch 中实现指数加权平均的代码,包括偏差校正:
python
import torch
# 初始化参数
beta = 0.9 # 衰减率
ema_value = 0 # 初始EMA值
# 模拟一些数据
data = torch.tensor([1.0, 2.0, 3.0, 4.0, 5.0])
# 计算EMA
for t, x in enumerate(data, 1):
ema_value = beta * ema_value + (1 - beta) * x
corrected_ema = ema_value / (1 - beta**t) # 偏差校正
print(f"Step {t}: EMA = {ema_value}, Corrected EMA = {corrected_ema}")
5. 输出示例
假设输入数据为 [1.0, 2.0, 3.0, 4.0, 5.0]
,输出如下:
Step 1: EMA = 0.1, Corrected EMA = 1.0
Step 2: EMA = 0.29, Corrected EMA = 1.5263157894736843
Step 3: EMA = 0.561, Corrected EMA = 2.0434782608695654
Step 4: EMA = 0.9049, Corrected EMA = 2.5508474576271185
Step 5: EMA = 1.31441, Corrected EMA = 3.048780487804878