编者按:本文是澳大利亚知名机器学习专家 Jason Brownlee 撰写的教程,极其全面细致,一步步向读者解释如何操作,以及为什么这么做。雷锋网 (公众号:雷锋网) 整理编译,特与大家分享。更多AI开发技术文章,请关注AI研习社(微信号:okweiwu)。

Jason Brownlee:时间序列预测法是一个过程,而获得良好预测结果的唯一途径是实践这个过程。
在本教程中,您将了解如何利用python语言来预测波士顿每月持械抢劫案发生的数量。
本教程所述为您提供了一套处理时间序列预测问题的框架,包括方法步骤和工具,通过实践,可以用它来解决自己遇到的相关问题。
本教程结束之后,您将了解:
如何核查Python环境并准确地定义一个时间序列预测问题。
如何构建一套测试工具链,用于评估模型,开发预测原型。以及如何通过时间序列分析工具更好地理解你的问题。
如何开发自回归积分滑动平均模型(ARIMA),将其保存到文件,并在之后加载它对新的时间步骤进行预测。
让我们开始吧。

波士顿
概述在本教程中,我们将端到端地来解析一个时间序列预测工程,从下载数据集、定义问题到训练出最终模型并进行预测。
该工程并不面面俱到,但展示了如何通过系统性地处理时间序列预测问题,来快速获得好的结果。
我们将通过如下步骤来解析该工程 :
环境配置.
问题描述
测试工具链
持续性.
数据分析
ARIMA 模型
模型验证
该部分提供一个解决时间序列预测问题的模板,你可以套用自己的数据集。
1. 环境配置本教程假设在已安装好了SciPy及其相关依赖库的环境下进行,包括:
SciPy
NumPy
Matplotlib
Pandas
scikit-learn
statsmodels
我使用的是Python2.7。该脚本将帮助你确认你安装这些库的版本。
# scipy
import scipy
print('scipy: {}'.format(scipy.__version__))
# numpy
import numpy
print('numpy: {}'.format(numpy.__version__))
# matplotlib
import matplotlib
print('matplotlib: {}'.format(matplotlib.__version__))
# pandas
import pandas
print('pandas: {}'.format(pandas.__version__))
# scikit-learn
import sklearn
print('sklearn: {}'.format(sklearn.__version__))
# statsmodels
import statsmodels
print('statsmodels: {}'.format(statsmodels.__version__))
我编写该教程的所用的开发环境显示的结果如下:
scipy: 0.18.1
numpy: 1.11.2
matplotlib: 1.5.3
pandas: 0.19.1
sklearn: 0.18.1
statsmodels: 0.6.1
2. 问题描述我们研究的问题是预测美国波士顿每月持械抢劫案的数量。
该数据集提供了从1966年1月到1975年10月在波士顿每月发生的的武装抢劫案的数量, 或者说,是这十年间的数据。
这些值是一些记录的观察计数,总有118个观察值。
数据集来自于McCleary&Hay(1980)。
您可以了解有关此数据集的更多信息,并直接从 DataMarket 下载。
下载地址:https://datamarket.com/data/set/22ob/monthly-boston-armed-robberies-jan1966-oct1975-deutsch-and-alt-1977#!ds=22ob&display=line
将数据集下载为CSV文件,并将其放在当前工作目录中,文件名为“robberies.csv”。
3.测试工具链我们必须开发一套测试工具链来审查数据和评估候选模型。
这包含两个步骤:
1.定义好验证数据集。
2.开发一套模型评估方法。
3.1 验证数据集这个数据集不是当前时间段的数据集。 这意味着我们不能轻轻松松收集更新后的数据来验证该模型。
因此,我们假设现在是1974年10月,并将分析和模型选择的数据集里扣除最后一年的数据。
最后一年的数据将用于验证生成的最终模型。
下面的代码会加载该数据集为Pandas序列对象并将其切分成两部分,一个用于模型开发(dataset.csv)和另一个用于验证(validation.csv)。
from pandas import Series
series = Series.from_csv('robberies.csv', header=0)
split_point = len(series) - 12
dataset, validation = series[0:split_point], series[split_point:]print('Dataset %d, Validation %d' % (len(dataset), len(validation)))
dataset.to_csv('dataset.csv')
validation.to_csv('validation.csv')
运行该示例将会创建两个文件并打印出每个文件中的观察数。
1. Dataset 106, Validation 12
这些文件的具体内容是:
dataset.csv:1966年1月至1974年10月的观察(106次观察)
validation.csv:1974年11月至1975年10月的观察(12次观察)
验证数据集大小是原始数据集的10%。
请注意,由于保存的数据集中没有标题行,因此,稍后处理这些文件时,我们也不需要满足此要求。
3.2. 模型验证模型评估将仅对上一节中准备的dataset.csv中的数据进行处理。
模型评估涉及两个要素:
1. 评价指标。
2. 测试策略。
3.2.1评价指标这些观察值是抢劫案的计数。
我们将使用均方根误差(RMSE)的方式来评价预测的好坏。这将给予错误的预测更多的权重,并且将具有与原始数据相同的单位。
在RMSE进行计算和报告之前,必须反转对数据的所有转换,以使不同方法的效果可直接比较。
我们可以使用scikit-learn库的辅助函数mean_squared_error()来执行RMSE计算,该函数计算出了预期值列表(测试集)和预测列表之间的均方误差。 然后我们可以取这个值的平方根来作为一个RMSE分数。
例如:
from sklearn.metrics import mean_squared_error
from math import sqrt
...
test = ...
predictions = ...
mse = mean_squared_error(test, predictions)
rmse = sqrt(mse)
print('RMSE: %.3f' % rmse)
3.2.2 测试策略将使用步进验证的方式(walk-forward)来评估候选模型。
这是因为该问题定义需要滚动式预测的模型。给定所有可用数据,这需要逐步进行预测。
步进验证的方式将按照如下几步执行:
数据集的前50%将被用来训练模型。
剩余的50%的数据集将被迭代并测试模型。
对于测试数据集中的每个步骤:
训练该模型
利用该模型预测一次,并经预测结果保存下来用于之后的验证
测试数据集的数据作为下一个迭代的训练集数据
对在测试数据集迭代期间进行的预测结果进行评估,并报告RMSE得分。
由于较小的数据规模,我们将允许在每次预测之前,在给定所有可用数据的情况下重新训练模型。
我们可以使用简单的NumPy和Python来编写测试工具的代码。
首先,我们可以将数据集直接分成训练和测试集。 我们总要将加载的数据转换为float32类型,以防止仍然有一些数据为String或Integer数据类型。
# prepare data
X = series.values
X = X.astype('float32')
train_size = int(len(X) * 0.50)
train, test = X[0:train_size], X[train_size:]接下来,我们可以时间步长遍历测试数据集。训练数据集存储在一个Python的list对象中,因为我们需要在每次迭代中很容易的附加一些观察值,Numpy数组连接有些overkill。
模型进行的预测,按惯例称为yhat。这是由于结果或观察被称为y,而yhat(有上标“^”的y)是用于预测y变量的数学符号。
打印预测和观察结果,对每个观察值进行完整性检查,以防模型存在问题。
# walk-forward validation
history = [x for x in train]predictions = list()
for i in range(len(test)):
# predict
yhat = ...
predictions.append(yhat)
# observation
obs = test[i]history.append(obs)
print('>Predicted=%.3f, Expected=%3.f' % (yhat, obs))
4. Persistence(持续性模型)在数据分析和建模陷入困境之前的第一步是建立一个评估原型。
这里将为利用测试工具进行模型评估和性能测量,分别提供一套模版。通过该性能测量,可以将当前模型和其他更复杂的预测模型进行比较。
时间序列预测的预测原型被称为天真预测或Persistence。
在这里,先前时间步骤的观察结果将被用作于下一时间步长的预测。
我们可以将其直接插入上一节中定义的测试工具中。
下面罗列了完整的代码:
from pandas import Series
from sklearn.metrics import mean_squared_error
from math import sqrt
# load data
series = Series.from_csv('dataset.csv')
# prepare data
X = series.values
X = X.astype('float32'