¿Por qué NUMPY correlate y corrcoef devuelven valores diferentes y cómo “normalizar” un correlato en modo “completo”?

Estoy tratando de usar un análisis de series de tiempo en Python, usando Numpy.

Tengo dos series algo medianas, con valores de 20k cada una y quiero verificar la correlación deslizante.

El corrcoef me da como salida una Matriz de coeficientes de correlación / correlación automática. Nada útil por sí mismo en mi caso, ya que una de las series contiene un retraso.

La función de correlación (en modo = “completo”) devuelve una lista de 40k elementos que se parece al tipo de resultado al que aspiro (el valor máximo está tan lejos del centro de la lista como lo indicaría el retraso), pero Todos los valores son raros, hasta 500, cuando esperaba algo de -1 a 1.

No puedo simplemente dividirlo todo por el valor máximo; Sé que la máxima correlación no es 1.

¿Cómo podría normalizar la “correlación cruzada” (correlación en modo “completo”) para que los valores de retorno sean la correlación en cada paso de retardo en lugar de los valores muy grandes y extraños?

Estás buscando una correlación cruzada normalizada. Esta opción aún no está disponible en Numpy, pero hay un parche a la espera de una revisión que haga exactamente lo que usted desea. Creo que no debería ser demasiado difícil aplicarlo. La mayoría de los parches son solo cosas de cadena de documentos. Las únicas líneas de código que agrega son

if normalize: a = (a - mean(a)) / (std(a) * len(a)) v = (v - mean(v)) / std(v) 

donde a y v son las matrices de entrada de números de las cuales está encontrando la correlación cruzada. No debería ser difícil agregarlos a su propia distribución de Numpy o simplemente hacer una copia de la función de correlación y agregar las líneas allí. Haría esto último personalmente si quisiera ir por esta ruta.

Otra alternativa, posiblemente mejor, es simplemente hacer la normalización de los vectores de entrada antes de enviarla para correlacionarla. Depende de usted de qué manera le gustaría hacerlo.

Por cierto, esta parece ser la normalización correcta según la página de Wikipedia en la correlación cruzada, excepto por la división por len(a) lugar de (len(a)-1) . Creo que la discrepancia es similar a la desviación estándar de la muestra en comparación con la desviación estándar de la muestra y realmente no hará mucha diferencia en mi opinión.

De acuerdo a estas diapositivas , sugeriría hacerlo de esta manera:

 def cross_correlation(a1, a2): lags = range(-len(a1)+1, len(a2)) cs = [] for lag in lags: idx_lower_a1 = max(lag, 0) idx_lower_a2 = max(-lag, 0) idx_upper_a1 = min(len(a1), len(a1)+lag) idx_upper_a2 = min(len(a2), len(a2)-lag) b1 = a1[idx_lower_a1:idx_upper_a1] b2 = a2[idx_lower_a2:idx_upper_a2] c = np.correlate(b1, b2)[0] c = c / np.sqrt((b1**2).sum() * (b2**2).sum()) cs.append(c) return cs