收藏笔记每天写1000字工具癖

Python 用于金融数据分析第9课-----时间序列分析模型

2018-03-22  本文已影响439人  九日照林

大纲

一、时间序列基础知识

时间序列有一些基本的性质。

1. 趋势

从上图可以看出有个一开始向上,中间静止或者叫水平,后半段向下的趋势,这个趋势需要通过对数据求平均值才会看得更加明显。
虽然有围绕着均值上下波动的偏差,但是从较大的时间尺度上面来看,它仍然是可以看作有明显的趋势的。

2. 季节性

季节性

季节性比较好理解,就是值随着月份有着明显的涨落,比如谷歌搜索snowboarding的明显到了冬天就有个明显的飞涨,到了夏天就有明显的回落,重复出现。当然,从图上总体趋势还可以看出搜索snowboarding的量总体上也有个下降。

3. 周期性

周期性

周期性跟季节性的区别在于它带有明显的趋势,但没有重复,在上图当中不是季节性,因为并不是一到某个季节值就会有明显的涨落,而是每隔几年就有一次涨落。(这里还有些不理解)

二、statsmodels模块介绍

statsmodels是能够对数据进行建模,预测的工具包,它还能对数据进行假设性检验。

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import statsmodels.api as sm
nt=sm.datasets.macrodata.NOTE#datasets模块包含了很多数据集,我们在这里调用macrodata这个数据集,然后查看这个数据集的相关信息
print nt

接下来载入数据集

df=sm.datasets.macrodata.load_pandas().data
df.head()

在这里的意思是说以pandas的形式加载这个macrodata的数据,然后我取加载后的数据(可能是load_pandas之后不只有data这个属性,还有其他的属性)


我们看一下官方文档,可以发现,它的作用是传入开始start和end的日期文本,然后会转换成一系列的datetime序列(可以认为是range函数的日期版),关键是这里的日期缩写是怎么规律?


在这里我们大致可以看到缩写前面一部分是年份,后面字母代表频率,如果是Q则代表季度qurter,字母后面的数字代表开始的节点,如果是1996Q2,代表1996年的第二个季度开始,往后推length个长度的单位。

index=pd.Index(sm.tsa.datetools.dates_from_range('1959Q1', '2009Q3'))
df.index=index

我们发现原始数据的步长都是按照季度来的,因此我们生成按照季度来的时间序列,并将这个序列作为索引,给原始数据对应上

#画出重新设置序列以后的图
df['realgdp'].plot(color='darkgreen', linestyle='dashed')
plt.ylabel('gdp')

使用statsmodel模块得到趋势

Hodrick-Prescott filter能够把趋势和周期性区分开来。趋势用tao_{t}表示,而周期项用zeta_{t}
表示。所以某个时间的值可以用两者的加和表示。


而预测模型的组成由是最小化以下这个二次方损失函数所决定:


gdp_cyclical, gdp_trend=sm.tsa.filters.hpfilter(df['realgdp'])
gdp_trend.head()

打印出的结果是这个。
接下来我们把趋势和原数据都一起作图。

df['gdp_trend']=gdp_trend
df['gdp_cyclical']=gdp_cyclical
df[['realgdp', 'gdp_trend']].plot(figsize=(16, 6), color=['darkgreen', 'red'], linestyle='dashed')

可以看得到趋势和原始数据符合得不错。
还可以通过设置线的颜色和实虚线来突出表示。

df[['realgdp', 'gdp_trend']].plot(figsize=(16, 6), color=['darkgreen', 'red'], style=['-','--'])

三、指数平均化移动平均值EWMA

#导入航班数据
df=pd.read_csv('airline_passengers.csv', index_col='Month', parse_dates=True)
#指定index column,并且尽可能按照日期格式来解析index
df.dropna(inplace=True)#丢掉缺失的行
df.index=pd.to_datetime(df.index)
plt.plot_date(data=df, x=df.index, y='Thousands of Passengers', xdate=True, marker=None, linestyle='solid', color='darkgreen')

小提示,在这里可以通过指定marker为None来消除标记。

SMA

接下来使用简单的移动平均,也就是不引入权重和指数。

df['6_rolling_mean']=df['Thousands of Passengers'].rolling(6).mean()#仍旧是在移动完rolling之后要用聚合函数
df['12_rolling_mean']=df['Thousands of Passengers'].rolling(12).mean()
df.plot(kind='line', color=['darkred', 'darkgreen', 'darkblue'])

以上分别代表原数据,6个月为一个窗口的移动平均值以及12个月为移动窗口的平均值绘图。

EWMA

简单移动平均值具有一些缺点:

这里的x_{t-i}代表输入(其实我这里也不太懂是什么输入),代表着距离当前时间点t前i个单位的输入的影响,wi就是这个距离为i的权值。

EW函数支持两种,一种是默认adjust=True,在这种情况下,距离为i的滞后对t的权值
这样以上的公式可以写成:

如果adjust=False,那么就是另外一种计算方式:


相当于使用权重:


在这里其实是类似于之前的ARIMA模型,认为当前值是跟前面的一项有关,并且加上当前的误差项。
具体有进一步的推导,参考这篇文章
接下来要注意


,alpha可以从以下这些值当中取。
在这里s代表移动平均值所涉及的跨度,c代表移动跨度s的一半,

,h是指权重项衰减到原有的一半的时候所需的时间大小。
代码部分。

df['12_span_ewm']=df['Thousands of Passengers'].ewm(span=12).mean()
df[['12_span_ewm', 'Thousands of Passengers']].plot(style=['--', '-'], color=['darkgreen','darkred'])

可以看得出相对于简单的移动平均值,指数权值化后的移动平均值具有更加明显的季节性,与原有的数据更加贴合。
关于这部分还有很多需要学习的,目前只是入门。

三、ETS模型

我们还可以通过对原始数据按照Error、Trend和Seasonality三部分来分解,具体原理可以参考这篇文章
ETS模型分为加法和乘法模型,如果趋势Trend是线性增长的关系,那么就用加法模型additive,否则非线性则用multiplicative乘法模型。具体用法是用seasonal_decompose,传入数据,以及对应的模型参数model。

from statsmodels.tsa.seasonal import seasonal_decompose
result=seasonal_decompose(df['Thousands of Passengers'], model='multiplicative')
result.plot()
plt.show()

result包括四部分内容,一个是观察值,趋势,季节性的值还有残差。残差可以认为是trend和观察值之间的差距。

上一篇下一篇

猜你喜欢

热点阅读