【问题标题】:Time Series Decomposition function in PythonPython中的时间序列分解函数
【发布时间】:2014-01-07 11:06:51
【问题描述】:

时间序列分解是一种将时间序列数据集分成三个(或更多)组件的方法。例如:

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

在 R 中,我会执行函数 decomposestl。我将如何在 python 中执行此操作?

【问题讨论】:

    标签: python time-series


    【解决方案1】:

    你被介绍给scipy了吗?根据我在几个 PDF/网站中看到的内容

    HereHere

    这是可行的。但是如果没有看到一个具体的例子,就很难有人向你展示一个代码示例。 Scipy 太棒了,我在我的研究中使用它,仍然没有被它失望。

    【讨论】:

    • 是的,我目前正在使用 Scipy,包括 statsmodel、pandas 和 numpy。我能找到的最接近的方法是使用 pandas 中的 resample,但这不允许您对时间序列进行淡化。
    【解决方案2】:

    您可以使用 rpy2 从 python 调用 R 函数 使用 pip 安装 rpy2: pip install rpy2 然后使用这个包装器:https://gist.github.com/andreas-h/7808564 来调用 R 提供的 STL 功能

    【讨论】:

    • 此时调用实际上不起作用。不知道为什么
    【解决方案3】:

    我遇到了类似的问题,正在努力寻找最佳的前进道路。尝试将您的数据移动到 Pandas DataFrame 中,然后调用 StatsModels tsa.seasonal_decompose。见following example

    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()
    

    然后您可以从以下位置恢复分解的各个组件:

    res.resid
    res.seasonal
    res.trend
    

    我希望这会有所帮助!

    【讨论】:

    • 如何从组件中重建原始时间序列?
    • 您可以选择是通过减法还是除法来解构它们。加法是典型的方法,在这种情况下,您只需将组件重新添加在一起即可。
    • 在代码 sn-p 中,哪个变量保存输入数据?
    • dta.co2 是输入,但您也应该能够在调用后作为 res.observed 访问它。
    • 根据 StatsModels 文档,与 STL 相比,这是一种幼稚的分解。不确定是不是参数不好还是什么,但您不希望在剩余系列中看到这种季节性结构。正如下面 cast42 所指出的,使用github.com/andreas-h/pyloess 可能会更好
    【解决方案4】:

    我已经回答了这个问题here,但下面是关于如何使用 rpy2 执行此操作的快速函数。这使您可以使用 R 的鲁棒统计分解与 loess,但在 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
    

    上述函数假定您的系列具有日期时间索引。它返回一个包含各个组件的数据框,然后您可以使用您最喜欢的图形库对其进行图形化。

    你可以传递stl seenhere的参数,但是将任何句点更改为下划线,例如上面函数中的位置参数是s_window,但在上面的链接中它是s.window。另外,我在this repository 上找到了上面的一些代码。

    示例数据

    希望以下内容有效,老实说还没有尝试过,因为这是我回答问题很久之后的请求。

    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')
    

    【讨论】:

    • 这个库是否可以与 Python 3 一起使用,还是只能与 Python 2 一起使用?
    • 这与 statsmodels 方法相比如何?
    • @Tanguy,我将它与 python3 一起使用。确保在使用前 series.dropna()。您还需要将您的 R_HOME 环境变量设置为您的 R 版本所在的位置,并且您需要下载预测包。
    • @Tanguy,这些几乎也是我的确切设置。使用 rpy2 可能会让人觉得有点 hacky,如果您要进行大量时间序列分析,R 可能是目前两者中更强大的语言,并且可以正常工作。 Rob Hyndman 的预测包非常可靠,并且可以在 R 中轻松运行。
    • @Googme 它只需要一个熊猫系列。它需要一个日期时间索引,但无论如何都可能会运行。我在上面放了一个例子,但没有测试过。
    猜你喜欢
    • 2020-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多