image.png

    趋势:**趋势是时间序列在某一方向上持续运动,现象是在较长时期内受某种根本性因素作用而形成的总的变动趋势。上图中可以看到从2014年2月到2014年4月,余额宝的申购资金一路下降,这是一个明显的趋势。

    季节变化:许多时间序列中包含季节变化,现象是在一年内随着季节的变化而发生的有规律的周期性变动。上图中肉眼很难看出时间序列随季节变化,第 3 小结将通过时间序列分解(STL)来展示序列中的季节变化。

    序列相关性:时间序列的一个最重要特征是序列相关性,又称为自相关性。上图中可以看到,数据之间存在一定的正相关与负相关。例如某天的数据上升,它的前一天或者后一天也上升或者下降。自相关性是时间序列可以预测未来的前提(序列中存在的规律),如果没有自相关性,就变成了白噪声(无规律)。

    随机噪声:**它是时间序列中除去趋势、季节变化和自相关性之后的剩余随机扰动。由于时间序列存在不确定性,随机噪声总是夹杂在时间序列中,致使时间序列表现出某种震荡式的无规律运动。

    这里采用 STL 算法进行时间序列分解:

    1. def decomposing(timeseries):
    2. decomposition = seasonal_decompose(timeseries)
    3. trend = decomposition.trend
    4. seasonal = decomposition.seasonal
    5. residual = decomposition.resid
    6. plt.figure(figsize=(16, 12))
    7. plt.subplot(411)
    8. plt.plot(timeseries, label='Original')
    9. plt.legend(loc='best')
    10. plt.subplot(412)
    11. plt.plot(trend, label='Trend')
    12. plt.legend(loc='best')
    13. plt.subplot(413)
    14. plt.plot(seasonal, label='Seasonarity')
    15. plt.legend(loc='best')
    16. plt.subplot(414)
    17. plt.plot(residual, label='Residual')
    18. plt.legend(loc='best')
    19. plt.show()
    20. dateparse = lambda dates: pd.datetime.strptime(dates, '%Y-%m-%d')
    21. purchase_seq_201402_201407 = pd.read_csv('./purchase_seq_201402_201407.csv', parse_dates=['report_date'],
    22. index_col='report_date', date_parser=dateparse)
    23. decomposing(purchase_seq_201402_201407)

    image.png

    四个序列从上到下依次表示:原始序列、趋势序列、季节序列、残差序列。
    上图中可以看出,从2014年2月开始,余额宝的申购总金额是呈现出一个逐步下降的趋势(如果大家结合余额宝和银行的利率曲线可以了解到,其实在这段时间内,相比于2013年末到2014年初,余额宝和银行的利息都降低了不少)。原始序列具有强烈的季节变化(或者称为周期性),几乎是每个月四个周期,也就是以星期为一个周期波动(这一点也很好理解,人们对于资金的存取习惯,跟工作日与节假日有密切的关系)。最后一项是残差序列,也就是原始序列中去除趋势和季节变化后的序列,这一部分是序列中的不稳定因素,具有一定的随机性,需要做进一步分析。
    时间序列分解的成功与否,取决于两个因素:一是数据序列本身是隐藏着规律的,不可预测的部分只是其中的一小部分;二是分解的方法要合适,尤其是周期的判断要准确。