[Day30]凌晨狂上上下下23次-时间序列分析终局之战,ARIMA差分整合移动平均自回归模型

在时间序列分析中相当有名的一个数学模型,差分整合移动平均自回归模型,又名为ARIMA模型,我们就来介绍这东西吧

ARIMA模型

ARIMA模型是一种时间序列分析模型,想要了解它就必须先听闻过另外三种知名的时间序列分析模型

  • 自回归模型-AR模型

  • 移动平均模型-MA模型

  • 自回归滑动平均模型-ARMA模型
    而ARMA模型是将上面两种时间序列分析模型,AR模型、MA模型整合在一起的产物,而ARIMA则是以ARMA做优化的产品,时间序列分析模型的目的大多数都是要拿以现有的数据来预测未来,而这些模型都有自己的特色,下面来一一简单介绍一下

AR模型

常写为AR(p)
公式为:

Yt = α+β1Yt-1+β2Yt-2+…+βpYt-p+ɛt

公式这里就不细说了,要多复杂的解释网路上那里都有,这里就简单说明
AR模型就是以前期的资料来预测本期的资料,而且越接近本期的资料,对预测结果的影响力就越大
如果我们想预测五分钟後的气温,我想大多数都认同30分钟前的资料比3天前的资料更具有参考价值这个观点吧,而AR模型正是把这个观点以数学的方式呈现出来,而且AR模型是以过去p笔资料的线性组合来预测的,因此才会写成AR(p),p是我们要挑选的过去资料的笔数,然而现实生活中很少有自然现象会真的以线性的方式出现,因此AR模型为了贴近真实生活中的数据,会在加上一个随机变数,因此我们可以简单的将公式解读为

预测值 = 常数 + [ ( 前1期资料的影响力 * 前1期资料的数值 ) + ... + ( 前p期资料的影响力 * 前p期资料的数值 ) ] + 随机变数

MA模型

常写为MA(q)
公式为:

Yt = α+ɛt+Φ1ɛt-1+Φ2ɛt-2+…+Φqɛt-q

这称为移动平均模型,q是前面几期的笔数,我们简单的将公式解读为

预测值 = 平均数 + [ ( Φ1 * ɛt-1 ) + ... + ( Φq * ɛt-q ) ] + 随机变数

其中最重要的是 ( Φ1 * ɛt-1 ) ~ ( Φq * ɛt-q ) 这几项的累加,我们一一分开来看
Φ是介於-1~1之间,可以想像为影响力的大小
ɛ是残差值
我们简单的将残差值的公式解读为

残差值 = 随机变数 + [ ( 前1期资料的影响力 * 前1期资料的数值 ) + ... + ( 前p期资料的影响力 * 前p期资料的数值 ) ]

ARMA模型

公式为

Xt = c + εt + β1Yt-1+β2Yt-2+…+βpYt-p + Φ1ɛt-1+Φ2ɛt-2+…+Φqɛt-q

仔细看公式,斜体的部份正好就是 AR及MA模型的一部分,所以写法为ARMA(p,q)

关键心法

这些模型其实不难,仔细想一下,公式会落落长就只是因为时间序列本身的关系,因为序列本来就是许多数字组成的,每个数字做的运算其实都不难,只是要做很多次罢了,在说,要算也是丢给电脑算,所以不要害怕

ARIMA模型

上述三种模型虽有其强大之处,也有相应的缺陷,就是这三种模型只能处理稳定的资料,而ARIMA模型就是为了解决这问题而诞生的,它自带了第三个参数,差分项,因此能将非稳定的资料处理成稳定的资料,常写成ARIMA(p,d,q),其中d就是为了使资料平稳所作的差分次数,我们直接往下实做,我们就以昨天补值的资料做范例

首先要先对资料做平稳化处理,这里我们直接暴力解决,直接让它帮我们算出推荐的差分次数,差分後要如何检查稳不稳定呢?这时候就要使用稳定性检验法,其中最知名的就是ADF检验法,因此我们要在ndiffs()里面加上test="adf"参数,意思就是,通过ADF检验法的差分次数,就是我们要的答案

import pandas as pd
import numpy as np
from matplotlib import pyplot as plt 
from pmdarima.arima import ndiffs


if __name__ == "__main__":
    data = pd.read_csv("./OK.csv")

    # 有些插值法是时间序列专用,所以最好先将索引转成时间
    data["time"] = pd.to_datetime(data["time"])
    data = data.set_index("time")

    # 算出推荐的差分次数
    d =  ndiffs(data["time_imputed"],  test="adf")
    print(d) # 1

接着我们要来挑选p参数,这是要透过偏自相关函数图PACF图来帮助我们选择,简单来说PACF图可以让我们看出,究竟多久远以前的资料,对於我们的预测还具有影响力,毕竟AR(p)模型中就是不断的强调过去资料对现在的影响力嘛

我们来简单的说明一下这张图,每一根柱子都表示过去的一笔资料,我们前两跟柱子,非常接近1,所以表示影响力非常大,而第三跟柱子也很大根,可是却是接近-1的,表示前第三笔资料的增加将会造成预测数值的缩小,而低於阴影的笔数则代表影响力过低,没用,因此这里p值选择7

最後我们要来挑选q参数,这要透过自相关函数图ACF图来帮助我们选择,用法跟PACF图差不多

不用说了,直接选35吧

import pandas as pd
import numpy as np
from matplotlib import pyplot as plt 
from pmdarima.arima import ndiffs
from statsmodels.graphics.tsaplots import plot_pacf, plot_acf


if __name__ == "__main__":
    data = pd.read_csv("./OK.csv")

    # 有些插值法是时间序列专用,所以最好先将索引转成时间
    data["time"] = pd.to_datetime(data["time"])
    data = data.set_index("time")

    # 算出推荐的差分次数
    d =  ndiffs(data["time_imputed"],  test="adf")
    print(d) # 1

    #  观察PACF图,参数是差分之後的资料
    plot_pacf(data["time_imputed"].diff(1))
    plt.show()

    #  观察ACF图,参数是差分之後的资料
    plot_acf(data["time_imputed"].diff(1))
    plt.show()

接着直接来做ARIMA模型预测吧,我们用资料的前90%来预测後面10%

import pandas as pd
import numpy as np
from matplotlib import pyplot as plt 
from pmdarima.arima import ndiffs
from statsmodels.graphics.tsaplots import plot_pacf, plot_acf
from statsmodels.tsa.arima_model import ARIMA


if __name__ == "__main__":
    data = pd.read_csv("./OK.csv")

    # 有些插值法是时间序列专用,所以最好先将索引转成时间
    data["time"] = pd.to_datetime(data["time"])
    data = data.set_index("time")

    # 算出推荐的差分次数
    d =  ndiffs(data["time_imputed"],  test="adf")
    print(d) # 1

    # #  观察PACF图,参数是差分之後的资料
    # plot_pacf(data["time_imputed"].diff(1))
    # plt.show()

    # #  观察ACF图,参数是差分之後的资料
    # plot_acf(data["time_imputed"].diff(1))
    # plt.show()
    
    # 过去资料
    data_set = data["time_imputed"][:int(0.9*data.shape[0])].copy()
    # 正确答案
    target = data["time_imputed"][int(0.9*data.shape[0]):].copy()
    # 建立模型
    model = ARIMA(data_set,order=(7,1,35)).fit(disp=0)
    # 模型预测
    predict = model.forecast(steps=int(0.9*data.shape[0]))

<<:  谁温暖了资安部-28(破口)

>>:  Day 30 ~ AI从入门到放弃 - 结语

Day 23 -资料库应用小程序 资料库设计(系统需求分析)

完善的资料库能够有效地存储数据,提供最新、最精确的资讯,满足使用者的应用需求,因此正确的资料库结构设...

【第二八天 - Flutter 开发套件之旅(上)】

前言 当我在做某某知名平台的画面时,我发现其实健在都没有这个效果的 plugin,可以快速达到想要做...

Day 15 知识地图

画出一张属於自己的学习地图,只有知道自己身在何处,才不会迷路。你必须知道这项学习的终点,该拥有什麽样...

从零开始-30日练习开发iOS APP-UserDefault Day-28

正文: 利用 UserDefault 储存资料 预览图: 程序码: import UIKit cla...

缓冲区溢出和记忆体泄漏(Buffer Overflow and Memory Leak)

-进程的记忆体布局 **缓冲区(Buffer)**是指用於存储特定大小数据的一段内存。如果数据大小...