web-dev-qa-db-fra.com

Fonction de décomposition de séries temporelles en Python

La décomposition des séries chronologiques est une méthode qui sépare un ensemble de données chronologiques en trois (ou plus) composants. Par exemple:

x(t) = s(t) + m(t) + e(t)

t is the time coordinate
x is the data
s is the seasonal component
e is the random error term
m is the trend

Dans R, je ferais les fonctions decompose et stl . Comment pourrais-je faire cela en python?

43
user3084006

J'ai eu un problème similaire et j'essaie de trouver la meilleure voie à suivre. Essayez de déplacer vos données dans un Pandas DataFrame puis appelez StatsModelstsa.seasonal_decompose. Voir exemple suivant :

import statsmodels.api as sm

dta = sm.datasets.co2.load_pandas().data
# deal with missing values. see issue
dta.co2.interpolate(inplace=True)

res = sm.tsa.seasonal_decompose(dta.co2)
resplot = res.plot()

Three plots produced from above input

Vous pouvez ensuite récupérer les composants individuels de la décomposition à partir de:

res.resid
res.seasonal
res.trend

J'espère que ça aide!

60
AN6U5

J'ai déjà répondu à cette question ici , mais ci-dessous est une fonction rapide sur la façon de le faire avec rpy2. Cela vous permet d'utiliser la décomposition statistique robuste de R avec le loess, mais en python!

    import pandas as pd

    from rpy2.robjects import r, pandas2ri
    import numpy as np
    from rpy2.robjects.packages import importr


def decompose(series, frequency, s_window = 'periodic', log = False,  **kwargs):
    '''
    Decompose a time series into seasonal, trend and irregular components using loess, 
    acronym STL.
    https://www.rdocumentation.org/packages/stats/versions/3.4.3/topics/stl

    params:
        series: a time series

        frequency: the number of observations per “cycle” 
                   (normally a year, but sometimes a week, a day or an hour)
                   https://robjhyndman.com/hyndsight/seasonal-periods/

        s_window: either the character string "periodic" or the span 
                 (in lags) of the loess window for seasonal extraction, 
                 which should be odd and at least 7, according to Cleveland 
                 et al.

        log:    boolean.  take log of series



        **kwargs:  See other params for stl at 
           https://www.rdocumentation.org/packages/stats/versions/3.4.3/topics/stl
    '''

    df = pd.DataFrame()
    df['date'] = series.index
    if log: series = series.pipe(np.log)
    s = [x for x in series.values]
    length = len(series)
    s = r.ts(s, frequency=frequency)
    decomposed = [x for x in r.stl(s, s_window).rx2('time.series')]
    df['observed'] = series.values
    df['trend'] = decomposed[length:2*length]
    df['seasonal'] = decomposed[0:length]
    df['residuals'] = decomposed[2*length:3*length]
    return df

La fonction ci-dessus suppose que votre série possède un index datetime. Il renvoie une trame de données avec les composants individuels que vous pouvez ensuite représenter graphiquement avec votre bibliothèque graphique préférée.

Vous pouvez passer les paramètres pour stl vu ici , mais changez n'importe quel point pour souligner, par exemple l'argument positionnel dans la fonction ci-dessus est s_window, mais dans le lien ci-dessus c'est s.window. En outre, j'ai trouvé une partie du code ci-dessus sur ce référentiel .

Exemples de données

J'espère que les travaux ci-dessous fonctionnent, honnêtement, je ne les ai pas essayés car il s'agit d'une demande longtemps après avoir répondu à la question.

import pandas as pd
import numpy as np
obs_per_cycle = 52
observations = obs_per_cycle * 3
data = [v+2*i for i,v in enumerate(np.random.normal(5, 1, observations))]
tidx = pd.date_range('2016-07-01', periods=observations, freq='w')
ts = pd.Series(data=data, index=tidx)
df = decompose(ts, frequency=obs_per_cycle, s_window = 'periodic')
8
Jeff Tilton

Vous pouvez appeler les fonctions R à partir de python en utilisant rpy2 Installer rpy2 en utilisant pip avec: pip install rpy2 Ensuite, utilisez ce wrapper: https: //Gist.github .com/andreas-h/7808564 pour appeler la fonctionnalité STL fournie par R

5
cast42

Avez-vous déjà découvert scipy ? D'après ce que j'ai vu dans quelques PDF/sites

Ici et Ici

c'est faisable. Mais sans voir un exemple spécifique, il serait difficile pour quelqu'un de vous montrer un exemple de code. Scipy est génial Je l'utilise dans mes recherches, je n'ai toujours pas été déçu.

0
Matt