J'ai des séries chronologiques qui augmentent lentement, mais sur une courte période de temps, elles sont très ondulées. Par exemple, la série chronologique pourrait ressembler à:
[10 + np.random.Rand() for i in range(100)] + [12 + np.random.Rand() for i in range(100)] + [14 + np.random.Rand() for i in range(100)]
Je voudrais tracer la série chronologique en mettant l'accent sur la tendance générale, pas sur les petites vagues. Existe-t-il un moyen de tracer la moyenne sur une période de temps entourée d'une bande indiquant les vagues (la bande devrait représenter l'intervalle de confiance, où le point de données pourrait être à ce moment)?
Un simple tracé ressemblerait à ceci:
L'intrigue que je voudrais, avec des intervalles de confiance, ressemblerait à ceci:
Existe-t-il une manière élégante de le faire en Python?
Vous pouvez utiliser pandas
function rolling(n)
pour générer les valeurs de moyenne et d'écart type sur n
points consécutifs.
Pour l'ombre des intervalles de confiance (représentés par l'espace entre les écarts-types), vous pouvez utiliser la fonction fill_between()
de matplotlib.pyplot
. Pour plus d'informations, vous pouvez consulter ici , dont le code suivant est inspiré.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
#Declare the array containing the series you want to plot.
#For example:
time_series_array = np.sin(np.linspace(-np.pi, np.pi, 400)) + np.random.Rand((400))
n_steps = 15 #number of rolling steps for the mean/std.
#Compute curves of interest:
time_series_df = pd.DataFrame(time_series_array)
smooth_path = time_series_df.rolling(n_steps).mean()
path_deviation = 2 * time_series_df.rolling(n_steps).std()
under_line = (smooth_path-path_deviation)[0]
over_line = (smooth_path+path_deviation)[0]
#Plotting:
plt.plot(smooth_path, linewidth=2) #mean curve.
plt.fill_between(path_deviation.index, under_line, over_line, color='b', alpha=.1) #std curves.
Avec le code ci-dessus, vous obtenez quelque chose comme ceci:
On dirait que vous doublez le std deux fois. Je suppose que ça devrait être comme ça:
time_series_df = pd.DataFrame(time_series_array)
smooth_path = time_series_df.rolling(20).mean()
path_deviation = time_series_df.rolling(20).std()
plt.plot(smooth_path, linewidth=2)
plt.fill_between(path_deviation.index, (smooth_path-2*path_deviation)[0], (smooth_path+2*path_deviation)[0], color='b', alpha=.1)
Vous pouvez générer la courbe lisse de différentes manières.
Une approche simple consiste à utiliser une moyenne mobile (valeur moyenne des points dans une fenêtre glissante). Si vous stockez vos données dans une trame de données Pandas, cela peut être tracé très facilement. Vous pouvez également calculer l'erreur standard pour chaque point pour obtenir vos bandes de confiance.
Une autre approche consisterait à ajuster un modèle aux données et à l'utiliser pour générer la courbe lissée. Par exemple, vous pouvez le faire en utilisant un processus gaussien. Ce modèle peut également produire la bande de confiance souhaitée pour chaque point. Voir ceci exemple Scikit-learn pour plus d'informations.