一、描述
为了观察时间序列的趋势、周期性、误差,我们需要对序列进行分解。
二、Code
分解的成分主要有三类
- Trend
- Seasonal
- Residual
1 # author: adrian.wu 2 import numpy as np 3 from matplotlib import pyplot as plt 4 import pandas as pd 5 from statsmodels.tsa.seasonal import seasonal_decompose 6 from datetime import datetime 7 8 path = """/Users/adrian.wu/PycharmProjects/jobs/time_series/data/19_01_by_day.csv""" 9 timeseries = pd.read_csv(path) 10 data_raw = timeseries['num'] 11 12 fig, ax = plt.subplots(1, 1) 13 14 timeseries = np.array(timeseries['num']) 15 length = len(timeseries) 16 print(length) 17 timeseries = np.log(timeseries) 18 df = pd.DataFrame(data=timeseries, index=pd.date_range(start=datetime(2019, 1, 1), periods=length, freq='d'), 19 columns=['value']) 20 21 decomposition = seasonal_decompose(df) 22 23 trend = decomposition.trend 24 seasonal = decomposition.seasonal 25 residual = decomposition.resid 26 27 plt.subplot(411) 28 plt.plot(trend, label='Trend') 29 plt.xticks(rotation=90, fontsize=9) 30 plt.legend(loc='best') 31 plt.subplot(412) 32 plt.plot(seasonal, label='Seasonality') 33 plt.xticks(rotation=90, fontsize=9) 34 plt.legend(loc='best') 35 plt.subplot(413) 36 plt.plot(residual, label='Residuals') 37 plt.xticks(rotation=90, fontsize=9) 38 plt.legend(loc='best') 39 plt.tight_layout() 40 plt.show()
三、结果
由Seasonality可以看出周期性为7天。因此由这个信息就可以做很多事情了
四、STL算法
STL为时序分解中一种常见的算法。基于LOESS将某时刻的数据Yv分解为趋势分量、周期分量和余项
STL分为内循环与外循环,其中内循环主要做了趋势拟合与周期分量的计算。假定Tv(k)、Sv(k)为内循环中第k-1次pass结束时的趋势分量、周期分量,初始时Tv(k)=0;并有以下参数:
- n(i)内层循环数
- n(o)外层循环数
- n(p)为一个周期的样本数
- n(s)为Step2中LOESS平滑参数
- n(l)为Step3中LOESS平滑参数
- n(t)为Step6中LOESS平滑参数
每个周期相同位置的样本点组成一个子序列(subseries),容易知道这样的子序列共有n(p)个,我们称其为cycle-subseries。内循环主要分为以下6个步骤:
- Step1: 去趋势,减去上一轮结果的趋势分量,Yv-Tv(k);
- Step2: 周期子序列平滑(Cycle-subseries smoothing),用LOESS对每个子序列做回归,并向前向后各延展一个周期;平滑结果组成temporary seasonal series,记为C。
- Step3: 周期子序列的低通量过滤(Low-Pass Filtering),对上一个步骤的结果序列C依次做长度为n(p),n(p)、3的滑动平均(moving average),然后做LOESS(q=n, d=1)回归,得到结果序列Lv,相当于提取周期子序列的低通量。
-
Step4: 去除平滑周期子序列趋势(Detrending of Smoothed Cycle-subseries),Sv=Cv-Lv
- Step5:去周期(Deseasonalizing),减去周期分量,Yv-Sv(k+1)
- Step6:趋势平滑(Trend Smoothing),对于去除周期之后的序列做LOESS回归,得到趋势分量Tv(k+1)。
外层循环主要用于调节robustness weight。如果数据序列中有outlier,则余项会较大。定义
h = median(R|v|)
对于位置为v的数据点,其robustness weight为