微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Python-时间序列分析

文章目录


金融数据常见类型为:

  1. 截面数据
  2. 时间序列数据
  3. 面板数据

时间数据序列时序图

import pandas as pd
import matplotlib.pyplot as plt

Index = pd.read_table('TRD_Index.txt', sep='\t', index_col='Trddt')
SHindex = Index[Index.Indexcd == 1]
# 提取上证综指的收盘指数数据
Clsindex = SHindex.Clsindex
# 将收盘指数转换成时间序列格式
Clsindex.index = pd.to_datetime(Clsindex.index)
# 最后,绘制时间序列图
Clsindex.plot()
plt.show()

选取特点时期的时间序列数据

将index转换为时间序列,即可根据特定的条件从时间序列数据中提取出子集。

# 截取2014年10月8日到10月31日的数据
SHindex.index = pd.to_datetime(SHindex.index)
SHindexPart = SHindex['2014-10-08':'2014-10-31']
# 截取2015年数据
SHindex2015 = SHindex['2015']
# 选取2015年初以后的数据
SHindexAfter2015 = SHindex['2015':]
# 选取2015年以前的数据
SHindexBefore2015 = SHindex[:'2014-12-31']
# 选取2014年9月到年底的数据
SHindex9End = SHindex['2014-09':'2014']

在这里插入图片描述

时间序列描述性统计

Clsindex.hist()
plt.show()

# 求最大值
Clsindex.max()
# 求最小值
Clsindex.min()
# 求均值
Clsindex.mean()
# 求中位数
Clsindex.median()
# 求标准差
Clsindex.std()

# 总结数据分布情况
print(Clsindex.describe())
# count     311.000000
# mean     2490.001161
# std       563.700980
# min      1991.253000
# 25%      2052.140500
# 50%      2224.654000
# 75%      2996.395000
# max      4135.565000
# Name: Clsindex, dtype: float64

在这里插入图片描述

时间序列基本性质

自相关性

即,一个时间序列的两个不同时间点的变量是否有关联。

自协方差 - Autocovariance Function

自相关系数 - Autocorrelation Coefficient Function

偏自相关系数 - Partial Autocorrelation Coefficient Function

Python操作

from statsmodels.tsa import stattools
from statsmodels.graphics.tsaplots import *
import pandas as pd
import matplotlib.pyplot as plt

data = pd.read_csv('TRD_Index.txt', sep='\t', index_col='Trddt')
sh_index = data[data.Indexcd == 1]
sh_index.index = pd.to_datetime(sh_index.index)
sh_return = sh_index.Retindex

acfs = stattools.acf(sh_return)
pacfs = stattools.pacf(sh_return)
plot_acf(sh_return, use_vlines=True, lags=30)
plot_pacf(sh_return, use_vlines=True, lags=30)
plt.show()

在这里插入图片描述

在这里插入图片描述

平稳性

只有基于平稳的时间序列的预测才是有效的。

强平稳

即,该序列的任何统计性质都不会随时间改变,理论和实际应用中都很难检验。

弱平稳

满足三个条件即可:

  1. 序列的均值为常数
  2. 存在二阶矩
  3. l 阶自协方差的大小不随着 t 值变动,只与 l 值有关

Python检验时间序列平稳性

# method 1 - 绘时序图

import pandas as pd
import matplotlib.pyplot as plt

sh_close = sh_index.Clsindex
sh_close.plot()
plt.show()
sh_return.plot()
plt.show()

下图⇩前半段平稳,后半段不平稳


下图⇩总体平稳

# method 2 - 绘制ACF/PACF图

from statsmodels.graphics.tsaplots import *

plot_acf(sh_return, use_vlines=True, lags=30)
plot_pacf(sh_return, use_vlines=True, lags=30)
plot_acf(sh_close, use_vlines=True, lags=30)
plt.show()

一般平稳的时间序列,其自相关系数或者偏自相关系数大都快速减小至0附近或者在某一阶段后变为0。

↓↓↓ sh_return较为平稳;sh_close不平稳。

在这里插入图片描述


在这里插入图片描述


在这里插入图片描述

# method 3 - 单位根检验[常见方法有:ADF,DF,PP]

from arch.unitroot import ADF

adf_sh_return = ADF(sh_return)
print(adf_sh_return.summary().as_text())
adf_sh_close = ADF(sh_close)
print(adf_sh_close.summary().as_text())

↓↓↓ 统计量小于1%显著性水平下的临界值,所以拒绝原假设(序列非平稳)——即sh_return序列是平稳的。

在这里插入图片描述


↓↓↓ 统计量大于1%、5%、10%显著性水平下的临界值,所以无法拒绝原假设(序列非平稳)——即sh_close序列是非平稳的。

在这里插入图片描述

白噪声

即,白噪声序列一定是平稳的时间序列,均值为常数、方差为常数,其间隔大于0的自协方差都恒等于0[平稳性序列的自协方差只与时间间隔相关,而不与时间的起始点相关的要求]。

btw,白噪声只代表序列各期无相关性,不代表各期之间相互独立。

import matplotlib.pyplot as plt
import numpy as np

white_noise = np.random.standard_normal(size=500)
plt.plot(white_noise, c='b')
plt.title('white noise')
plt.show()

在这里插入图片描述

Python——白噪声检验__Ljung-Box检验

Ljung-Box检验的原假设:序列为纯随机序列/白噪声序列。

from statsmodels.tsa import stattools
import pandas as pd

data = pd.read_csv('TRD_Index.txt', sep='\t', index_col='Trddt')
sh_index = data[data.Indexcd == 1]
sh_index.index = pd.to_datetime(sh_index.index)
sh_return = sh_index.Retindex
sh_close = sh_index.Clsindex

ljung_Box1 = stattools.q_stat(stattools.acf(sh_return)[1:13], len(sh_return))
print(ljung_Box1[1][-1])  # 0.4936174964502932--接受原假设,是随机序列
ljung_Box2 = stattools.q_stat(stattools.acf(sh_close)[1:13], len(sh_close))
print(ljung_Box2[1][-1])  # 0.0--序列存在自相关性

时间序列预测

移动平均预测

  1. 简单移动平均
  2. 加权移动平均
  3. 指数加权移动平均

ARMA模型预测

模型ACFPACF
AR(p)拖尾 (几何型或震荡型)p阶截尾
MA(q)q阶截尾拖尾 (几何型或震荡型)
ARMA(p,q)拖尾 (几何型或震荡型)拖尾 (几何型或震荡型)
import pandas as pd
import matplotlib.pyplot as plt

cpi = pd.read_csv('CPI.csv', index_col='time')
cpi.index = pd.to_datetime(cpi.index)
print(cpi.shape)  # (161, 1)
cpi = cpi.sort_index()
cpi.plot(title='CPI 2001-2014')
plt.show()

在这里插入图片描述

from arch.unitroot import ADF

# 选取训练集,评价模型准确度
cpi_train = cpi[:-3].dropna()
print(ADF(cpi_train, max_lags=10).summary().as_text())

在这里插入图片描述


所以我们可以认为序列平稳。

from statsmodels.tsa import stattools

ljungBox = stattools.q_stat(stattools.acf(cpi_train)[1:12], len(cpi_train))
print(ljungBox[1][-1]) # 0.0005560128948515362<0.05 ---- 拒绝原假设,不是白噪声序列

识别ARMA模型的p和q。

from statsmodels.graphics.tsaplots import *

ax1 = plt.subplot(211)
plot_acf(cpi_train, lags=30, ax=ax1)
ax2 = plt.subplot(212)
plot_pacf(cpi_train, lags=30, ax=ax2)
plt.show()

在这里插入图片描述


有图像可知,ACF&PACF均为拖尾。
判断p,q取值,运用AIC准则选出AIC值最小的模型。

from statsmodels.tsa import arima_model

model_1 = arima_model.ARIMA(cpi_train, order=(1, 0, 1)).fit()
print(model_1.summary())

↓↓↓

(p,q)(1,1)(1,2)(2,1)(2,2)(3,1)(3,2)(3,3)
AIC308.678310.521307.933309.271310.972308.496310.484

所以选择ARMA(2,1)模型。

接下来,进行模型诊断。

  1. 系数显著性检验
  2. 残差序列是否为白噪声的检验
# Step 1

print(model_3.conf_int())

#                     0           1
# const      100.216756  100.286655
# ar.L1.CPI    1.101874    1.404685
# ar.L2.CPI   -0.458490   -0.146583
# ma.L1.CPI   -1.039059   -0.960941

所有系数的置信区间都不包含0,因此5%(conf_int()函数认α=0.05)置信水平下,所有系数都是显著的。

# Step 2

import math

std_resid = model_3.resid / math.sqrt(model_3.sigma2)
plt.plot(std_resid)
plot_acf(std_resid, lags=20)
plt.show()

在这里插入图片描述


在这里插入图片描述


↑↑↑无法确定残差是不是白噪声序列。
因此,作LB检验。

ljung_Box = stattools.q_stat(stattools.acf(std_resid)[1:20], len(std_resid))
print(ljung_Box)

查看LB的p值可知,12阶后存在p<5%。因此模型的残差不是一个白噪声序列。

再查看残差自相关系数图。

plot_acf(std_resid, lags=40)
plt.show()

在这里插入图片描述


↑↑↑可以发现12、24、36阶系数显著,由此可判断需要季节性调整——ARIMA模型。

print(model_3.forecast(3)[0], '\n', cpi[-3:])

# [100.27850933 100.21018    100.19155332] 
#                CPI
# time             
# 2014-03-01   99.5
# 2014-04-01   99.7
# 2014-05-01  100.1

另外,如果利用模型对未来的序列值进行预测,可以用forecast函数,但此案例中根据训练集建模的预测结果并不是很好。

平稳时间序列建模

import pandas as pd
from arch.unitroot import ADF
from statsmodels.tsa import stattools

da_tang = pd.read_csv('Datang.csv', index_col='time')
da_tang.index = pd.to_datetime(da_tang.index)
returns = da_tang.datang['2014-01-01':'2016-01-01']
# 检验序列是否平稳
print(ADF(returns).summary())
# 检验序列是否为白噪声
print(stattools.q_stat(stattools.acf(returns)[1:12], len(returns))[1])

↓↓↓↓↓平稳&不是白噪声

在这里插入图片描述

# 确认pq值
print(stattools.arma_order_select_ic(returns, max_ma=4))

在这里插入图片描述

# ARMA(1,0)建模

from statsmodels.tsa import arima_model

model = arima_model.ARIMA(returns, order=(1, 0, 0)).fit()
print(model.summary())

print(model.conf_int())
#                      0         1
# const        -0.331197  0.614627
# ar.L1.datang  0.053630  0.236092

在这里插入图片描述

# 残差诊断

import math
from statsmodels.graphics.tsaplots import *
import matplotlib.pyplot as plt

std_resid = model.resid / math.sqrt(model.sigma2)
plt.plot(std_resid)
plot_acf(std_resid, lags=20)
plt.show()

l_b = stattools.q_stat(stattools.acf(std_resid)[1:12], len(std_resid))
print(l_b[1])
# [0.99403632 0.9995103  0.77556433 0.53779996 0.60674717 0.69723692
#  0.70864821 0.21276688 0.22902475 0.10008502 0.1410863 ]

残差项之间不存在显著的自相关性,对于LB检验也有较高的p值,所以基本上模型符合要求。
↓↓↓↓↓↓

在这里插入图片描述


在这里插入图片描述

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐