He generado 100 series temporales de muestra, cada una de ellas de 24 elementos, y cada una con una distribución exponencial con una escala diferente para cada uno de los 24 puntos temporales. Este es el parámetro de escala por punto de tiempo:
Mis 100 series temporales tienen este aspecto:
Esta es la matriz de covarianza de la muestra:
Este es el primer día:
Ahora voy a crear artificialmente dos nuevos días: Uno en el que añado una cantidad a un punto de tiempo en el que la varianza es generalmente alta (el día2 obtiene un aumento a las 8), y otro en el que añado la misma cantidad a un punto de tiempo en el que la varianza es baja (el día3 obtiene el mismo aumento a las 2).
Esperaré que la distancia dist(día1, día2) sea mucho menor que dist(día1, día3), porque el aumento del día2 se produjo en una región de alta varianza (las 8 de la mañana).
Pero la salida que obtengo es:
mahalanobis(day1, day2, Sigma) # should be "small"
62.9029
mahalanobis(day1, day3, Sigma) # should be larger
15.0200
¿Por qué la distancia dist(día1, día2) es mayor que dist(día1, día3)?
Editar: Código Python para reproducir las cifras y los resultados:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
one_day_length = 24
n_days = 400
x = np.array(range(one_day_length))
scales = 0.2 + 2 * np.sin(x / 5) ** 2
# plt.plot(scales)
np.random.seed(20181106)
one_random_day = np.random.exponential(scale=scales, size=one_day_length)
# plt.plot(one_random_day)
random_days = pd.DataFrame([np.random.exponential(scale=scales, size=one_day_length) for _ in range(n_days)])
# random_days.head(20).T.plot(legend=False)
Sigma = random_days.cov()
from scipy.spatial.distance import mahalanobis
day1 = random_days.iloc[0]
# plt.plot(day1)
# plt.title('Day 1')
# plt.imshow(Sigma)
mahalanobis(day1, day1, Sigma) # 0 of course
day2 = day1.copy()
day2[9] += 30
# plt.plot(day2)
# plt.title('Day 2 (8am += 30)')
day3 = day1.copy()
day3[2] += 30
# plt.plot(day3)
# plt.title('Day 3 (2am += 30)')
mahalanobis(day1, day2, Sigma) # should be "small", but is 64.61
mahalanobis(day1, day3, Sigma) # should be larger, but is 15.02