How to Save an ARIMA Time Series Forecasting Model in Python (如何在Python中保存ARIMA时间序列预测模型)
How to Save an ARIMA Time Series Forecasting Model in Python
原文作者:Jason Brownlee 原文地址:https://machinelearningmastery.com/save-arima-time-series-forecasting-model-python/ 译者微博:@从流域到海域 译者博客:blog.csdn.net/solo95
如何在Python中保存ARIMA时间序列预测模型
自回归积分滑动平均模型(Autoregressive Integrated Moving Average Mode, ARIMA)是一个流行的时间序列分析和预测的线性模型。
statsmodels库中提供了Python中所使用ARIMA的实现。ARIMA模型可以保存到一个文件中,以便以后用于对新数据进行预测。statsmodels库的当前版本中有一个bug,会阻止保存的模型被加载。
在本教程中,您将了解如何诊断和解决此问题。
让我们开始吧。
照片由Les Chatfield提供,保留一些权利。
日均女性出生数据集
首先,我们来看一个标准的时间序列数据集,我们可以用它来理解有关statsmodels ARIMA实现的问题。
这个“日均女性出生”数据集描述了1959年加利福尼亚州每天的女性出生人数。
计数单位是一,365天都进行了观察。数据集的来源归功于Newton(1988)。
下载数据集并将其放在当前工作目录中,文件命名为“ daily-total-female-births.csv ”。
下面的代码片段将加载和绘制数据集。
from pandas import Series
from matplotlib import pyplot
series = Series.from_csv('daily-total-female-births.csv', header=0)
series.plot()
pyplot.show()
运行示例将数据集加载为Pandas系列,然后显示数据的线图。
Python环境
请确认您使用的是最新版本的statsmodels库。
你可以通过运行下面的脚本来进行确认:
import statsmodels
print('statsmodels: %s' % statsmodels.__version__)
运行脚本应该产生一个显示statsmodels 0.6或0.6.1的结果。
statsmodels: 0.6.1
您可以使用Python 2或3。
更新:我可以确认故障仍存在于statsmodels 0.8中并导致下列错误消息出现:
AttributeError: 'ARIMA' object has no attribute 'dates'
ARIMA模型保存bug
我们可以很容易地在“日均女性出生”数据集上训练一个ARIMA模型。
下面的代码片段在数据集上的训练出一个ARIMA(1,1,1)模型。
model.fit()函数返回一个ARIMAResults对象,我们可以在这个对象上调用save()保存到文件模型并且之后可以使用load()来加载它。
from pandas import Series
from statsmodels.tsa.arima_model import ARIMA
from statsmodels.tsa.arima_model import ARIMAResults
# load data
series = Series.from_csv('daily-total-female-births.csv', header=0)
# prepare data
X = series.values
X = X.astype('float32')
# fit model
model = ARIMA(X, order=(1,1,1))
model_fit = model.fit()
# save model
model_fit.save('model.pkl')
# load model
loaded = ARIMAResults.load('model.pkl')
运行本例将训练出模型并将其保存到文件中,而不会出现问题。
但当您尝试从文件加载模型时,会报告一个错误。
Traceback (most recent call last):
File "...", line 16, in <module>
loaded = ARIMAResults.load('model.pkl')
File ".../site-packages/statsmodels/base/model.py", line 1529, in load
return load_pickle(fname)
File ".../site-packages/statsmodels/iolib/smpickle.py", line 41, in load_pickle
return cPickle.load(fin)
TypeError: __new__() takes at least 3 arguments (1 given)
特别的,注意下面这一行:
TypeError: __new__() takes at least 3 arguments (1 given)
之前的步骤都没出错,那么我们如何解决这个问题呢?
ARIMA模型保存Bug解决方法
Zae Myung Kim在2016年9月发现了这个错误并报告了错误。
你可以在这里读到所有和它有关的信息:
这个错误是因为pickle所需要的一个函数(用于序列化Python对象的库)在statsmodels中没有定义。
在保存之前,必须在ARIMA模型中定义函数__getnewargs__,以定义构造对象所需的参数。
我们可以解决这个问题。修复涉及两件事情:
- 定义一个适用于ARIMA对象的__getnewargs__函数的实现 。
- 将这个新函数添加到ARIMA。
谢天谢地,Zae Myung Kim在他的bug报告中提供了一个函数的例子,所以我们可以直接使用它:
def __getnewargs__(self):
return ((self.endog),(self.k_lags, self.k_diff, self.k_ma)
Python允许我们对一个对象施加猴补丁操作,即使是像statsmodels这样的库。 (猴补丁(英语:Monkey patch),参见维基百科,有相应中文条目,译者注)
我们可以使用赋值在现有的对象上定义一个新的函数。
我们可以对ARIMA对象上的__getnewargs__函数做如下操作:
ARIMA.__getnewargs__ = __getnewargs__
下面列出了使用猴补丁在Python中加载和保存ARIMA模型的完整示例:
from pandas import Series
from statsmodels.tsa.arima_model import ARIMA
from statsmodels.tsa.arima_model import ARIMAResults
# monkey patch around bug in ARIMA class
def __getnewargs__(self):
return ((self.endog),(self.k_lags, self.k_diff, self.k_ma))
ARIMA.__getnewargs__ = __getnewargs__
# load data
series = Series.from_csv('daily-total-female-births.csv', header=0)
# prepare data
X = series.values
X = X.astype('float32')
# fit model
model = ARIMA(X, order=(1,1,1))
model_fit = model.fit()
# save model
model_fit.save('model.pkl')
# load model
loaded = ARIMAResults.load('model.pkl')
现在运行示例就可以成功加载模型,而不会出错。
概要
在这篇文章中,您了解了如何解决statsmodels ARIMA实现时的一个错误,该错误阻止了您将ARIMA模型保存到文件或从文件中加载ARIMA模型。
你学到了如何编写一个猴补丁来解决这个bug,以及如何证明它确实已经修复了。
- 北京允许无人驾驶路测 难道是为方便圣诞老人送礼?
- 小程序新增多项功能,优化100多个功能点,堪称重磅!
- 人工智能的回报率:对冲基金嵌入机器学习?
- “人工智能助力上海科创中心建设”国际高峰论坛圆满结束
- 纳米白与Pandas
- 人工智能来了!实体零售会变成什么样?
- 全国计算机等级考试重大改革!新增Python科目
- 福特:相比美国人中国人更欢迎自动驾驶未来
- Zzreal的大数据笔记-SparkDay03
- 一文读懂公有链、私有链、联盟链
- 你开车低头看个微信消息都能被拍的清清楚楚,因为有这些黑科技
- 开启程序员世界的Hello World
- TensorFlow实战——图像分类神经网络模型
- SQL,一门不是语言的语言?
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 责任链设计模式:老哥用程序生孩子
- LAMP架构应用实战—Apache服务介绍与安装01
- Excel合并
- 自定义异常为什么性能差,我来告诉你
- GitHub比较火的springBoot实战项目
- LAMP架构应用实战—Apache服务介绍与安装02
- AWS lambda and dynamodb with Java
- 用设计模式搞定女朋友,吃什么火锅,设计模式不香吗
- LAMP架构应用实战—Apache服务基于IP的虚拟主机配置
- MySQL集群搭建—GTID方式
- MySQL主从复制集群搭建
- LAMP架构应用实战—Apache服务基于端口虚拟主机配置
- MySQL主从复制架构介绍
- MySQL行锁、表锁、间隙锁,你都了解吗
- LAMP架构应用实战—Apache服务mod_expires模块介绍