np.correlate calcola il (normalizzato) cross-correlation tra due sequenze 1-dimensionali:
z[k] = sum_n a[n] * conj(v[n+k])
mentre df.corr (di default) calcola il Pearson correlation coefficient.
Il coefficiente di correlazione (se esiste) è sempre compreso tra -1 e 1 incluso. La correlazione incrociata non è limitata.
Le formule sono in qualche modo correlate, ma si noti che nella formula di cross-correlazione (sopra) non vi è sottrazione delle medie e nessuna divisione delle deviazioni standard che fa parte della formula per il coefficiente di correlazione di Pearson.
Il fatto che la deviazione standard di df['a']
e df['b']
sia zero è ciò che fa sì che df.corr
sia NaN ovunque.
Dal commento di seguito, sembra che stiate cercando Beta. È collegato al coefficiente di correlazione di Pearson, ma invece di dividere per il prodotto delle deviazioni standard:
si divide per una varianza:
È possibile calcolare Beta
utilizzando 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()
Il rapporto tra mu
s è 2, e beta
è ~ 2.1.
E si potrebbe anche calcolare con df.corr
, anche se questo è un modo molto più rotonda di farlo (ma è bello vedere la coerenza):
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)
Grazie! Quindi nel caso in cui il mio "a" e "b" sono variazioni giornaliere dei prezzi e voglio misurare come fa "b" fa rispetto a "a" (che significa - se ogni volta "a" sale dell'1% b sale del 2% mi aspetterei di vedere 2.0, se "b" è sempre -0.5% mi aspetterei -0.5). Immagino che la "cross-correlazione" sia ciò che voglio, giusto? –