J'ai besoin de faire l'auto-corrélation d'un ensemble de nombres, ce qui, d'après ce que je comprends, n'est que la corrélation de l'ensemble avec lui-même.
Je l'ai essayé en utilisant la fonction de corrélation de numpy, mais je ne crois pas au résultat, car il donne presque toujours un vecteur où le premier nombre n'est pas le plus grand, comme il se doit.
Donc, cette question est en réalité deux questions:
- Que fait exactement
numpy.correlate
? - Comment puis-je l'utiliser (ou autre chose) pour faire une auto-corrélation?
Réponses:
Pour répondre à votre première question,
numpy.correlate(a, v, mode)
exécute la convolution dea
avec l'inverse dev
et donne les résultats coupés par le mode spécifié. La définition de la convolution , C (t) = ∑ -∞ <i <∞ a i v t + i où -∞ <t <∞, permet des résultats de -∞ à ∞, mais vous ne pouvez évidemment pas stocker un infiniment long tableau. Il faut donc le découper, et c'est là que le mode entre en jeu. Il existe 3 modes différents: complet, identique et valide:t
deuxa
etv
se chevauchent.a
ouv
).a
et sev
chevauchent complètement. La documentation denumpy.convolve
donne plus de détails sur les modes.Pour votre deuxième question, je pense
numpy.correlate
est de vous donner l'auto - corrélation, il est juste de vous donner un peu plus aussi. L'autocorrélation est utilisée pour déterminer à quel point un signal ou une fonction est similaire à lui-même à une certaine différence de temps. À une différence de temps de 0, l'autocorrélation doit être la plus élevée car le signal est identique à lui-même, vous vous attendiez donc à ce que le premier élément du tableau de résultats d'autocorrélation soit le plus grand. Cependant, la corrélation ne commence pas à une différence de temps de 0. Elle commence à une différence de temps négative, se ferme à 0, puis devient positive. Autrement dit, vous vous attendiez:autocorrélation (a) = ∑ -∞ <i <∞ a i v t + i où 0 <= t <∞
Mais ce que vous avez, c'est:
autocorrélation (a) = ∑ -∞ <i <∞ a i v t + i où -∞ <t <∞
Ce que vous devez faire est de prendre la dernière moitié de votre résultat de corrélation, et cela devrait être l'autocorrélation que vous recherchez. Une simple fonction python pour faire cela serait:
Vous aurez bien sûr besoin d'une vérification des erreurs pour vous assurer qu'il
x
s'agit bien d'un tableau 1-d. De plus, cette explication n'est probablement pas la plus mathématiquement rigoureuse. J'ai jeté autour des infinis parce que la définition de la convolution les utilise, mais cela ne s'applique pas nécessairement à l'autocorrélation. Donc, la partie théorique de cette explication peut être légèrement bancale, mais j'espère que les résultats pratiques seront utiles. Ces pages sur l'autocorrélation sont très utiles et peuvent vous donner un bien meilleur contexte théorique si cela ne vous dérange pas de parcourir la notation et les concepts lourds.la source
return numpy.correlate(x, x, mode='same')
np.correlate(x,x,mode='full')[len(x)//2:] != np.correlate(x,x,mode='same')
. Par exemple,x = [1,2,3,1,2]; np.correlate(x,x,mode='full');
{>>> array([ 2, 5, 11, 13, 19, 13, 11, 5, 2])
}np.correlate(x,x,mode='same');
{>>> array([11, 13, 19, 13, 11])
}. La bonne est:np.correlate(x,x,mode='full')[len(x)-1:];
{>>> array([19, 13, 11, 5, 2])
} voir le premier élément est le plus grand .[len(x)-1:]
commence à partir du décalage 0. Parce quefull
mode donne une taille de résultat2*len(x)-1
, A.Levy[result.size/2:]
est le même que[len(x)-1:]
. Il vaut mieux en faire un int, comme[result.size//2:]
.L'auto-corrélation existe en deux versions: statistique et convolution. Ils font tous les deux la même chose, sauf pour un petit détail: La version statistique est normalisée pour être sur l'intervalle [-1,1]. Voici un exemple de la façon dont vous faites la statistique:
la source
numpy.corrcoef[x:-i], x[i:])[0,1]
dans la deuxième ligne car la valeur de retour decorrcoef
est une matrice 2x2Utilisez la
numpy.corrcoef
fonction au lieu denumpy.correlate
pour calculer la corrélation statistique pour un décalage de t:la source
Je pense qu'il y a 2 choses qui ajoutent de la confusion à ce sujet:
J'ai créé 5 fonctions qui calculent l'auto-corrélation d'un tableau 1d, avec des distinctions partielles et non partielles. Certains utilisent la formule des statistiques, d'autres utilisent la corrélation dans le sens du traitement du signal, ce qui peut également être fait via FFT. Mais tous les résultats sont des auto-corrélations dans la définition des statistiques , ils illustrent donc comment ils sont liés les uns aux autres. Code ci-dessous:
Voici la figure de sortie:
Nous ne voyons pas les 5 lignes car 3 d'entre elles se chevauchent (en violet). Les chevauchements sont tous des auto-corrélations non partielles. En effet, les calculs à partir des méthodes de traitement du signal (
np.correlate
, FFT) ne calculent pas une moyenne / std différente pour chaque chevauchement.Notez également que le résultat
fft, no padding, non-partial
(ligne rouge) est différent, car il n'a pas rempli la série temporelle de 0 avant de faire la FFT, donc c'est une FFT circulaire. Je ne peux pas expliquer en détail pourquoi, c'est ce que j'ai appris d'ailleurs.la source
Comme je viens de rencontrer le même problème, je voudrais partager quelques lignes de code avec vous. En fait, il existe actuellement plusieurs articles assez similaires sur l'autocorrélation dans stackoverflow. Si vous définissez l'autocorrélation comme
a(x, L) = sum(k=0,N-L-1)((xk-xbar)*(x(k+L)-xbar))/sum(k=0,N-1)((xk-xbar)**2)
[c'est la définition donnée dans la fonction a_correlate d'IDL et qu'elle est en accord avec ce que je vois dans la réponse 2 de la question # 12269834 ], alors ce qui suit semble donner les résultats corrects:Comme vous le voyez, j'ai testé cela avec une courbe de péché et une distribution aléatoire uniforme, et les deux résultats ressemblent à ce que j'attendais. Notez que j'ai utilisé
mode="same"
au lieu demode="full"
comme les autres l'ont fait.la source
Votre question 1 a déjà été largement discutée dans plusieurs excellentes réponses ici.
J'ai pensé partager avec vous quelques lignes de code qui permettent de calculer l'autocorrélation d'un signal en se basant uniquement sur les propriétés mathématiques de l'autocorrélation. Autrement dit, l'autocorrélation peut être calculée de la manière suivante:
soustraire la moyenne du signal et obtenir un signal non biaisé
calculer la transformée de Fourier du signal non biaisé
calculer la densité spectrale de puissance du signal, en prenant la norme carrée de chaque valeur de la transformée de Fourier du signal non biaisé
calculer la transformée de Fourier inverse de la densité spectrale de puissance
normaliser la transformée de Fourier inverse de la densité spectrale de puissance par la somme des carrés du signal non biaisé, et prendre seulement la moitié du vecteur résultant
Le code pour cela est le suivant:
la source
p = np.abs(f)
?Je suis un biologiste informatique, et quand j'ai dû calculer les auto / corrélations croisées entre des couples de séries chronologiques de processus stochastiques, j'ai réalisé que cela
np.correlate
ne faisait pas le travail dont j'avais besoin.En effet, ce qui semble manquer,
np.correlate
c'est le moyennage sur tous les couples possibles de points temporels à distance 𝜏.Voici comment j'ai défini une fonction faisant ce dont j'avais besoin:
Il me semble qu'aucune des réponses précédentes ne couvre cette instance d'auto / corrélation croisée: j'espère que cette réponse pourra être utile à quelqu'un travaillant sur des processus stochastiques comme moi.
la source
J'utilise talib.CORREL pour une autocorrélation comme celle-ci, je suppose que vous pourriez faire la même chose avec d'autres packages:
la source
Utilisation de la transformation de Fourier et du théorème de convolution
La complexité temporelle est N * log (N)
Voici une version normalisée et non biaisée, c'est aussi N * log (N)
La méthode fournie par A. Levy fonctionne, mais je l'ai testée sur mon PC, sa complexité temporelle semble être N * N
la source
Une alternative à numpy.correlate est disponible dans statsmodels.tsa.stattools.acf () . Cela donne une fonction d'autocorrélation décroissante en continu comme celle décrite par OP. La mise en œuvre est assez simple:
Le comportement par défaut est de s'arrêter à 40 nlags, mais cela peut être ajusté avec l'
nlag=
option pour votre application spécifique. Il y a une citation au bas de la page pour les statistiques derrière la fonction .la source
Je pense que la vraie réponse à la question du PO est succinctement contenue dans cet extrait de la documentation Numpy.correlate:
Cela implique que, lorsqu'elle est utilisée sans définition de «mode», la fonction Numpy.correlate renverra un scalaire, lorsqu'elle aura le même vecteur pour ses deux arguments d'entrée (c'est-à-dire lorsqu'elle est utilisée pour effectuer une autocorrélation).
la source
Une solution simple sans pandas:
la source
Tracez l'autocorrélation statistique en fonction d'une série de retours pandas datatime:
la source
autocorrelation_plot()
dans ce cas? (cf. stats.stackexchange.com/questions/357300/… )