np.correlate oblicza (nieznormalizowanego) cross-correlation między dwiema sekwencjami 1-wymiarowe:
z[k] = sum_n a[n] * conj(v[n+k])
podczas df.corr (domyślnie) oblicza Pearson correlation coefficient.
Współczynnik korelacji (jeśli istnieje) wynosi zawsze od -1 do 1 włącznie. Korelacja krzyżowa nie jest ograniczona.
Formuły są nieco podobne, ale należy zauważyć, że w formule korelacji krzyżowej (powyżej) nie ma odejmowania środków, ani podziału przez odchylenia standardowe, które są częścią wzoru dla współczynnika korelacji Pearsona.
Fakt, że standardowe odchylenie df['a']
i df['b']
wynosi zero, powoduje, że df.corr
ma wszędzie NaN.
Z poniższego komentarza wygląda na to, że szukasz Beta. Wiąże się to współczynnik korelacji Pearsona, ale zamiast dzieląc przez iloczyn odchyleń standardowych:
podzielić przez wariancji:
Można obliczyć Beta
użycie np.cov
cov = np.cov(a, b)
beta = cov[1, 0]/cov[0, 0]
import numpy as np
import matplotlib.pyplot as plt
np.random.seed(100)
def geometric_brownian_motion(T=1, N=100, mu=0.1, sigma=0.01, S0=20):
"""
http://stackoverflow.com/a/13203189/190597 (unutbu)
"""
dt = float(T)/N
t = np.linspace(0, T, N)
W = np.random.standard_normal(size=N)
W = np.cumsum(W) * np.sqrt(dt) # standard brownian motion ###
X = (mu - 0.5 * sigma ** 2) * t + sigma * W
S = S0 * np.exp(X) # geometric brownian motion ###
return S
N = 10 ** 6
a = geometric_brownian_motion(T=1, mu=0.1, sigma=0.01, N=N)
b = geometric_brownian_motion(T=1, mu=0.2, sigma=0.01, N=N)
cov = np.cov(a, b)
print(cov)
# [[ 0.38234755 0.80525967]
# [ 0.80525967 1.73517501]]
beta = cov[1, 0]/cov[0, 0]
print(beta)
# 2.10609347015
plt.plot(a)
plt.plot(b)
plt.show()
Stosunek mu
s wynosi 2, a beta
wynosi około 2,1.
I można również obliczyć ją df.corr
, choć jest to o wiele bardziej okrągłe o sposób to zrobić (ale miło jest zobaczyć istnieje spójność):
import pandas as pd
df = pd.DataFrame({'a': a, 'b': b})
beta2 = (df.corr() * df['b'].std() * df['a'].std()/df['a'].var()).ix[0, 1]
print(beta2)
# 2.10609347015
assert np.allclose(beta, beta2)
Dzięki! Tak więc, w przypadku, gdy moje "a" i "b" są dziennymi zmianami cen i chcę zmierzyć, w jaki sposób "b" ma wartość "a" (czyli - jeśli za każdym razem "a" wzrasta o 1% b wzrasta o 2%. Spodziewam się zobaczyć 2,0, jeśli "b" zawsze wynosi -0,5%, oczekiwam -0,5). Myślę, że "korelacja krzyżowa" jest tym, czego chcę, prawda? –