关于算法:Python和R使用指数加权平均EWMAARIMA自回归移动平均模型预测时间序列

47次阅读

共计 9431 个字符,预计需要花费 24 分钟才能阅读完成。

原文链接:http://tecdat.cn/?p=21773

概述

  • 学习创立工夫序列预测的步骤
  • 关注 Dickey-Fuller 测验和 ARIMA(自回归挪动均匀)模型
  • 从实践上学习这些概念以及它们在 python 中的实现

介绍

工夫序列(从现在起称为 TS)被认为是数据迷信畛域中鲜为人知的技能之一。

应用 python 创立工夫序列预测

咱们应用以下步骤:

  1. 工夫序列是什么
  2. 加载和解决工夫序列
  3. 如何测验工夫序列的平稳性?
  4. 如何使工夫序列安稳?
  5. 预测工夫序列

1. 什么是工夫序列?

顾名思义,TS 是以固定工夫距离收集的数据点的汇合。

对这些数据进行剖析,以确定长期趋势,从而预测将来或进行其余模式的剖析。

然而什么使 TS 不同于惯例回归问题呢?

  1. 它取决于工夫。所以线性回归模型的根本假如,即观测值是独立的,在这种状况下不成立。
  2. 随着一个减少或缩小的趋势,大多数 TS 具备某种模式的季节性趋势,即特定于特定工夫范畴的变动。例如,如果你看到一件羊毛夹克的销售随着工夫的推移,你肯定会发现夏季的销售量更高。

因为其固有的个性,对其进行剖析波及到各种步骤。上面将具体探讨这些问题。让咱们从在 Python 中加载一个 TS 对象开始。咱们应用航空乘客数据。

2 加载和解决工夫序列

Pandas 有专门的库来解决 TS 对象,特地是 datatime64[ns]类,它存储工夫信息,咱们能够疾速执行一些操作。让咱们从启动所需的库开始:

 %matplotlib inline

from matplotlib.pylab import rcParams 


data = pd.read_csv('AirPassengers.csv', parse_dates=['Month'], index_col='Month') 

让咱们逐个了解这些论点:

  1. parse  dates:指定蕴含日期工夫信息的列。如上所述,列名是 ’Month’。
  2. index_col:将 Pandas 用于 TS 数据背地的一个要害思维是,索引必须是形容日期工夫信息的变量。所以这个参数通知 panda 应用 ’Month’ 列作为索引。
  3. date parse:指定一个函数,将输出字符串转换为 datetime 变量。默认状况下,读取格局为“YYYY-MM-DD HH:MM:SS”的数据。如果数据不是此格局,则必须手动定义格局。相似于这里定义的 dataparse 函数的货色能够用于此目标。

当初咱们能够看到数据以 time 对象作为索引,#Passengers 作为列。咱们能够应用以下命令穿插查看索引的数据类型:

留神 dtype=’datetime[ns]’ 确认它是一个 datetime 对象。作为集体偏好,我会将列转换为 Series 对象,以避免每次应用 TS 时都援用列名称。

ts = data[‘#Passengers’] ts.head(10) 

在进一步探讨之前,我将探讨一些 TS 数据的索引技术。让咱们从抉择 Series 对象中的特定值开始。这能够通过以下两种形式实现:

#1. 指定索引为字符串常量:
ts['1949-01-01']

#2. 导入 datetime 库并应用 'datetime' 函数:
from datetime import datetime 

两者都将返回值“112”,这也能够从以前的输入中确认。假如咱们想要 1949 年 5 月之前的所有数据。这能够通过两种形式实现:

#1. 指定整个范畴:ts['1949-01-01':'1949-05-01']

#2. 如果其中一个索引位于开端,请应用“:”:ts[:'1949-05-01']

两者都将产生以下输入:

这里有两点须要留神:

  1. 与数字索引不同的是,完结索引蕴含在这里。例如,如果咱们将列表索引为[:5],那么它将返回索引处的值–[0,1,2,3,4]。但这里的索引“1949-05-01”蕴含在输入中。
  2. 必须对索引进行排序,能力使范畴发挥作用。

思考另一个须要 1949 年所有值的例子。这能够通过以下形式实现:

ts['1949'] 

月份局部被省略了。相似地,如果您抉择某个月的所有日期,则能够省略日期局部。
当初,让咱们持续剖析 TS。

3. 如何测验工夫序列的平稳性?

如果 TS 的统计个性(如均值、方差)随工夫放弃不变,则称其为安稳的。但为什么重要呢?大多数 TS 模型都假如 TS 是安稳的。直觉上,咱们能够假如,如果一个 TS 在一段时间内有一个特定的行为,那么它很有可能在未来也会有同样的行为。与非安稳序列相比,安稳序列的相干实践更为成熟和易于实现。
平稳性是应用十分严格的规范来定义的。然而,出于理论目标,咱们能够假如序列是安稳的,如果它随工夫具备恒定的统计个性,即:

  1. 恒定平均值
  2. 恒定方差
  3. 不依赖于工夫的自协方差。

我将跳过这些细节,因为在本文中对其进行了十分明确的定义。让咱们开始测试平稳性的办法。首先也是最重要的是简略地绘制数据并进行可视化剖析。能够应用以下命令绘制数据:

plt.plot(ts) 

很显著,随着一些季节性变动,数据总体呈上升趋势。然而,可能并不总是可能做出这样的视觉直观推断(咱们稍后会看到这样的状况)。因而,更正式地说,咱们能够应用以下办法查看平稳性:

  1. 绘制滚动统计:咱们能够绘制挪动平均值或挪动方差,看它是否随工夫变动。挪动平均值 / 方差,我的意思是,在任何时刻‘t’,咱们将取去年的平均值 / 方差,即过来 12 个月的平均值 / 方差。但这更像是一种视觉技术。
  2. Dickey-Fuller 测验:这是测验平稳性的统计测验之一。这里的零假如是 TS 是非安稳的。测验后果包含测验统计量和不同置信水平的一些临界值。如果“测验统计量”小于“临界值”,咱们能够回绝零假如并说序列是安稳的。

在这一点上,这些概念听起来可能不是很直观。
回到平稳性查看,咱们将应用滚动统计图以及 Dickey-Fuller 测验后果很多,所以我定义了一个函数,它以 TS 作为输出并为咱们生成它们。请留神,我绘制了标准差而不是方差,以放弃单位与平均值类似。

def test_stat(timeseries):
    
    orig = plt.plot(timeseries, color='blue',label='原始序列')
    mean = plt.plot(rolmean, color='red', label='滚动均匀')
    std = plt.plot(rolstd, color='black', label = '滚动标准差')
    plt.title('滚动平均数和标准偏差',fontproperties=myfont)

    
    #执行 Dickey-Fumer 测验:dftest = adfuller(timeseries, maxlag=13, regression='ctt', autolag='BIC') 

让咱们为输出序列运行它:

test_stat(ts) 

尽管标准差的变动很小,但平均值显著随工夫减少,这不是一个安稳序列。而且,测验统计量远大于临界值。请留神,应该比拟有符号的值,而不是绝对值。
下一步,咱们将探讨能够用来将这个 TS 转换安稳的办法。

4 如何使工夫序列安稳?

尽管许多 TS 模型都采纳平稳性假如,但理论工夫序列中简直没有一个是安稳的。统计学家们曾经找到了使序列安稳的办法,咱们当初就来探讨。实际上,要使一个序列齐全安稳简直是不可能的,但咱们要尽量靠近它。
让咱们理解是什么使 TS 不稳固。TS 的非平稳性有两个次要起因:

  1. 趋势 - 随工夫变动的平均值。例如,在这个例子中,咱们看到均匀而言,乘客人数随着工夫的推移而增长。
  2. 季节性 - 特定工夫范畴内的变动。因为加薪或节日的起因,人们可能有在特定月份呈现的偏向。

其基本原理是对序列中的趋势和季节性进行建模或预计,并从序列中去除这些趋势和季节性以失去安稳序列。而后统计预测技术就能够在这个序列上实现。最初一步是通过利用趋势和季节性束缚将预测值转换为原始规模。
留神:我将探讨一些办法。在这种状况下,有些可能工作得很好,而有些可能不行。但咱们的想法是把握所有的办法,而不是只关注手头的问题。
让咱们从趋势局部开始。

预计和打消趋势

缩小趋势的第一个技巧之一能够转换。例如,在这种状况下,咱们能够分明地看到存在显着的增长趋势。因而,咱们能够利用转换,以惩办更高的值,而不是较小的值。这些能够取对数,平方根,立方根等。在此处取对数转换简便简略:

np.log(ts) 

在这种简略的状况下,很容易看到数据的将来趋势。但在有乐音的状况下,它不是很直观。因而,咱们能够应用一些技术来预计或模仿这一趋势,而后将其从序列中删除。有很多办法能够做到这一点,其中最罕用的有:

  1. 聚合 - 取一段时间的平均值,如月 / 周平均值
  2. 平滑 - 取滚动平均值
  3. 多项式拟合 - 拟合回归模型

我将在这里探讨平滑,你应该尝试其余技术,以及可能解决其余问题。平滑是指采取滚动预计,即思考过来的几个实例。有很多种办法,但我将在这里探讨其中的两种。

挪动(滚动)均匀

在这种办法中,咱们依据工夫序列的频率取“k”间断值的平均值。这里咱们能够取过来一年的平均值,也就是最近 12 个值。pandas 有确定滚动统计的特定性能。

pd.rolling_mean(ts_log,12) 

红线示意滚动平均值。咱们从原来的数列中减去这个。留神,因为咱们取最初 12 个值的平均值,所以滚动平均值没有定义前 11 个值。这能够察看到:

 ts_log - moving_avg 

留神前 11 个是 Nan。让咱们删除这些 NaN 值并查看图以测验平稳性。

moving_avg_diff.dropna(inplace=True) 

这看起来是一个更好的系列。滚动值仿佛略有变动,但没有具体趋势。而且,测验统计量小于 5% 的临界值,所以咱们能够用 95% 的置信度说这是一个安稳序列。

加权挪动平均值(EWMA)

然而,这种办法的一个毛病是,时间段必须严格定义,在这种状况下,咱们能够取年平均数,但在预测股票价格等简单状况下,很难得出一个数字。所以咱们取一个“加权挪动平均值”,其中最近的值被赋予更高的权重。调配权重的办法有很多种,一种风行的办法是指数加权挪动平均法,即用衰减因子将权重调配给所有先前的值。请在此处查找详细信息。这能够实现为:

ewma(ts_log, half=12) 

请留神,这里的参数“半衰期”用于定义指数衰减的量。这只是一个假如,很大水平上取决于业务畛域。其余参数,如跨度和质心,也能够用来定义衰变,这将在下面共享的链接中探讨。当初,让咱们从序列中删除此项并查看平稳性:

 ts_log - expwighted_avg 

这个 TS 在平均值和标准偏差上的变动甚至更小。此外,测验统计量小于 1% 的临界值,这比前一种状况要好。留神,在这种状况下,不会呈现缺失值,因为从开始算起的所有值都是给定的权重。所以即便没有以前的值,它也能工作。

打消趋势和季节性

以前探讨过的简略的趋势缩小技术并不适用于所有状况,特地是那些具备高季节性的状况。让咱们探讨两种打消趋势和季节性的办法:

  1. 差分 - 用特定的时间差取差分
  2. 合成–对趋势和季节性进行建模,并将其从模型中移除。

差分

解决趋势性和季节性最罕用的办法之一是差分。在这项技术中,咱们取某一时刻的观测值与前一时刻的观测值之差。这在改善平稳性方面成果很好。一阶差分可按如下形式进行:

ts_log - ts_log.shift() 

这仿佛大大减少了这一趋势。让咱们应用绘图进行验证:

咱们能够看到平均值和标准差随工夫的变动很小。同时,Dickey-Fuller 测验统计量小于 10% 的临界值,因而 TS 是安稳的,置信度为 90%。咱们也能够取二阶或三阶差,在某些利用中可能会失去更好的后果。

合成

在这种办法中,趋势和季节性都被别离建模,序列的其余部分被返回。我将跳过统计数据得出后果:

decompose(ts_log)

 decomposition.trend
 decomposition.seasonal
 decomposition.resid 

在这里咱们能够看到趋势,季节性是从数据中分离出来的,咱们能够对残差进行建模。让咱们查看残差的平稳性:

ts_log_decompose = residual 

Dickey-Fuller 测验统计量显著低于 1% 的临界值。所以这个 t 十分靠近安稳。另外,您应该留神到,在本例中,将残差转换为将来数据的原始值不是很直观。

5 预测工夫序列

咱们看到了不同的技术,所有这些技术都相当好地使 TS 安稳。因为这是一种十分风行的技术,所以让咱们在差分后在 TS 上建设模型。此外,在这种状况下,将噪声和季节性增加回预测残差中绝对容易。执行趋势和季节性预计技术后,可能有两种状况:

  1. 一个严格安稳的序列,值之间没有依赖关系。这是一个简略的例子,咱们能够将残差建模为白噪声。但这是十分常见的。
  2. 值之间有显著相关性的一系列。在这种状况下,咱们须要应用一些统计模型,如 ARIMA 来预测数据。

让我简略介绍一下 ARIMA。我不会深刻探讨技术细节,但如果您心愿更无效地利用它们,您应该具体理解这些概念。ARIMA 代表自回归综合挪动平均线。安稳工夫序列的 ARIMA 预测只不过是一个线性 (相似于线性回归) 方程。预测因子取决于 ARIMA 模型的参数(p,d,q):

  1. AR(自回归)项数 (p): AR 项是因变量的滞后。例如,如果 p 为 5,x(t) 的预测因子为 x(t-1)….x(t-5)。
  2. 挪动平均线项数 (q): 挪动平均线项是预测方程中的滞后预测误差。例如,如果 q 是 5,x(t) 的预测因子将是 e(t-1)….e(t-5),其中 e(i)是挪动均匀在第一个霎时和理论值之间的差值。
  3. 差分的数量(d): 这些是非季节性差分的数量,即在这种状况下,咱们取一阶差分。所以咱们能够传递这个变量,让 d = 0 或者传递原始变量,让 d =1。两者都会产生雷同的后果。

这里的一个重要问题是如何确定“p”和“q”的值。咱们先来讨论一下。

  1. 自相干函数(ACF):它是 TS 与本身滞后之间相关性的度量。例如,在滞后 5 时,ACF 会将“t1”…“t2”时刻的序列与“t1-5”…“t2-5”时刻的序列进行比拟(t1- 5 和 t2 是起点)。
  2. 偏自相干函数(PACF):它测量了 TS 之间的相关性,但在打消了曾经解释的变动之后。例如,在滞后 5,它将查看相关性,但打消曾经由滞后 1 到 4 解释的影响。

差分后 TS 的 ACF 和 PACF 图能够绘制为:

 #绘图 ACF:plt.subplot(121) 
plt.plot(lag_acf)
plt.axhline(y=0,linestyle='--',color='gray')

#绘图 PACF:plt.subplot(122)
plt.plot(lag_pacf)
plt.axhline(y=0,linestyle='--',color='gray')

plt.tight_layout()

在这个图中,0 两边的两条虚线是置信区间。这些可用于确定“p”和“q”值,如下所示:

  1. p–PACF 图表第一次穿过置信区间下限的滞后值。如果你仔细观察,在这种状况下,p=2。
  2. q–ACF 图表首次穿过置信区间下限的滞后值。如果你仔细观察,在这种状况下,q=2。

当初,让咱们建设 3 种不同的 ARIMA 模型,既思考个体效应,也思考组合效应。我也会输入 RSS。请留神,这里的 RSS 是残差值,而不是理论序列。
咱们须要先加载 ARIMA 模型:

能够应用 ARIMA 的 order 参数指定 p、d、q 值,该参数采纳元组(p、d、q)。让咱们模仿 3 个案例:

AR 模型

model.fit(disp=-1)  
plt.plot(ts_log_diff) 

MA 模型

results_MA = model.fit(disp=-1)  
plt.plot(ts_log_diff) 

组合模型

 plt.plot(ts_log_diff)
plt.plot(results_ARIMA.fittedvalues, color='red') 

在这里,咱们能够看到 AR 和 MA 模型有简直雷同的 RSS,然而联合起来会更好。当初,咱们剩下最初一步,行将这些值复原到原始比例。

回到原来的比例

因为组合模型给出了最佳后果,让咱们将其缩放回原始值,看看它的预测体现如何。第一步是将预测后果存储为一个独自的序列并察看它。

请留神,这些开始于 ’1949-02-01’,而不是第一个月。为什么?这是因为咱们取了一个滞后 1,第一个元素之前没有任何货色能够减去。将差分转换为对数刻度的办法是将这些差分间断地增加到基数上。一个简略的办法是首先确定索引处的累积和,而后将其增加到基数中。累积总和如下所示:

您能够应用后面的输入疾速地做一些计算,以查看这些是否正确。接下来咱们要把它们加到底数上。为此,让咱们创立一个以所有值作为基数的序列,并将其差分相加。这能够这样做:

这里的第一个元素是基数自身,而后从那里累计加值。最初一步是取指数并与原数列进行比拟。

 plt.plot(predictions_ARIMA) 

这些都是 Python 中的内容。咱们来学习一下如何在 R 中实现工夫序列预测。

R 工夫序列预测

第一步:读取数据,计算根本总结

# 安装包并调用库
install.packages("tseries")

#读取 Airpaseengers 数据
tsdata<-AirPassengers
#辨认数据类别
class(tsdata)
#察看工夫序列数据
tsdata
#数据摘要
dfSummary(tsdata)

输入

class(tsdata)
"ts"
> #察看工夫序列数据
> tsdata
Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
1949 112 118 132 129 121 135 148 148 136 119 104 118
1950 115 126 141 135 125 149 170 170 158 133 114 140
1951 145 150 178 163 172 178 199 199 184 162 146 166
1952 171 180 193 181 183 218 230 242 209 191 172 194
1953 196 196 236 235 229 243 264 272 237 211 180 201
1954 204 188 235 227 234 264 302 293 259 229 203 229
1955 242 233 267 269 270 315 364 347 312 274 237 278
1956 284 277 317 313 318 374 413 405 355 306 271 306
1957 315 301 356 348 355 422 465 467 404 347 305 336
1958 340 318 362 348 363 435 491 505 404 359 310 337
1959 360 342 406 396 420 472 548 559 463 407 362 405
1960 417 391 419 461 472 535 622 606 508 461 390 432
> #

tsdata 
Dimensions: 144 x 1 
Duplicates: 26

----------------------------------------------------------------------------------------------------
No Variable Stats / Values Freqs (% of Valid) Graph Valid Missing 
---- ---------- -------------------------- ----------------------- --------------------- -------- --
1 tsdata Mean (sd) : 280.3 (120) 118 distinct values . : . 144 0 
[ts] min < med < max: Start: 1949-01 : : . . : (100%) (0%) 
104 < 265.5 < 622 End : 1960-12 : : : : : 
IQR (CV) : 180.5 (0.4) : : : : : : : 
: : : : : : : : . . 
----------------------------------------------------------------------------------------------------

第 2 步:查看工夫序列数据的周期并绘制原始数据

# 检查数据并绘制原始数据

plot(tsdata, ylab="乘客(1000 人)", type="o")

输入

cycle(tsdata)
Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
1949 1 2 3 4 5 6 7 8 9 10 11 12
1950 1 2 3 4 5 6 7 8 9 10 11 12
1951 1 2 3 4 5 6 7 8 9 10 11 12
1952 1 2 3 4 5 6 7 8 9 10 11 12
1953 1 2 3 4 5 6 7 8 9 10 11 12
1954 1 2 3 4 5 6 7 8 9 10 11 12
1955 1 2 3 4 5 6 7 8 9 10 11 12
1956 1 2 3 4 5 6 7 8 9 10 11 12
1957 1 2 3 4 5 6 7 8 9 10 11 12
1958 1 2 3 4 5 6 7 8 9 10 11 12
1959 1 2 3 4 5 6 7 8 9 10 11 12
1960 1 2 3 4 5 6 7 8 9 10 11 12

步骤 3: 合成工夫序列数据

# 将数据合成为趋势、季节性和随机误差重量
plot(tsdata_decom)

输入

第四步:测验数据的平稳性

# 测试数据的平稳性
#单位根测验
adf(tsdata)

#自相干测验
plot(acf(tsdata,plot=FALSE))+ labs(title="航空旅客数据相干图")

plot(acf(tsdata_decom$random,plot=FALSE)) 

输入

Augmented Dickey-Fuller Test

data: tsdata
Dickey-Fuller = -7.3186, Lag order = 5, p-value = 0.01
alternative hypothesis: stationary 

the p-value is 0.01 which ip 值为 0.01,小于 0.05,因而,咱们回绝了零假如,因而工夫序列是安稳的。s <0.05, therefore, we reject the null hypothesis and hence time series is stationary.

最大滞后为 1 个月或 12 个月,表明与 12 个月周期正相干。
主动绘制 7:138 的随机工夫序列观测值,不包含 NA 值

步骤 5:拟合模型

# 拟合模型
#线性模型
plot(tsdata) + smooth(method="lm")


#ARIMA 模型
arimats 

Series: tsdata 
ARIMA(2,1,1)(0,1,0)[12]

Coefficients:
ar1 ar2 ma1
0.5960 0.2143 -0.9819
s.e. 0.0888 0.0880 0.0292

sigma^2 estimated as 132.3: log likelihood=-504.92
AIC=1017.85 AICc=1018.17 BIC=1029.35 

第 6 步:预测

 #Arima 模型的预测
    fore(arimats, level = c(95)) 

最初咱们有一个原始数据的预测。


最受欢迎的见解

1. 在 python 中应用 lstm 和 pytorch 进行工夫序列预测

2.python 中利用长短期记忆模型 lstm 进行工夫序列预测剖析

3. 应用 r 语言进行工夫序列(arima,指数平滑)剖析

4.r 语言多元 copula-garch- 模型工夫序列预测

5.r 语言 copulas 和金融工夫序列案例

6. 应用 r 语言随机稳定模型 sv 解决工夫序列中的随机稳定

7.r 语言工夫序列 tar 阈值自回归模型

8.r 语言 k -shape 工夫序列聚类办法对股票价格工夫序列聚类

9.python3 用 arima 模型进行工夫序列预测

正文完
 0