2011-04-04 615 views
6

如果我有時間序列數據 - {x,y}對列表並且想要平滑它,我可以使用像這樣的指數移動平均線:實現雙指數平滑,又名雙指數移動平均線(DEMA)

EMA[data_, alpha_:.1] := 
    Transpose @ {#1, ExponentialMovingAverage[#2, alpha]}& @@ [email protected] 

您將如何實施double exponential smoothing

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

如果它自己計算出alpha和gamma的好值,那將會非常好。


有關如何處理存在的時間序列,即缺口的情況下相關問題,樣品不能均勻地分佈在時間:

Exponential Moving Average Sampled at Varying Times

+0

我瞭解幾乎一無所知的問題,但似乎(從http://en.wikipedia.org/wiki/Exponential_smoothing),您可能需要趨勢估計。 http://reference.wolfram.com/applications/timeseries/UsersGuideToTimeSeries/PreparingDataForModeling/1.4.3.html – DavidC 2011-04-04 01:07:39

+0

請告訴我,如果Sasha的代碼給出正確的輸出 – 2011-04-04 04:28:53

+0

@ Mr.Wizard:在嘗試使用它時,它看起來是正確的我有數據。 (不幸的是,這也讓我相信這不是我想要的!但這是我自己的問題,希望這對未來在Mathematica中搜索DEMA的人有用!) – dreeves 2011-04-04 06:18:39

回答

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, [email protected]}]][[-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)))} 
+0

謝謝Sasha!我相信這是正確的。請注意,這與規範並不完全相同,因爲數據意味着具有{x,y}對的時間序列。但沒關係;這個與內置的ExponentialMovingAverage相似。 – dreeves 2011-04-04 06:15:50

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 * [email protected] 
][[All, 1]]