随时间变化的指数移动平均线
我有一个连续的值,我想计算一个指数移动平均线 。 通常我只是使用这个标准公式:
- S n =αY+(1-α)S n-1
其中S n是新的平均值,α是α,Y是样本,S n-1是以前的平均值。
不幸的是,由于各种问题,我没有一个一致的采样时间。 我可能知道最多可以抽样一次,也就是每毫秒一次,但是由于我不能控制的因素,我可能无法一次抽样数毫秒。 然而,可能更常见的情况是,我简单地抽样了一些早或晚,而不是在0,1和2毫秒采样。 我在0,0.9和2.1毫秒采样。 我预料到,不pipe延迟如何,我的采样频率将远远高于奈奎斯特极限,因此我不必担心锯齿。
我认为,我可以根据自上次采样以来的时间长度,通过适当地改变阿尔法来或多或less地合理地处理这个问题。
我的推理的部分原因是,EMA在前一个数据点和当前数据点之间“线性插入”。 如果我们考虑以间隔t计算以下样本列表的EMA:[0,1,2,3,4]。 如果我们使用间隔2t,input变成[0,2,4],那么我们应该得到相同的结果,对吗? 如果EMA假设在t 2时刻t 2时刻的值为2,那么和在[0,2,2,4,4]上计算的时间间隔t的计算方法是一样的。 或者这是否有意义呢?
有人能告诉我如何适当地改变阿尔法? “请展示你的工作。” 也就是说,告诉我mathcertificate你的方法确实是做正确的事情。
这个答案基于我对低通滤波器的理解(“指数移动平均值”实际上只是一个单极点低通滤波器),但是我对你正在寻找的东西有朦胧的理解。 我想以下是你想要的:
首先,你可以简化你的方程(看起来更复杂,但代码更容易)。 我将使用“Y”作为输出,“X”使用input(而不是S输出,Yinput)。
Y n =αX+(1-α)Y n-1 →Y n = Y n-1 +α(X-Y n-1 )
其编码为:
Y += alpha * (XY);
其次,此处的α的值与1-e-Δt /τ相等,其中Δt是样本之间的时间,τ是低通滤波器的时间常数。 因为当Δt/τ小于1,并且α= 1-e-Δt/ τ≈Δt/τ ,所以在引号中“相等”。 (但是不要太小:你会遇到量化问题,除非你采用一些奇特的技术,否则通常需要在状态variablesS中额外的N位分辨率,其中N = -log 2 (α)。)对于较大Δt/τ的值,过滤效果开始消失,直到你接近α的点,而你基本上只是把input分配给输出。
这应该适用于不同的Δt值(只要alpha很小,Δt的变化就不是很重要,否则你会遇到一些相当奇怪的奈奎斯特问题/别名/等等),如果你在处理器上工作乘法比分割更便宜,或者定点问题很重要,可以预先计算ω= 1 /τ,并考虑尝试近似于α的公式。
如果你真的想知道如何导出公式
α= 1-e- Δt/τ
那么考虑它的微分方程来源:
Y +τdY / dt = X
当X是一个单位阶梯函数时,它有解Y = 1-e -t /τ 。 对于Δt的小值,导数可以近似为ΔY/Δt,从而产生
Y +τΔY/Δt= X
ΔY/Δt=(XY)/τ
ΔY=(XY)(Δt/τ)=α(XY)
并且α= 1-e- Δt/τ的“外推”来自于试图使行为与单位阶跃函数情况匹配。
看看这里: http : //www.eckner.com/research.html
看看第二个链接:“”非均匀时间序列的algorithm:移动平均线和其他滚动操作符“
这个文档描述了你所需要的编程algorithm,我想。
这不是一个完整的答案,但可能是一个开始。 就在我玩了一个小时左右的时间, 我把它作为我正在寻找的一个例子发布,也许是其他人在这个问题上的启发。
我从S 0开始,S 0是从先前的平均值S -1得到的平均值,以及在t 0得到的样本Y 0 。 (t 1 – t 0 )是我的样本间隔,α被设置为适合于那个样本间隔和我希望平均的周期。
我考虑过如果我在t 1错过了样本,而不得不在t 2时取样Y 2,会发生什么? 那么,我们可以开始扩展方程,看看如果我们有Y 1 :
- S 2 =αY2 +(1-α)S 1 ,其中S 1 =αY1 +(1-α)S 0
代:
- S 2 =αY2 +(1-α)(αY1 +(1-α)S 0 )
- S 2 =αY2 +(1-α)αY1 +(1-α)(1-α)S 0
- S 2 =αY2 +(1-α)αY1 +(1-α) 2 S 0
我注意到这个系列似乎是无限地延伸的,因为我们可以无限期地在右边replaceS n :
- S 2 =αY2 +(1-α)αY1 +(1-α) 2 (αY0 +(1-α)S -1 )
- S 2 =αY2 +(1-α)αY1 +(1-α)2αY0 +(1-α) 3 S -1
- 等等
好吧,这不是一个多项式(愚蠢的我),但如果我们乘以一个初始项,然后我们看到一个模式:
- S 2 =(1-α)0αY2 +(1-α)αY1 +(1-α)2αY0 +(1-α) 3 S -1
嗯:这是一个指数级数。 Quelle惊喜! 想象一下,出现指数移动平均的方程!
所以无论如何,我有这个x 0 + x 1 + x 2 + x 3 + …事情正在进行,而且我确定我在这里嗅到一个自然的对数,但是我不记得我在哪里在我耗尽时间之前,我正在前进。
对这个问题的任何答案,或者这个答案的任何正确性的certificate,都很大程度上取决于你所测量的数据。
如果你的样本是在t 0 = 0ms,t 1 = 0.9ms和t 2 = 2.1ms,但是你selectα是基于1ms间隔的,所以你需要一个局部调整的αn,select的正确性意味着知道t = 1ms和t = 2ms的采样值。
这导致了一个问题:你能否合理地插入你的数据来理解中间值可能是什么? 或者你甚至可以插入平均本身?
如果这两者都不可能,则就我所知,中间值Y(t)的逻辑select是最近计算的平均值 ,即Y(t)≈Sn,其中n是最大值,使得t n <t。
这个select有一个简单的结果:不pipe时差是什么,都留下α。
另一方面,如果有可能插值你的值,那么这将给你一个平稳的时间间隔样本。 最后,如果甚至有可能自己插入平均值,那将会使问题变得毫无意义。
通过使用一个略微不同的α(等于(1-α)中的问题 ),将一个新的值Y加到现有的S 0平均值上的基本公式如下:
S(Y,S 0 )=
(1-α)Y +αS0 =
Y – αY+αS0 =
Y +α(S 0 -Y)
如果我们现在加上时间间隔t的长度,并假设α只取决于t,那么公式看起来像这样:
S(Y,t,S 0 )= Y +αt(S 0 -Y)
现在假设t = t 1 + t 2 。 如果通过在时间间隔t 1和t 2上添加两个Y值来创build平均值,则所得的平均值如下所示:
S(Y,t 2 ,S(Y,t 1 ,S 0 ))=
Y +αt 2 (S(Y,t 1 ,S 0 )-Y)=
Y +αt 2 ((Y +αt 1 (S 0 -Y)) – Y)=
Y +αt 2αt 1 (S 0 -Y)
如果这个平均值应该与整个t时间间隔相同,那么αt =αt 1αt 2 。 满足这个要求的α的定义是:
αx := A x (对于某个常数A)
因为:
αt = A t = A t 1 + t 2 = A t 1 A t 2 =αt 1αt 2
这导致以下平均function:
S(Y,t,S 0 )= Y + A t (S 0 -Y)
我没有真正testing过,但是如果我所做的假设符合你的情况,这看起来像一个平均函数,可以很好地处理采样间隔的变化。
假设我们想在连续函数上做一个指数衰减平均值。 但是,我们没有这个函数的所有值,只有几个样本。 这个公式将会对我们所拥有的样本进行加权平均,以及它们在连续平均值中的权重。
乘数n = Alpha 时间n –时间n-1
Sum n = Val n + Sum n-1 *乘数n
计数n = 1 +计数n-1 *乘数n
Avg n = Sum n / Count n
我将只保留alpha
值,并填写缺失的数据。
由于您不知道在无法采样期间会发生什么情况,因此可以用0填充这些采样,或者保持以前的值稳定,并将这些值用于EMA。 或者一旦你有一个新的样本一些后向插值,填写缺失的值,并重新计算EMA。
我试图得到的是你有一个inputx[n]
有漏洞。 没有办法绕过你缺less数据的事实。 因此,可以使用零阶保持,或将其设置为零,或者在x[n]
和x[n+M]
之间进行某种插值,其中M
是缺失样本的数量,n是间隙的起点。 可能甚至使用n
之前的值。
这与我待办事项列表上的一个开放问题类似。 我有一个计划在一定程度上解决了,但还没有math工作来支持这个build议。
更新和总结:希望保持平滑因子(alpha)独立于补偿因子(我在此称为beta)。 杰森杰出的答案在这里已经被接受,对我来说很好。
第一步。
- 如果您还可以测量自上次采样以来的时间(以恒定采样时间的四舍五入为单位,因此最后一个采样为7.8个单位),这可以用于平滑多次。 在这种情况下应用公式8次。 你已经有效地做了一个平滑的偏向更多的当前价值。
第二步。
- 为了得到更好的平滑,我们需要调整阿尔法,而在前面的情况下应用公式8次。
这个平滑近似会丢失什么?
- 在上面的例子中已经错过了7个样本
- 这在步骤1中被近似为平坦的重新施加当前值另外7次
- 如果我们定义一个近似因子beta ,它将与alpha一起使用(如alpha * beta,而不仅仅是alpha),我们将假设7个错过的样本在先前样本值和当前样本值之间平稳地变化。