实施双重指数平滑,也称为双重指数移动平均线(DEMA)

6
如果我有时间序列数据 -- 一组{x,y}对的列表 -- 并且想要平滑处理它,我可以使用指数移动平均法,如下所示:
EMA[data_, alpha_:.1] := 
  Transpose @ {#1, ExponentialMovingAverage[#2, alpha]}& @@ Transpose@data

你如何实现双指数平滑

DEMA[data_, alpha_, gamma_] := (* unstub me! *)

如果它能自动找到适合的alpha和gamma值,那就更好了。
关于如何处理时间序列中存在间隔的情况,即样本在时间上不是均匀分布的相关问题: 在不同时间采样的指数移动平均值

我对这个问题几乎一无所知,但从http://en.wikipedia.org/wiki/Exponential_smoothing看来,您可能需要一个趋势估计。http://reference.wolfram.com/applications/timeseries/UsersGuideToTimeSeries/PreparingDataForModeling/1.4.3.html - DavidC
请告诉我Sasha的代码是否给出了正确的输出。 - Mr.Wizard
@Mr.Wizard:在我尝试一些我拥有的数据时,它看起来是正确的。(不幸的是,这也让我相信这实际上并不是我想要的!但这是我的问题。希望这对于未来在Mathematica中搜索DEMA的人们有用!) - dreeves
我曾经用它进行过几次金融(市场)时间序列分析。你用它做什么? - Dr. belisarius
@belisarius:我试图改进黑客饮食(http://fourmilab.ch/hackdiet)的方法。例如,http://beeminder.com/d/mass - dreeves
2个回答

3

我不确定这是最快的代码,但以下代码似乎可以做到:

DEMA[data_, alpha_, gamma_] := 
 Module[{st = First[data], bt = data[[2]] - data[[1]], btnew, stnew},
  Reap[
    Sow[st];
    Do[
     stnew = alpha y + (1 - alpha) (st + bt);
     btnew = gamma (stnew - st) + (1 - gamma) bt;
     Sow[stnew];
     st = stnew;
     bt = btnew;
     , {y, Rest@data}]][[-1, 1]
   ]]

这几乎是从您引用的页面直接提取的。您可以修改源代码中b的初始条件。将bt最初设置为零可恢复单指数平滑处理。
In[81]:= DEMA[{a, b, c, d}, alpha, gamma]

Out[81]= {a, (1 - alpha) b + alpha b, 
 alpha c + (1 - alpha) ((1 - alpha) b + 
     alpha b + (-a + b) (1 - gamma) + (-a + (1 - alpha) b + 
        alpha b) gamma), 
 alpha d + (1 - 
     alpha) (alpha c + (1 - 
        gamma) ((-a + b) (1 - gamma) + (-a + (1 - alpha) b + 
           alpha b) gamma) + (1 - alpha) ((1 - alpha) b + 
        alpha b + (-a + b) (1 - gamma) + (-a + (1 - alpha) b + 
           alpha b) gamma) + 
     gamma (-(1 - alpha) b - alpha b + 
        alpha c + (1 - alpha) ((1 - alpha) b + 
           alpha b + (-a + b) (1 - gamma) + (-a + (1 - alpha) b + 
              alpha b) gamma)))}

谢谢 Sasha!我相信这是正确的。请注意,这不完全符合规范,因为数据应该是带有{x,y}对的时间序列。但这没关系;这个与内置的指数移动平均值相似。 - dreeves

1

这是我的公式:

DEMA[data_, alpha_, gamma_] :=
 FoldList[
   Module[{x, y},
     x = #[[1]] + #[[2]];
     y = #2 - alpha x;
     {y + x, #[[2]] + gamma * y}
     ] &,
   {data[[1]], data[[2]] - data[[1]]},
   alpha * Rest@data
 ][[All, 1]]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接