web-dev-qa-db-fra.com

Comment tracer un tableau de séries temporelles, avec des intervalles de confiance affichés, en python?

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:

enter image description here

L'intrigue que je voudrais, avec des intervalles de confiance, ressemblerait à ceci:

enter image description here

Existe-t-il une manière élégante de le faire en Python?

9
Ștefan

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: enter image description here

9
Ștefan

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)
3
flrndttrch

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.

1
lightalchemist