2016-11-23 20 views
4

パンダのewm.std計算を検証して、自分のコードに対してワンステップ更新を実装できるようにしようとしています。コードの問題の完全な説明は次のとおりです。パンダewm.std計算

mrt = pd.Series(np.random.randn(1000)) 
N = 100 
a = 2/(1+N) 
bias = (2-a)/2/(1-a) 
x = mrt.iloc[-2] 
ma = mrt.ewm(span=N).mean().iloc[-3] 
var = mrt.ewm(span=N).var().iloc[-3] 
ans = mrt.ewm(span=N).std().iloc[-2] 
print(np.sqrt(bias*(1-a) * (var + a * (x- ma)**2)), ans) 

(1.1352524643949702、1.1436193844674576)

Iは、標準的な製剤を使用しています。誰かがなぜ2つの値が同じであってはならないのか教えていただけますか?すなわち、パンダが指数関数的に重み付けされた標準をどのように計算するのか?

編集:ジュリアンの回答後 - もう少しユースケースを教えてください。私はpandasで計算されたvarの割合をプロットしています。また、Cyndorのpandas ewm-covarianceのコードから推測された式を使用しています。この比率は1でなければなりません(誰かが指摘できれば私の公式に問題があると推測しています)。

mrt = pd.Series(np.random.randn(1000)) 

N = 100 
a = 2./(1+N) 
bias = (2-a)/2./(1-a) 
mewma = mrt.ewm(span=N).mean() 

var_pandas = mrt.ewm(span=N).var() 
var_calculated = bias * (1-a) * (var_pandas.shift(1) + a * (mrt-mewma.shift(1))**2) 

(var_calculated/var_pandas).plot() 

プロットは問題をはっきりと示しています。

plot of the ratio after the initial values are removed

EDIT 2:試行錯誤することで、私は右の式を考え出し:

var_calculated = (1-a) * (var_pandas.shift(1) + bias * a * (mrt-mewma.shift(1))**2) 

をしかし、私はそれが正しいものであることを納得していませんよ!誰かがそれに光を当てることができますか? ans == np.sqrt(mrt.ewm(span=N).var().iloc[-2])

+1

潜在的な重複[このクエスト(http://stackoverflow.com/questions/37924377/does-pandas-calculate-wm-wrong)? –

+0

@JulienMarrecいいえ。エイマを正確に確認できます。私はewmstdでトランプされています。 –

+0

ewmは、[window.py#L1387](https://github.com/pandas-dev/pandas/blob/master/pandas/core/window.py#L1387)で定義されています。 ewm.stdコールは[こちら](https://github.com/pandas-dev/pandas/blob/master/pandas/core/window.py#L1555)です.-そして_zqrst [ここ]に行きますhttps://github.com/pandas-dev/pandas/blob/master/pandas/core/window.py#L1761) –

答えて

3

あなたの質問は、実際に実際にパンダが上記のあなたの例ではそうewm.var()

In [1]: 
(np.sqrt(mrt.ewm(span=span).var()) == mrt.ewm(span=span).std())[1:].value_counts() 

Out[1]: 
True 999 
dtype: int64 

の計算方法に帰着します。

それは(ewmvarの計算方法を調査するために)、それは我々が最初の要素をチェックした場合input_x=input_y=mrt


emcovを呼び出すことによって、それをしない:、emcovルーチンを使用して、

mrt.ewm(span=span).var()[:2].values 
> array([nan, 0.00555309]) 

特定のケースに適用する:

x0 = mrt.iloc[0] 
x1 = mrt.iloc[1] 
x2 = mrt.iloc[2] 

# mean_x and mean_y are both the same, here we call it y 
# This is the same as mrt.ewm(span=span).mean(), I verified that too 
y0 = x0 
# y1 = mrt.ewm(span=span).mean().iloc[1] 
y1 = ((1-alpha)*y0 + x1)/(1+(1-alpha)) 
#y2 = (((1-alpha)**2+(1-alpha))*y1 + x2)/(1 + (1-alpha) + (1-alpha)**2) 

cov0 = 0 

cov1 = (((1-alpha) * (cov0 + ((y0 - y1)**2))) + 
       (1 * ((x1 - y1)**2)))/(1 + (1-alpha)) 

# new_wt = 1, sum_wt0 = (1-alpha), sum_wt2 = (1-alpha)**2 
sum_wt = 1+(1-alpha) 
sum_wt2 =1+(1-alpha)**2 


numerator = sum_wt * sum_wt # (1+(1-alpha))^2 = 1 + 2(1-alpha) + (1-alpha)^2 
denominator = numerator - sum_wt2 # # 2*(1-alpha) 


print(np.nan,cov1*(numerator/denominator)) 

>(nan, 0.0055530905712123432) 
+0

ありがとうJulien。あなたがしたことは大丈夫だと思います。あなたは最後のステップで同じ平等を得ることができますか?上記の質問の編集をご覧ください。 –

+0

はい、確認済みです。 –

+0

ありがとう!だから私の式にはいくつか問題があります。試行錯誤により、正しい式がvar_calculated =(1-a)*(var_pandas.shift(1)+ bias * a *(mrt-mewma.shift(1))** 2)であることがわかりました。これは完全一致を与える!しかし、私はなぜか分からない:すべてのトラブルのおかげで@ジュリアン –