如何从理论上推导Pandas中ewm.std的计算公式?
咱们先把Pandas里ewm.std的计算逻辑用数学语言拆解开,再对比你的推导,就能明白问题出在哪了。
首先明确Pandas的实际计算步骤
对应你给出的代码,假设我们有长度为$M$的序列$x_1, x_2, ..., x_M$,平滑系数为$\alpha$(代码里的a),那么计算流程是:
- 计算权重:给每个样本赋予指数衰减权重,越靠后的样本权重越大:
$$w_t = (1-\alpha)^{M-t}$$
(比如最后一个样本$x_M$的权重是$(1-\alpha)0=1$,第一个样本$x_1$的权重是$(1-\alpha){M-1}$) - 计算指数加权均值:
$$\mu_{ewm} = \frac{\sum_{t=1}^M w_t x_t}{\sum_{t=1}^M w_t}$$ - 计算偏差修正项:
$$B = \frac{(\sum_{t=1}^M w_t)2}{(\sum_{t=1}M w_t)^2 - \sum_{t=1}^M w_t^2}$$ - 计算指数加权方差与标准差:
$$\sigma^2_{ewm} = B \cdot \frac{\sum_{t=1}^M w_t (x_t - \mu_{ewm})2}{\sum_{t=1}M w_t}$$
$$\sigma_{ewm} = \sqrt{\sigma^2_{ewm}}$$
你的推导和Pandas公式的核心差异
你之前的推导,其实是在计算指数加权均值(EWMA)这个统计量本身的方差,而Pandas的ewm.std做的是用指数加权的方式,估计原始数据序列的总体方差——这完全是两个不同的问题!
举个直白的例子:
- 你算的是“用EWMA方法估算出来的均值,它本身的波动有多大”;
- Pandas算的是“给原始数据每个点的离均差平方加指数权重,来估算原始数据整体的波动水平”。
偏差修正项的来源
你可能会好奇那个$B$项是干嘛的,其实它和等权方差里的$\frac{1}{n-1}$是一个道理——做无偏性修正。
在等权样本中,我们用$\frac{1}{n-1}$代替$\frac{1}{n}$来修正自由度偏差;而指数加权的场景下,我们用有效样本量来修正:
有效样本量的定义是$\frac{(\sum w_t)^2}{\sum w_t^2}$,它衡量的是加权样本等效于多少个等权样本。对应的无偏修正因子就是$\frac{(\sum w_t)^2}{(\sum w_t)^2 - \sum w_t^2}$,也就是代码里的bias。
两者的关联
回到你的推导结果:
$$Var(x_t) = \frac{(\sum c{T-t})2}{\sum c^{2(T-t)}} \cdot Var(\text{ewm}_T)$$
这里的$Var(\text{ewm}T)$是EWMA估计量的方差,而Pandas里的$\sigma^2{ewm}$是对$Var(x_t)$的估计。把你的式子变形一下就能看到:
$$Var(x_t) = B \cdot Var(\text{ewm}T)$$
而Pandas的$\sigma^2{ewm}$,本质上是用加权离均差平方和来估计$Var(x_t)$,再乘以修正项$B$得到无偏估计。
总结
你之前的思路没出错,但混淆了两个核心概念:Pandas的ewm.std是估计原始序列的方差,而你推导的是EWMA估计量自身的方差,这就是两者看起来不相关的原因。
备注:内容来源于stack exchange,提问作者GabCaz

