【时间序列预测算法】——ARIMA 算法介绍及代码实现

2023-11-04

基本概念

一阶差分:时间序列在t 与t-1 时刻函数值的差值,提升时序数据的平稳性(ARIMA算法对数据平稳性有要求)
二阶差分:在一阶差分的基础上再做一次(一般时序数据最多做两阶,再多则预测意义不大)
自回归模型: f ( t ) , t ∈ [ 0 , m ] f(t),t\in[0,m] f(t)t[0,m]已知历史数据,预测 f ( t ′ ) , t ′ > m f(t'),t'>m f(t),t>m 。用变量自身的历史数据对自身进行预测 自回归模型必须满足平稳性的要求
ARIMA:全称“自回归移动平均模型”。记作ARIMA(p,d,q),用于时序预测的模型,通常适用单列时序数据分析,前提是时序数据平稳(围绕均值有限波动,方差有限,且均值和方差几乎不变),不能有明显上升/下降趋势(如果有,则要差分处理),可使用ADF检验稳定性(待研究)。
严平稳:时序的统计特性不随时间变化而时移(实际中难以满足)
弱平稳:期望值基本不变,相关性基本不变(未来的值与历史值的依赖关系不变,否则无法预测)(实际中通常情况)
截尾:自相关函数(ACF)或偏自相关函数(PACF)在某阶后瞬间衰减为0的性质,可通过计算相邻点的斜率超过预设阈值来自动判定,或通过计算折线图中积分值占据总积分(面积)的比例超过预设比例阈值如90%来自动判定。
拖尾:ACF或PACF在某阶后逐渐衰减为0的性质。
QQ图:quantile-quantile plot,用于检验一组数据是否服从某一分布;检验两个分布是否服从同一分布。原理是用图形的方式比较两个概率分布,把两组数据的分位数放在一起绘图比较——首先选好分位数间隔,图中的每个点(x,y)反映出其中一组数据的分布分位数(y坐标)和相同分位数下另一组数据的值(x坐标)。如果两个分布相似,则该Q-Q图趋近于落在y=x线上。如果两分布线性相关,则点在Q-Q图上趋近于落在一条直线y=kx上,如果要利用Q-Q图来对数据进行正态分布的检验,则可以令一组数据为正态分布的标准数据,另一组数据与之计算分位数,绘QQ图后观察两者构成的点分布在一条直线上,就证明样本数据与正态分布存在线性相关性,即服从正态分布。

算法步骤

  1. ADF检验平稳性,分析t值,确定是否可以显著拒绝序列不平稳假设 ( p < 0.05 或 0.01 ) (p<0.05或0.01) (p<0.050.01)
  2. 偏自相关分析、自相关分析,根据截尾情况估算p、q值(使用AIC BIC选择简单的模型)
  3. 检验模型残差是否为白噪声(纯随机),Q统计量的p值检验 或 信息准则AIC和BIC 或 ACF/PACF图分析。
  4. 模型参数表→模型公式
  5. 向后预测输出指定阶数(向后预测几个时间点的值)

NOTE:前两步骤主要是研究严谨性所需。

AR模型

自回归模型,构建历史数据到未来数据的映射关系
差分得到平稳序列
p阶自回归过程公式定义:

y t = μ 常 数 + Σ i = 1 p 阶 数 γ i y t − i + ϵ t 误 差 y_t=\mu常数+\Sigma^{p阶数}_{i=1}\gamma_iy_{t-i}+\epsilon_t误差 yt=μ+Σi=1pγiyti+ϵt

γ \gamma γ是自相关系数,表示i时刻和t时刻的相关性,相关性越大则系数越大,i时刻的y值对t时刻的y值影响越大。
p p p阶数表示t时刻与前面p个时刻的y值相关,可通过计算自相关系数确定p的大小,若i时刻自相关系数<0.5,则p就截止到i+1时刻。

MA模型

移动平均模型
自回归模型中误差项会累加,所以预测的模型公式中加入MA项来消除预测时的随机波动

Σ i = 1 q 阶 数 θ i ϵ t − i \Sigma^{q阶数}_{i=1}\theta_i\epsilon_{t-i} Σi=1qθiϵti

ARMA模型

自回归移动平均模型

y t = μ 常 数 + Σ i = 1 p 阶 数 γ i y t − i + ϵ t 误 差 + Σ i = 1 q 阶 数 θ i ϵ t − i y_t=\mu常数+\Sigma^{p阶数}_{i=1}\gamma_iy_{t-i}+\epsilon_t误差+\Sigma^{q阶数}_{i=1}\theta_i\epsilon_{t-i} yt=μ+Σi=1pγiyti+ϵt+Σi=1qθiϵti

(p,d,q)都需要指定,pq是阶数,也称为滞后值,d=1或2(通常取1),对应I字母,所以:

ARIMA模型

ARIMA模型是差分自回归移动平均模型
(Autoregressive Integrated Moving Average Model)
比ARMA模型多了个开始的差分处理

ACF自相关函数

autocorrelation function
反映序列在不同时间点上的取值相关性
A C F ( k ) = ρ k = C o v ( y t , y t − k ) / V a r ( y t ) ∈ [ − 1 , 1 ] ACF(k)=\rho_k=Cov(y_t,y_{t-k})/Var(y_t)\in[-1,1] ACF(k)=ρk=Cov(yt,ytk)/Var(yt)[1,1]
-1负相关 +1 正相关 0 不相关
可以绘制 A C F ( k ) ACF(k) ACF(k)的曲线图
图

NOTE:图来自网络博客 https://blog.csdn.net/y1163307648/article/details/107832178

PACF偏/部分自相关函数

partial autocorrelation function

  1. ACF得到的并不是 y t , y t − k y_t,y_{t-k} yt,ytk间的严格关系,因为 y t y_t yt还受前k-1个y的影响,即ACF包括直接和间接的相关性,所以PACF是剔除干扰后的相关性计算。
  2. PACF找的是残差 R t R_t Rt与前第k个滞后值 y t − k y_{t-k} ytk的相关性。只描述观测值 y t y_t yt和​其滞后项 y t − k y_{t-k} ytk的直接关系
  3. AR过程:在ACF图中显示出逐渐减少的趋势,因为作为一个AR过程,其当前与过去的滞后项具有良好的相关性;PACF在滞后项阶数后会急剧下降,因为这些接近当前项的滞后项可以很好地捕获变化,因此不需要很多过去的滞后项来预测当前项
  4. MA过程:在ACF 图中在阶数q 之后迅速下降,能够画出相邻的滞后项之间的良好的相关关系,且和过去的滞后项没有相关关系;在PACF中,曲线逐渐下降,临近的滞后项不能预测当前项,更远的滞后项有良好的相关关系。
  5. 计算公式复杂,参考博客:点击查看

pq确定表

pq表

AIC/BIC/HQ模型选择

AIC

赤化信息准则 Akaike Information Criterion 人名命名
A I C = 2 k − 2 l n L AIC=2k-2lnL AIC=2k2lnL

BIC

贝叶斯信息准则 Bayesian Information Criterion
B I C = k l n N − 2 l n L BIC=klnN-2lnL BIC=klnN2lnL

HQ

Hannan-Quinn Criterion
H Q = k l n ( l n N ) − 2 l n L HQ=kln(lnN)-2lnL HQ=kln(lnN)2lnL

k:模型参数的个数,模型参数的差别就在于p和q,所以可认为k=p+q
N:样本数量
L:模型函数的(最大)似然函数值

NOTE:比较时只采用其中的一种原则;均满足参数越多越不好的哲学原理;原则的值越小则说明模型越简单。

模型残差检验

检验残差是否是均值=0 方差=constant的正态分布

  1. 绘制残差图,定量计算均值和方差,并根据样本分布使用假设检验理论来计算是否符合正态分布
  2. QQ图绘制,如果呈现线性则符合正态分布。

代码实现

差分使用pandas:

df.diff(1)#按照间隔1个点计算差值
df.plot(subplots=True)#绘制曲线

使用statsmodels库提供的函数可以计算相关性系数等。

pip install statsmodels

使用基础库计算:

matplotlib.rc('xtick', labelsize=40)
matplotlib.rc('ytick', labelsize=40)
# 使用库进行处理更简单
from statsmodels.tsa.stattools import acf, pacf

# ------------------参数定义------------------
#d=1时 p,d,q=6,1,6 p+q=12
#d=2时 p,d,q=4,2,2 p+q=6<12 根据模型选择原则选择d=2
d = 2
K_MAX = 10
epochs = 10
Period = 100
epsilon = [np.random.normal() for _ in range(Period)]
# ------------------时序数据构造------------------
t = np.linspace(0, 10, 500)
# adding normally distributed series in exponential series
y = np.random.normal(0, 5, 500) + np.exp(t ** 0.5)
# 原始时序数据
plt.figure(figsize=(16, 7))
plt.plot(t, y)
plt.show()


# ------------------差分函数------------------
def diff(y, d):
    for d_index in range(d):
        y = [y[i] - y[i - 1] for i in range(1, len(y))]
    return y


diff_y = diff(y, d)
plt.plot(t[:len(diff_y)], diff_y)
plt.title("Diff of %d order" % d)
plt.show()


# ------------------ACF函数计算------------------
def ACF(y, k):
    y_t = np.array([y[i] for i in range(k, len(y))])
    y_t_k = np.array([y[i] for i in range(k - k, len(y) - k)])
    avg_y_t = np.mean(y_t)
    avg_y_t_k = np.mean(y_t_k)
    # * 相当于 np.multiply对应元素相乘 要求两array的shape一致
    cov = np.mean((y_t - avg_y_t) * (y_t_k - avg_y_t_k))  # 应该是÷(n-1)
    var = np.mean((y_t - avg_y_t) ** 2)  # 应该是÷(n-1)
    return cov / var


acf_list = []
for k in range(K_MAX):
    acf_list.append(ACF(diff_y, k))
plt.plot(acf_list)
plt.title("ACF-K Curve")
plt.show()
for k in range(K_MAX):
    plt.plot(np.ones(2) * k, [0, acf_list[k]])
# 绘制水平辅助线 ax h line → axhline
# 绘制竖直辅助线 ax v line → axvline
plt.axhline(y=0, linestyle='--')
plt.title("ACF-k Point")
plt.show()
# ------------------PACF函数计算------------------
# 参考博客:https://www.cnblogs.com/nkuhyx/p/12162637.html
from scipy.linalg import toeplitz

# 1.使用statsmodels计算:
import statsmodels.tsa.stattools as stattools


def default_pacf(ts, k):
    return statools.PACF(ts, nlags=k, unbiased=True)


# 2.使用原生库计算:
def PACF(ts, k):
    ''' Compute partial autocorrelation coefficients for given time series,unbiased
    '''

    def yule_walker(ts, order):
        ''' Solve yule walker equation
        '''
        x = np.array(ts) - np.mean(ts)
        n = x.shape[0]

        r = np.zeros(order + 1, np.float64)  # to store acf
        r[0] = x.dot(x) / n  # r(0)
        for k in range(1, order + 1):
            r[k] = x[:-k].dot(x[k:]) / (n - k)  # r(k)

        R = toeplitz(r[:-1])

        return np.linalg.solve(R, r[1:])  # solve `Rb = r` to get `b`

    res = [1.]
    for i in range(1, k + 1):
        res.append(yule_walker(ts, i)[-1])
    return res


# pacf_list = []
# for k in range(K_MAX):
#     pacf_list.append()
pacf_list = PACF(diff_y, K_MAX)
plt.plot(pacf_list)
plt.title("PACF-K Curve")
plt.show()
for k in range(K_MAX):
    plt.plot(np.ones(2) * k, [0, pacf_list[k]])
# 绘制水平辅助线 ax h line → axhline
# 绘制竖直辅助线 ax v line → axvline
plt.axhline(y=0, linestyle='--')
plt.title("PACF-k Point")
plt.show()
# --------------截尾自动判别-------------
# 计算绝对值,在>0的范围上进行计算斜率
# 斜率截尾时满足↗↘,转折点就是阶数
acf_list_abs = np.abs(acf_list)
pacf_list_abs = np.abs(pacf_list)
# 计算斜率k = 差值δy÷δx
acf_k = np.abs(diff(acf_list_abs, 1)) / 1
pacf_k = np.abs(diff(pacf_list_abs, 1)) / 1
q = 0
for i in range(1, len(acf_k) - 1):
    if (acf_k[i] > acf_k[i - 1]) and (acf_k[i] > acf_k[i + 1]):
        q = i + 1
        break
p = 0
for i in range(1, len(pacf_k) - 1):
    if (pacf_k[i] > pacf_k[i - 1]) and (pacf_k[i] > pacf_k[i + 1]):
        p = i + 1
        break
print("p:", p,end=" ")
print("d:",d,end=" ")
print("q:", q,end=" ")
# -----------AR模型----------------
def AR(miu,yt,p,epsilon,t):
    # t:yt输入的第0项对应的时刻点
    # yt:y0 y1 y2 -> y3
    # acf_list:k=0 1 2 3
    ar = miu
    for i in range(1,p+1):
        ar += acf_list[i]*yt[-i]+epsilon[(t+i-1)%len(epsilon)]
    return ar
data = []
label = []
predict = []
for i in range(len(diff_y)-p):
    data.append(diff_y[i:i+p])
    label.append(diff_y[i+p])
miu=0
print()
for epoch in range(epochs):
    predict = []
    for i in range(len(data)):
        predict.append(AR(miu,data[i],p,epsilon,i))
    # 计算偏差
    bias_loss = np.mean(-np.array(predict)+np.array(label))
    miu = bias_loss#自动学习 更新模型参数
    loss = np.mean((np.array(predict)-np.array(label))**2)
    print("epoch:",epoch+1,"loss:",loss,"bias_loss:",bias_loss,"miu:",miu)
print("学习后 miu:",miu)
plt.plot(label,label='True')
plt.plot(predict,label='Pred')
plt.legend(loc=1)
plt.title("AR predictions")
plt.show()

AR模型的预测效果:
AR模型
ACF
PACF

10个分位点时绘制QQ图
QQ图
20个分位点时绘制QQ图
QQ图
50个分位点时绘制QQ图:
QQ图

NOTE:必过(0,0) (1,1)两点,因为0时对应min值0(首先要归一化 否则关系比较难看出来),1时对应max值1。

备注

算法的代码还是以基础代码实现为好,使用库函数则参数难以调整。

  1. 只实现了AR模型的预测,因为MA模型的θ相关性系数不清楚如何计算
  2. AR模型预测效果在d=0或1的时候较稳定(指的是De_Diff后),在d=2的时候差分序列预测结果较好,但逆差分还原后到一阶差分结果时预测结果一般,还原到零阶差分结果时预测结果很差,所以d不能过大。实际应用中需要的结果是零阶的结果(即原时序数据)而不是二阶的结果,所以如果逆差分的结果偏差大,则即使未逆差分时的结果拟合程度较好(实测的结果,d=2时两阶差分拟合程度高,但逆差分到零阶后拟合程度却很差),仍无法使用该模型。
  3. Q-Q图也是基础代码实现,没有调用高级库,未展现在本博客中。思路:横坐标是分位点,纵坐标是分位点处的序列值(归一化后),也可以将多组序列数据绘制到一张Q-Q图中,观察是否相似,如果相似则说明统计上服从的分布接近。根据实际图可以发现和正态分布接近,所以残差检验通过。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【时间序列预测算法】——ARIMA 算法介绍及代码实现 的相关文章

随机推荐

  • CV计算机视觉核心08-目标检测yolo v3(coco数据集)

    CV计算机视觉核心08 目标检测yolo v3 对应代码文件下载 https download csdn net download m0 37755995 86237192 需要自己下载coco的train2014和val2014 http
  • VirtualBox如何添加ISO文件或物理光盘

    最近学习Linux 想先在虚拟机上操作练练手 装个CentOS distribution 但是一开始捣鼓的时候发现 VirtualBox似乎只支持vmdk等类型的文件 但我下的是iso镜像文件啊 相信大家也可能遇到或者将会遇到这个问题 这可
  • 详解批量梯度下降法(BGD)、随机梯度下降法(SGD)和小批量梯度下降法(MBGD)

    在应用机器学习算法时 我们常采用梯度下降法来对才用的算法进行训练 梯度下降法有三种不同的形式 批量梯度下降 Batch Gradient Descent 随机梯度下降 Stochastic Gradient Descent 以及小批量梯度下
  • android 导入modoule_Android Studio中导入module的方法(简单版)

    1 把要导入成Mudle的项目修改成符合Library的格式 修改该项目中bulid gradle文件中第一行代码 把 apply plugin com android application 修改为 apply plugin com an
  • 强烈推荐的几款实用的IDEA插件(通俗易懂)

    IDEA官网插件离线下载地址 JProfiler 启动完成会自动弹出JProfiler窗口 在里面就可以监控自己的代码性能了 JProfiler 操作指南详解 点击此处跳转 EasyCode 使用Easy Code可以自动化生产后台基础逻辑
  • php 数组元素快速去重

    1 使用array unique方法进行去重 对数组元素进行去重 我们一般会使用array unique方法 使用这个方法可以把数组中的元素去重 1 2 3 4 5 6 1 2 3 4 5 6 输出 Array 0 gt 1 1 gt 2
  • 总结磁共振成像的脑龄预测的人工智能模型

    脑龄预测的人工智能模型 介绍 基于神经影像的BA预测 BA预测建模 从统计方法到DL 统计方法 使用统计 最大似然估计方法的BA研究的主要结果 深度学习 使用DL方法进行BA研究的主要结果 可解释的人工智能 即可解释的深度学习方案 可解释的
  • 从简入难makefile文件编写,Linux C++编程,简单vi命令

    1 一个最基本的C 程序 2 第二个c 程序 3 第一个入门级别的简单的makefile 4 在makefile中定义变量 5 编写makefile的依赖 如果start 标识后面的某个 o没有 则重新编译没有编译的那个文件 6 最终的ma
  • 连接git仓库失败解决办法

    问题出现 首先是我在本地建了个项目 写完了之后呢打算用sourceTree推到gitlab的仓库里 奈何这gitlab仓库怎么也连接不上 基于我是第一次使用sourceTree 想着是不是啥东西没配置好 结果各种捣鼓发现gitee和gith
  • vertx文章系列--响应式Mysql操作入门体验

    官网地址 https vertx io 中文文档 https vertx china gitee io Mysql驱动连接练习 https vertx china gitee io docs vertx mysql client java
  • CVPR2018-SRMD-Kai Zhang

    https github com cszn SRMD https github com 2wins SRMD pytorch 创新点 1 设计了一个非盲单一 CNN 网络SRMD 针对多个退化模型 模型的输入除了LR图 还有 degrati
  • Unity UI上的物体跟随场景物体位置变化而变化(人物血条/称号)

    首先看下UI上物体的位置计算 UI上的物体 以下用 血条 代称 这个很简单 无非就是坐标转换 把人物的世界坐标转到屏幕坐标 代码如下 public Transform target public Transform hpSp public
  • Linux系统安装Java

    1 下载JDK 下载网址 https www oracle com technetwork java javase downloads index html 下拉 找到jdk8 使用Xshell远程连接虚拟机 2 先新建一个文件夹 目录是
  • oracle 分区表插入数据_Oracle数据库分区表整理笔记

    关键词 partition 分区subpartition 辅助分区已经存在的表没有方法可以直接转化为分区表 分区索引 一 分区表类型 1 范围分区 1 1 按指定要求划分 假设有一个CUSTOMER表 表中有数据200000行 我们将此表通
  • JS reduce 用法

    定义 reduce 方法接收一个函数作为累加器 数组中的每个值 从左到右 开始缩减 最终计算为一个值 语法 array reduce function total currentValue currentIndex arr initialV
  • HEVC对场编码的支持

    HEVC值得注意的是它没有提供专用于隔行视频的工具 而是将隔行视频的一帧看作两个独立的场 对各个场数据分别进行编码 简化了编码器的实现 这也是因为随着数字视频技术的快速发展 视频的隔行扫描方式日渐式微 https blog csdn net
  • vue+element-ui实现表格里嵌套表格

    效果图 点击某行数据展开另一个嵌套在里面的table 核心代码 从后台请求的数据格式 代码实现
  • table 表格合并

    table 表格合并 开发工具与关键技术 DW JavaScript 作者 刘东标 撰写时间 2019 03 14 div div span colspan和rowspan这两个属性用于创建特殊的表格 span span colspan用来
  • JAVA查搜索文件内容

    上周突然遇到了个要查找历史sql的中是否包含某个字段的问题 Everting虽然可以查找某个后缀的文件 可是并不能搜索文件内容 所以就花费一点功夫自己写一个了 使用起来还是非常方便 1 单文件查找内容 2 单文件夹下读取所有文件 并查找内容
  • 【时间序列预测算法】——ARIMA 算法介绍及代码实现

    基本概念 一阶差分 时间序列在t 与t 1 时刻函数值的差值 提升时序数据的平稳性 ARIMA算法对数据平稳性有要求 二阶差分 在一阶差分的基础上再做一次 一般时序数据最多做两阶 再多则预测意义不大 自回归模型 f t