文章目录
- 前言
- 时间序列分析
- 时间序列预测简介
- 常用时间序列分析模型
- 数据预处理
- 序列检验方法
- 为什么只进行季节因素的分解?
- 如何根据序列图来判断模型的乘性或加性?
- ARIMA模型
- 实例一:
- 数据源准备
- 做出时序图
- 几种数据分析方法
- (1)朴素法
- (2)简单平均法
- (3)霍尔特(Holt)线性趋势法
- (4)Holt-Winters季节性预测模型
- (5)自回归移动平均模型(ARIMA)
- 相关概念速查
- 时间序列分析的性质
- 白噪声
- 平稳性
- 时间序列转换
- 时间序列的ARMA模型
- 典型的时间序列的性质
- 单变量时间序列
- 估计ARMA模型
- 自相关函数(ACF)与偏自相关函数(PACF)
- Q检验
- 残差诊断
- 信息准则
- 时间序列的趋势
- 季节性时间序列
前言
这两天,又接收到了不少新的讯息。我是越来越佩服“梦想橡皮檫”,檫哥了(打开周榜/总榜很好找,前排),他居然能用几年的时间来打磨一个系列。别说收39块,就是原价99我也买了,不为啥,就凭人家打磨了三年的毅力,我服!!!
想想我自己,曾经也有几个机会摆在我面前,但是我都放弃了,告诉自己:急流勇退。。。 好吧,我要像檫哥学习,认真的打磨一个系列。
但是我又不知道做什么系列,深思熟虑之后,那就:“打开我的收藏夹”系列吧。早晚有一天,我会把这个系列打磨的可以拿来卖。
时间序列分析啊,我这功力不足,就花两倍的时间来整理吧。
时间序列分析
时间序列预测简介
时间序列是在定期的时间间隔内记录度量的序列。
根据频率,时间序列可以是每年(例如:年度预算),每季度(例如:支出),每周(例如:销售数量),每天(例如天气),每小时(例如:股票价格),分钟(例如:来电提示中的呼入电话),甚至是几秒钟(例如:网络流量)。
常用时间序列分析模型
很遗憾,我们今天可能只能讲ARIMA模型,或者还能加上一两个,拭目以待。 ARIMA模型是指将非平稳时间序列转化为平稳时间序列,然后将结果变量做自回归(AR)和自平移(MA)。
数据预处理
时间序列分析之前,需要进行序列的预处理,包括纯随机性和平稳性检验。根据检验结果可以将序列分为不同的类型,采取不同的分析方法。
这种怎么弄呢?把我们写代码的思维带进来,其实没那么玄乎,不就是条件判断嘛:
代码语言:javascript复制if 检验序列A是白噪声序列:
return null;
elif 检验序列A是平稳非白噪声序列:
return ARIMA检验
else:
转变为平稳序列
return ARIMA检验
至于检验方法:
序列检验方法
(1)白噪声检验方法
实际上纯随机性序列的样本自相关系数不会绝对为零,但是很接近零,并在零附近随机波动。 常用的检验统计量有Q统计量、LB统计量,由样本各延迟期数的自相关系数,可以计算出检验统计量,然后计算对应的p值,如果p值大于显著性水平α(0.05),则表示接受原假设,是纯随机序列,停止分析。
(2)平稳性检验方法
如果时间序列在某一常数附近波动且波动范围有限,即有常数均值和常数方差,并且延迟k期的序列变量的自协方差和自相关系数是相等的,或者说延迟k期的序列变量之间的影响程度是一样的,则称该时间序列为平稳序列。
判断方法一:根据自相关图、偏自相关图自己看。这样难免有失偏颇,何况我们还没到那一步。 判断方法二:ARIMA定阶。
(1)计算自相关系数(ACF)和偏自相关系数(PACF) (2)ARMA模型识别,也叫模型定阶,由AR(p)模型、MA(q)模型和ARMA(p,q)的自相关系数和偏自相关系数的性质,选择合适的模型。
(3)估计模型中未知参数的值,并进行参数检验 (4)模型检验 (5)模型优化 (6)模型应用:进行短期预测。
我们当时也就学了这些(可能是我当时就学了这些)。
(3)非平稳时间序列分析
把所有序列的变化都归结为四个因素,长期趋势、 季节变动、 循环变动和随机变动的综合影响。 随机时序分析可以建立的模型有 ARIMA模型、残差自回归模型、季节模型、异方差模型等。
通常情况下,我们考虑进行季节因素的分解,也就是将季节变动因素从原时间序列中去除,并生成由剩余三种因素构成的序列来满足后续分析需求。
为什么只进行季节因素的分解?
代码语言:javascript复制时间序列中的长期趋势反映了事物发展规律,是重点研究的对象;
循环变动由于周期长,可以看做是长期趋势的反映;
不规则变动由于不容易测量,通常也不单独分析。
季节变动有时会让预测模型误判其为不规则变动,从而降低模型的预测精度
综上所述:当一个时间序列具有季节变动特征时,在预测之前会先将季节因素进行分解。
代码语言:javascript复制定义日期标示变量:即先将序列的时间定义好,才能分析其时间特征。
了解序列发展趋势:即序列图,确定乘性还是加性
进行季节因素分解
建模
分析结果解读
预测
如何根据序列图来判断模型的乘性或加性?
代码语言:javascript复制如果随着时间的推移,序列的季节波动变得越来越大,则建议使用乘法模型。
如果序列的季节波动能够基本维持恒定,则建议使用加法模型。
(关于这些,后面用SPSS来讲)
(这里先不讲其他的模型,为什么呢?可以翻到前面去看一下,ARIMA模型的第一步就是使得模型平稳,如果在两次差分之后还是无法平稳,那我们再议。)
如何使得序列平稳呢?最常见的方式就是差分了。
ARIMA模型
这一块儿讲一些概念,实操的话下面再开一块儿。其实上面也涉及到不少了了,这里就补全一下上面遗漏的点吧。
“ARIMA”实际上并不是一整个单词,而是一个缩写。其全称是:Autoregressive Integrated Moving Average Model,即自回归移动平均模型。它属于统计模型中最常见的一种,用于进行时间序列的预测。其原理在于:在将非平稳时间序列转化为平稳时间序列的过程中,将因变量仅对它的滞后值以及随机误差项的现值和滞后值进行回归所建立的模型。
ARIMA模型与ARMA模型的区别:ARMA模型是针对平稳时间序列建立的模型。ARIMA模型是针对非平稳时间序列建模,需要对时间序列先做差分,平稳后再建立ARMA模型。
代码语言:javascript复制拖尾:始终有非零取值,不会在k大于某个常数后就恒等于零(或在0附近随机波动)
截尾:在大于某个常数k后快速趋于0为k阶截尾
代码语言:javascript复制AR模型:自相关系数拖尾,偏自相关系数截尾;
MA模型:自相关系数截尾,偏自相关函数拖尾;
ARMA模型:自相关函数和偏自相关函数均拖尾。
其实截尾拖尾我们这水平也不那么容易看出来,上面不是说了嘛,还会带有主观性。 所以我们还是交给计算机帮我们判断参考吧。
AR模型对应p,根据偏自相关图的截尾位置确定p,ACF与PACF图的横轴均从0开始,如果PACF在2时还在置信区间以外,从3开始之后均在置信区间以内,则定p为2。MA模型对应q,根据自相关图的截尾位置确定q,确定方法同p。
实例一:
点此进入案例来源
数据源准备
无数据或数据质量低,会影响模型预测效果。在建立的一个合理的模型之前,对数据要进行收集,再在搜集的数据基础上进行预处理。
有了数据,但是有一部分特征是算法不能直接处理的,还有一部分数据是算法不能直接利用的。
点这里·数据集下载
读取出数据集:
代码语言:javascript复制import pandas as pd
df = pd.read_csv('jetrail.csv')
df.head()
print(df.shape)
依照上面的代码,我们获得了 2012-2014 年两年每个小时的乘客数量。为了解释每种方法的不同之处,以每天为单位构造和聚合了一个数据集。
代码语言:javascript复制从 2012 年 8 月- 2013 年 12 月的数据中构造一个数据集。
前 14 个月( 2012 年 8 月- 2013 年 10 月)用作训练数据,后两个月(2013 年 11 月 – 2013 年 12 月)用作测试数据。
以每天为单位聚合数据集。
做出时序图
代码语言:javascript复制import pandas as pd
import matplotlib.pyplot as plt
df = pd.read_csv('jetrail.csv', nrows=11856)
# Creating train and test set
# Index 10392 marks the end of October 2013
train = df[0:10392] #训练数据
test = df[10392:] #测试数据
# Aggregating the dataset at daily level
df['Timestamp'] = pd.to_datetime(df['Datetime'], format='%d-%m-%Y %H:%M') # 4位年用Y,2位年用y
df.index = df['Timestamp']
df = df.resample('D').mean() # 按天采样,计算均值
train['Timestamp'] = pd.to_datetime(train['Datetime'], format='%d-%m-%Y %H:%M')
train.index = train['Timestamp']
train = train.resample('D').mean()
test['Timestamp'] = pd.to_datetime(test['Datetime'], format='%d-%m-%Y %H:%M')
test.index = test['Timestamp']
test = test.resample('D').mean()
# Plotting data
train.Count.plot(figsize=(15, 8), title='Daily Ridership', fontsize=14)
test.Count.plot(figsize=(15, 8), title='Daily Ridership', fontsize=14)
plt.show()
几种数据分析方法
详见:点此进入案例来源 我相信,大部分人点过去也会回来的。
其中代码做了些许微调,处理了一些警告。
(1)朴素法
如果数据集在一段时间内都很稳定,我们想预测第二天的价格,可以取前面一天的价格,预测第二天的值。这种假设第一个预测点和上一个观察点相等的预测方法就叫朴素法。
朴素法并不适合变化很大的数据集,最适合稳定性很高的数据集。
(2)简单平均法
我们经常会遇到一些数据集,虽然在一定时期内出现小幅变动,但每个时间段的平均值确实保持不变。这种情况下,我们可以预测出第二天的价格大致和过去天数的价格平均值一致。这种将预期值等同于之前所有观测点的平均值的预测方法就叫简单平均法。
将过去观察值赋予不同权重的方法就叫做加权移动平均法。加权移动平均法其实还是一种移动平均法,只是“滑动窗口期”内的值被赋予不同的权重,通常来讲,最近时间点的值发挥的作用更大了。即
(3)霍尔特(Holt)线性趋势法
每个时序数据集可以分解为相应的几个部分:趋势(Trend),季节性(Seasonal)和残差(Residual)。任何呈现某种趋势的数据集都可以用霍尔特线性趋势法用于预测。
代码语言:javascript复制import statsmodels.api as sm
sm.tsa.seasonal_decompose(train['Count']).plot()
result = sm.tsa.stattools.adfuller(train['Count'])
plt.show()
霍尔德线性探测算法:
我们将这两个方程相加,得出一个预测函数。我们也可以将两者相乘而不是相加得到一个乘法预测方程。当趋势呈线性增加和下降时,我们用相加得到的方程;当趋势呈指数级增加或下降时,我们用相乘得到的方程。
实践操作显示,用相乘得到的方程,预测结果会更稳定,但用相加得到的方程,更容易理解。
代码语言:javascript复制from statsmodels.tsa.api import Holt
y_hat_avg = test.copy()
fit = Holt(np.asarray(train['Count'])).fit(smoothing_level=0.3, smoothing_trend=0.1)
y_hat_avg['Holt_linear'] = fit.forecast(len(test))
plt.figure(figsize=(16, 8))
plt.plot(train['Count'], label='Train')
plt.plot(test['Count'], label='Test')
plt.plot(y_hat_avg['Holt_linear'], label='Holt_linear')
plt.legend(loc='best')
plt.show()
这种方法能够准确地显示出趋势,因此比前面的几种模型效果更好。如果调整一下参数,结果会更好。
(4)Holt-Winters季节性预测模型
它是一种三次指数平滑预测,其背后的理念就是除了水平和趋势外,还将指数平滑应用到季节分量上。 Holt-Winters季节性预测模型由预测函数和三次平滑函数——一个是水平函数ℓt,一个是趋势函数bt,一个是季节分量 st,以及平滑参数α,β和γ。
其中 s 为季节循环的长度,0≤α≤ 1, 0 ≤β≤ 1 , 0≤γ≤ 1。水平函数为季节性调整的观测值和时间点t处非季节预测之间的加权平均值。趋势函数和霍尔特线性方法中的含义相同。季节函数为当前季节指数和去年同一季节的季节性指数之间的加权平均值。
代码语言:javascript复制from statsmodels.tsa.api import ExponentialSmoothing
y_hat_avg = test.copy()
fit1 = ExponentialSmoothing(np.asarray(train['Count']), seasonal_periods=7, trend='add', seasonal='add', ).fit()
y_hat_avg['Holt_Winter'] = fit1.forecast(len(test))
plt.figure(figsize=(16, 8))
plt.plot(train['Count'], label='Train')
plt.plot(test['Count'], label='Test')
plt.plot(y_hat_avg['Holt_Winter'], label='Holt_Winter')
plt.legend(loc='best')
plt.show()
我们可以看到趋势和季节性的预测准确度都很高。
(5)自回归移动平均模型(ARIMA)
指数平滑模型都是基于数据中的趋势和季节性的描述,而自回归移动平均模型的目标是描述数据中彼此之间的关系。ARIMA的一个优化版就是季节性ARIMA。它像Holt-Winters季节性预测模型一样,也把数据集的季节性考虑在内。
建议你在解决问题时,可以依次试试这几种模型,看看哪个效果最好。我们从上文也知道,数据集不同,每种模型的效果都有可能优于其它模型。因此,如果一个模型在某个数据集上效果很好,并不代表它在所有数据集上都比其它模型好。
相关概念速查
时间序列分析的性质
频率、时间跨度、均值、方差、协方差是用来描述时间序列的基本指标。
白噪声
白噪声,是不含任何有助于估计信息(除其方差和高阶矩)的时间序列。
平稳性
平稳性是时间序列的一个重要性质。如果一个时间序列是平稳的,那么发生在时间 t 上的任何冲击,随着时间的推移会有一个递减效应。 最后会消失在时间 t s,s->∞。 这种特性称之为均值回归。
非平稳的时间序列却并非如此,冲击的影响要么在未来所有的时间持续呈现相同的规模,要么被看做序列在接下来的时间中“激增”的源头。
注意白噪声序列虽然是平稳的,但是平稳序列是不会自动成为白噪声序列的。要想成为白噪声,我们需要添加所有的协方差为0的附加条件。
时间序列转换
差分平稳时间序列差分后平稳化,趋势平稳序列去趋势后平稳化,结构突变趋势的平稳序列通过结构变化去趋势之后平稳化(更多?往下看就更多)
在差分和去趋势之前,最常用的转换方式就是将数据取对数,这样可以处理一些非线性趋势序列或将序列的指数趋势降低到线性趋势。
代码语言:javascript复制当数据呈指数增长时要对数据取自然对数;
差分是将非平稳序列转换为平稳序列的最常用的方法:
一阶差分 ∆y₂ = y₂ - y₁ (意会一下,这里下标及就找到这俩符号了)
二阶差分 ∆²y₂ = ∆y₂ - ∆y₁
再高阶差分也没有什么意义了,一阶差分我们得到的是速度,二阶差分我们得到的是加速度,三阶?三阶差分图个什么?
去趋势是为了消除数据中的线性趋势或高阶趋势的过程。为了消除时间序列的趋势,我们进行一个关于常数、时间t、t的高阶幂的回归。
时间序列的ARMA模型
ARMA模型是用来估计平稳的不规则波动或时间序列季节性变动的最常见的模型。ARMA是移动平均自回归模型的简称,它是自回归模型和移动平均模型的组合。
典型的时间序列的性质
(1)趋势 经济时间序列通常包含一个趋势。
(2)趋势突变和结构变化
(3)均值上下浮动
(4)冲击的高持久性
(5)波动不是常数
(6)非平稳
(7)多元时间序列的联动性
单变量时间序列
估计ARMA模型
自相关函数(ACF)与偏自相关函数(PACF)
自相关函数和偏自相关函数,有助于确定ARMA(p,q)数据生成过程的参数p和q。
Q检验
在实践中,样本ACF和PACF往往是不确定的,因此发现一个明确的模式是很难的。 为了增加正确选择滞后期数的机会,我们可以使用另一个工具:基于Q统计量的Q检验提供一个更正确的方式来评估正确的滞后期数。
残差诊断
正确模拟数据生成过程的模型的残差应该是白噪声。这意味着它们不应该包含任何有效的信息。白噪声所有的自相关函数都等于0,因此使用Q检验来检验一个时间序列是否是白噪声只是一个合适但是有限的工具(不看屏幕不看键盘盲打一段)。
信息准则
有时候,会出现好几种可以选的模型。 这时候,我们选择最简约的,往往能够较好的拟合数据的动态。
时间序列的趋势
确定性趋势 随机性趋势 随机和确定性趋势
在实际应用中估计程序:
代码语言:javascript复制检测趋势
通过合适的转换消除趋势
估计转换的时间序列
季节性时间序列
包含季节性模式的时间序列不一定是非平稳的,但是,当估计数据生成过程时,如果我们忽视了季节性模式的存在,我们也不会达到最简约的模型。
后面会出一篇基于R语言的时间序列分析,基于SPSS的时间序列分析。 谁知道呢。