Python构建时间序列ARIMA模型
前言
时间:19/04/25,天气晴,心情愉悦。
大学生活不知不觉已经快要结束了,我才第一次认真的开始检查、审视自己过去两年中究竟学到了些什么?仔细回想,学的东西好像还蛮多的,从我开始懵懂学习C语言后入坑编程系列学习以来,自己慢慢的喜欢上这一领域,开始用C实现一些小小的功能,例如12306抢票、一些经典的小游戏等。后续除了掌握一些基本数据库知识之外我又接触了Java这种oo语言,并且我在自己的课程设计里面独立编写了基于MINA框架的商城Shopping微信小程序,虽然写的有点烂,但是也基本实现了商城的大部分功能(对自己要求有点低)。再后来一次侥幸的机会跟着导师做了一个项目,是基于计算机视觉的智能小车导航避障的,为此,我专门去学习了在MFC框架下用opencv实现图像处理,嗯,opencv图像处理是我学了最长时间也是最系统的学习,从简单的图像形态学处理、图像去燥、图像分割到复杂颇具挑战的模式识别我都有了解过研究过,在做图像处理的过程中,我慢慢的发现自己对图像数据(数据)的各式各样处理计算颇感兴趣。那时候正值大数据的热潮,我从网上找了一些大数据的视频学习了Hadoop、Spark等,掌握了大批量数据下并行处理的方式,但是自己并不知道用什么方法去处理数据,于是,18年的下半年,我开始正式接触机器学习领域,至今学习机器学习时常也有半年的时间了,在这半年里也学习了很多公式推导也有很多算法流程,如今让我回忆一下自己曾经学的这些机器学习的东西,自己的印象其实已经没有那么深刻了,即使在学习当下对算法推导以及应用非常的熟悉,但是没有把自己学的内容整理下来,即使学过随着时间推移也差不多把大部分细节给忘记了。我挺后悔自己当初学习的时候没有做笔记,不过悔在过去、行在当下,从此刻开始记录我的学习,我相信我可以坚持记录下去。
ARIMA模型简介
具有如下结构的模型称为求和自回归移动平均(Autoregressive Integrated Moving Average),简记为ARIMA(p,d,q)模型:
式中:
ARIMA模型的数学原理和公式我就不一一解释了,如果有不懂的地方可以参考ARIMA模型,在本篇中我们主要探讨如何用Python对时序进行分析建模。
Python实现ARIMA模型预测
数据的获取与准备
如某市1995-2003年各月的工业生产总值如下表所示,试对1995-2002年数据建模,2003年的数据留做检验模型的预测结果。
我们在获取数据时,可能会因为一些客观因素(比如一些表格编辑软件的自动将编码转换UTF-8,默认的时间格式规范不一致,例如19/04/25可能会转换成04/25/19,还有就是本身数据就存在缺失、不合理等问题)导致了数据的异常或缺失,然而在机器学习里,数据的好坏直接决定了模型结果的好坏,所以对数据的预处理必不可少。在我们这个实验数据中,数据并没有出现缺失以及不符逻辑的情况,所以我们可以直接将其作为ARIMA模型的输入数据。(如果数据出现缺失不合理等现象,可以选择性参考 https://blog.csdn.net/zhangyonggang886/article/details/80901290)
Python3:
import csv
data_files = csv.reader(open('data.csv','r'))
dataSet = [] # 训练数据集
dateSet = [] # 训练年份集
for data in data_files:
if data[0] == '200301': # 将csv文件中验证数据去除
break
if data[0] != 'date':
dateSet.append(data[0])
dataSet.append(float(data[1]))
绘制1995-2002年时间序列趋势图
显示一行一行的数据是难以观察数据的趋势走向,这样不利于我们观测数据之间的相互联系,因此画出趋势图有利于数据分析。
Python3:
# 利用Pandas库来绘制时间序列趋势图
import matplotlib.pyplot as plt
import pandas as pd
df = pd.DataFrame(dataSet,index=dateSet,columns=['real value'])
df.plot()
plt.show()
result:
去均值化后ADF平稳性检验以及差分
①为什么要去均值化?做数据的去均值化其实就是对数据进行标准化,在很多情况下,我们对数据本身大小并不感兴趣,我们感兴趣的是数据之间的联系,去均值化并不会影响这种联系,因为去均值化后得到的时间序列趋势和没有去均值化得到的时间序列趋势是一样的。
Python3:
# 对时间序列进行去均值化
mean = sum(dataSet)/len(dataSet) # 计算均值
dataSet_kill_mean = [data - mean for data in dataSet] # 得到去均值后的序列
②序列平稳是做ARIMA回归的前提条件,所以我们得到的序列必须是平稳的。观测上面的序列趋势图,我们可以很明显的发现数据有逐渐上升的趋势,因此我们判断该段时间序列为非平稳序列。为了得到平稳的时间序列,我们要做差分,因为差分目的是使变量序列平稳。
Python3:
# 进行一阶差分并绘制趋势图
df_kill_mean = pd.DataFrame(dataSet_kill_mean,index=dateSet,columns=['kill mean value'])
df_kill_mean_1 = dataSet_kill_mean