首页 > 解决方案 > Python中季节性的简单测试

问题描述

我一直在尝试找到一种方法来迭代多个时间序列(对于“客户”键)并为每个时间序列返回一个简单的是/否,以确定它是否具有可靠的季节性成分。

我知道 R 中有一个相对较新的库(seastests)——在 Python 中有什么东西可以在不绘制每个时间序列的情况下使用吗?

标签: pythonstatsmodels

解决方案


我知道这很旧,但我刚刚遇到了类似的问题。

我建议使用 SARIMAX 模型对每个客户的数据系列进行季节性分解,然后计算并使用季节性参数 p、d、q(P:季节性自回归顺序 - D:季节性差异顺序 - Q:季节性移动平均顺序) 来确定该系列是否是季节性的。如果这些参数 = 0,对于最小 AIC,我们可以假设该系列不是季节性的(y_ds 是系列数据值):

#customize data as per problem needs - in my case I have ds as date, customer_id and y as series values
data = pd.DataFrame({'ds': pd.to_datetime(data.ds), 'customer_id' : data['customer_id'], 'y' : data['y']})
data.set_index('ds', inplace=True)
customers = data['customer_id'].unique()

  for i in range(len(customers)):

        datai = data.loc[data['customer_id'] == customers[i]]
        datai['log_y'] = np.log(datai['y'])
        y_ds = datai['log_y'].resample('MS').mean()
        y_ds = y_ds.fillna(0)

        p = d = q = range(0, 2)
        pdq = list(itertools.product(p, d, q))
        seasonal_pdq = [(x[0], x[1], x[2], 12) for x in list(itertools.product(p, d, q))]

        cols = ['param','seasonal_param','AIC']
        lst = pd.DataFrame(columns=cols)
        for param in pdq:
            for param_seasonal in seasonal_pdq:
                try:
                    mod = sm.tsa.statespace.SARIMAX(y_ds,
                                            order=param,
                                            seasonal_order=param_seasonal,
                                            enforce_stationarity=False,
                                            enforce_invertibility=False)
                    results = mod.fit()
                    lst = lst.append({'param':param, 'seasonal_param':param_seasonal, 'AIC':results.aic},ignore_index=True)
                except:
                    continue

        order_param = lst.param[lst.AIC == lst.AIC.min()]
        order_param = order_param.values[0]
        seasonal_order_param = lst.seasonal_param[lst.AIC == lst.AIC.min()]
        seasonal_order_param = seasonal_order_param.values[0]
    
        if seasonal_order_param == (0,0,0,12):
            pattern = 'NON SEASONAL'
        else:
            pattern = 'SEASONAL'

        df = pd.DataFrame({'Trend': pattern,'customer_id': customers[i]})
        df_final = pd.concat([df_final, df])

推荐阅读