刚开始接触时间序列数据时,进行样本外预测可能会令人困惑。
statsmodels Python API 提供了执行单步和多步样本外预测的函数。
在本教程中,您将清除关于使用 Python 中的时间序列数据进行样本外预测的任何困惑。
完成本教程后,您将了解:
- 如何进行单步样本外预测。
- 如何进行多步样本外预测。
- forecast() 和 predict() 函数之间的区别。
启动您的项目,阅读我的新书《Python 时间序列预测入门》,其中包含分步教程和所有示例的Python 源代码文件。
让我们开始吧。
- 2019 年 4 月更新:更新了数据集链接。
- 2019年8月更新:更新了数据加载以使用新的API。
- 2020 年 10 月更新:根据 API 更改更新了文件加载。
- 2020 年 12 月更新:将 ARIMA API 更新为最新版本的 statsmodels。
- 2020 年 12 月更新:由于 API 更改,修复了样本外示例。

如何在 Python 中使用 ARIMA 进行样本外预测
照片由 dziambel 提供,部分权利保留。
教程概述
本教程分为以下 5 个步骤
- 数据集描述
- 拆分数据集
- 开发模型
- 单步样本外预测
- 多步样本外预测
停止以**慢速**学习时间序列预测!
参加我的免费7天电子邮件课程,了解如何入门(附带示例代码)。
点击注册,同时获得该课程的免费PDF电子书版本。
1. 每日最低温度数据集
该数据集描述了澳大利亚墨尔本市 10 年(1981-1990 年)的每日最低温度。
单位是摄氏度,共有3650个观测值。数据来源归功于澳大利亚气象局。
将“daily-minimum-temperatures.csv” 文件下载到您的当前工作目录。
下面的示例将数据集加载为 Pandas Series。
1 2 3 4 5 6 7 8 9 10 |
# 时间序列的折线图 from pandas import read_csv from matplotlib import pyplot # 加载数据集 series = read_csv('daily-minimum-temperatures.csv', header=0, index_col=0) # 显示前几行 print(series.head(20)) # 数据集的折线图 series.plot() pyplot.show() |
运行示例将打印加载的数据集的前 20 行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
日期 1981-01-01 20.7 1981-01-02 17.9 1981-01-03 18.8 1981-01-04 14.6 1981-01-05 15.8 1981-01-06 15.8 1981-01-07 15.8 1981-01-08 17.4 1981-01-09 21.8 1981-01-10 20.0 1981-01-11 16.2 1981-01-12 13.3 1981-01-13 16.7 1981-01-14 21.5 1981-01-15 25.0 1981-01-16 20.7 1981-01-17 20.6 1981-01-18 24.8 1981-01-19 17.7 1981-01-20 15.5 |
还会创建一个时间序列的折线图。

每日最低温度数据集折线图
2. 拆分数据集
我们可以将数据集拆分为两部分。
第一部分是训练数据集,我们将用它来准备 ARIMA 模型。第二部分是测试数据集,我们将假装它不可用。正是这些时间步长将被视为样本外。
该数据集包含从 1981 年 1 月 1 日到 1990 年 12 月 31 日的数据。
我们将保留 1990 年 12 月的最后 7 天作为测试数据集,并将这些时间步长视为样本外。
具体来说,是 1990-12-25 到 1990-12-31。
1 2 3 4 5 6 7 |
1990-12-25,12.9 1990-12-26,14.6 1990-12-27,14.0 1990-12-28,13.6 1990-12-29,13.5 1990-12-30,15.7 1990-12-31,13.0 |
以下代码将加载数据集,将其拆分为训练集和验证集,并将它们分别保存到文件 dataset.csv 和 validation.csv 中。
1 2 3 4 5 6 7 8 |
# 分割数据集 from pandas import read_csv series = read_csv('daily-minimum-temperatures.csv', header=0, index_col=0) split_point = len(series) - 7 dataset, validation = series[0:split_point], series[split_point:] print('Dataset %d, Validation %d' % (len(dataset), len(validation))) dataset.to_csv('dataset.csv', index=False) validation.to_csv('validation.csv', index=False) |
运行示例,您现在应该有两个文件可以处理了。
dataset.csv 中的最后一条观测值是 1990 年平安夜。
1 |
1990-12-24,10.0 |
这意味着 1990 年圣诞节及之后的时间步长对于在 dataset.csv 上训练的模型来说是样本外的。
3. 开发模型
在本节中,我们将使数据平稳并开发一个简单的 ARIMA 模型。
数据具有很强的季节性。我们可以通过进行季节性差分来消除这种季节性并使数据平稳。也就是说,我们可以取某一天的观测值并减去一年前同一天的观测值。
这将得到一个平稳的数据集,我们可以在其中拟合模型。
1 2 3 4 5 6 7 |
# 创建差分序列 def difference(dataset, interval=1): diff = list() for i in range(interval, len(dataset)): value = dataset[i] - dataset[i - interval] diff.append(value) return numpy.array(diff) |
我们可以通过加上一年前的观测值来反转此操作。我们需要将此操作应用于从季节性调整数据中拟合的模型所做的任何预测。
1 2 3 |
# 反转差分值 def inverse_difference(history, yhat, interval=1): return yhat + history[-interval] |
我们可以拟合一个 ARIMA 模型。
将一个强大的 ARIMA 模型拟合到数据并不是本文的重点,因此,与其进行问题分析或网格搜索参数,不如选择一个简单的 ARIMA(7,0,7) 配置。
我们可以将所有这些内容整合在一起,如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
from pandas import read_csv from statsmodels.tsa.arima.model import ARIMA import numpy # 创建差分序列 def difference(dataset, interval=1): diff = list() for i in range(interval, len(dataset)): value = dataset[i] - dataset[i - interval] diff.append(value) return numpy.array(diff) # 加载数据集 series = read_csv('dataset.csv', header=0) # 季节性差分 X = series.values days_in_year = 365 differenced = difference(X, days_in_year) # 拟合模型 model = ARIMA(differenced, order=(7,0,1)) model_fit = model.fit() # 打印拟合模型的摘要 print(model_fit.summary()) |
运行示例加载数据集,进行季节性差分,然后拟合 ARIMA(7,0,7) 模型并打印拟合模型的摘要。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
SARIMAX 结果 ============================================================================== 因变量: y 观测值数量: 3278 模型: ARIMA(7, 0, 1) 对数似然值 -8673.748 日期: Mon, 28 Dec 2020 AIC 17367.497 时间: 08:12:26 BIC 17428.447 样本: 0 HQIC 17389.322 - 3278 协方差类型: opg ============================================================================== 系数 标准误差 z P>|z| [0.025 0.975] ------------------------------------------------------------------------------ 常数 0.0127 0.133 0.096 0.924 -0.247 0.273 ar.L1 1.1428 0.316 3.620 0.000 0.524 1.762 ar.L2 -0.4348 0.169 -2.577 0.010 -0.766 -0.104 ar.L3 0.0961 0.044 2.172 0.030 0.009 0.183 ar.L4 0.0125 0.029 0.425 0.671 -0.045 0.070 ar.L5 -0.0101 0.029 -0.352 0.725 -0.066 0.046 ar.L6 0.0119 0.026 0.464 0.643 -0.038 0.062 ar.L7 0.0088 0.025 0.356 0.722 -0.040 0.057 ma.L1 -0.6161 0.315 -1.955 0.051 -1.234 0.002 sigma2 11.6360 0.282 41.296 0.000 11.084 12.188 =================================================================================== Ljung-Box (L1) (Q): 0.00 Jarque-Bera (JB): 1.40 Prob(Q): 1.00 Prob(JB): 0.50 异方差性 (H): 0.84 偏度: -0.02 Prob(H) (双边): 0.00 峰度: 3.10 =================================================================================== |
我们现在准备探索如何使用该模型进行样本外预测。
4. 单步样本外预测
ARIMA 模型非常适合单步预测。
单步预测是对序列中紧随用于拟合模型的数据的下一个时间步长的预测。
在这种情况下,我们感兴趣的是 1990 年圣诞节的单步预测。
1 |
1990-12-25 |
预测函数
statsmodel ARIMAResults 对象提供了一个 forecast() 函数用于进行预测。
默认情况下,此函数执行单步样本外预测。因此,我们可以直接调用它进行预测。forecast() 函数的结果是一个包含预测值、预测标准误差和置信区间信息的数组。现在,我们只对这个预测的第一个元素感兴趣,如下所示。
1 2 |
# 单步样本外预测 forecast = model_fit.forecast()[0] |
一旦做出预测,我们就可以反转季节性差分,并将值转换回原始尺度。
1 2 |
# 反转差分预测,使其更易于使用 forecast = inverse_difference(X, forecast, days_in_year) |
完整的示例列在下面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
from pandas import read_csv from statsmodels.tsa.arima.model import ARIMA import numpy # 创建差分序列 def difference(dataset, interval=1): diff = list() for i in range(interval, len(dataset)): value = dataset[i] - dataset[i - interval] diff.append(value) return numpy.array(diff) # 反转差分值 def inverse_difference(history, yhat, interval=1): return yhat + history[-interval] # 加载数据集 series = read_csv('dataset.csv', header=0) # 季节性差分 X = series.values days_in_year = 365 differenced = difference(X, days_in_year) # 拟合模型 model = ARIMA(differenced, order=(7,0,1)) model_fit = model.fit() # 单步样本外预测 forecast = model_fit.forecast()[0] # 反转差分预测,使其更易于使用 forecast = inverse_difference(X, forecast, days_in_year) print('Forecast: %f' % forecast) |
运行示例将打印 14.8 度,这接近 validation.csv 文件中预期的 12.9 度。
1 |
Forecast: 14.861669 |
预测函数
statsmodel ARIMAResults 对象还提供了一个 predict() 函数用于进行预测。
predict 函数可用于预测任意的样本内和样本外时间步长,包括下一个样本外预测时间步长。
predict 函数需要指定开始和结束时间。这些可以是相对于用于拟合模型的数据集开头的secutive时间步长的索引,例如:
1 2 3 4 |
# 单步样本外预测 start_index = len(differenced) end_index = len(differenced) forecast = model_fit.predict(start=start_index, end=end_index) |
开始和结束时间也可以是日期时间字符串或“datetime”类型;例如:
1 2 3 |
start_index = '1990-12-25' end_index = '1990-12-25' forecast = model_fit.predict(start=start_index, end=end_index) |
和
1 2 3 4 |
from pandas import datetime start_index = datetime(1990, 12, 25) end_index = datetime(1990, 12, 26) forecast = model_fit.predict(start=start_index, end=end_index) |
使用时间步长索引以外的任何内容都会在我的系统上导致错误,如下所示:
1 |
AttributeError: 'NoneType' object has no attribute 'get_loc' |
也许您会更幸运;目前,我将坚持使用时间步长索引。
完整的示例列在下面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
from pandas import read_csv from statsmodels.tsa.arima.model import ARIMA import numpy from pandas import datetime # 创建差分序列 def difference(dataset, interval=1): diff = list() for i in range(interval, len(dataset)): value = dataset[i] - dataset[i - interval] diff.append(value) return numpy.array(diff) # 反转差分值 def inverse_difference(history, yhat, interval=1): return yhat + history[-interval] # 加载数据集 series = read_csv('dataset.csv', header=0) # 季节性差分 X = series.values days_in_year = 365 differenced = difference(X, days_in_year) # 拟合模型 model = ARIMA(differenced, order=(7,0,1)) model_fit = model.fit() # 单步样本外预测 start_index = len(differenced) end_index = len(differenced) forecast = model_fit.predict(start=start_index, end=end_index) # 反转差分预测,使其更易于使用 forecast = inverse_difference(X, forecast, days_in_year) print('Forecast: %f' % forecast) |
运行示例将打印与使用 forecast() 函数时相同的预测结果。
1 |
Forecast: 14.861669 |
您可以看到 predict 函数更灵活。您可以指定样本内或样本外的任何点或连续的预测区间。
既然我们知道如何进行单步预测,现在就可以进行一些多步预测了。
5. 多步样本外预测
我们还可以使用 forecast() 和 predict() 函数进行多步预测。
对于天气数据,通常会进行一周(7 天)的预测,因此在本节中,我们将研究预测未来 7 个样本外时间步长的每日最低温度。
预测函数
forecast() 函数有一个名为 steps 的参数,允许您指定要预测的时间步长数。
默认情况下,此参数设置为 1,表示单步样本外预测。我们可以将其设置为 7 以获得未来 7 天的预测。
1 2 |
# 多步样本外预测 forecast = model_fit.forecast(steps=7)[0] |
然后,我们可以逐一反转每个预测的时间步长,并打印这些值。请注意,要反转 t+2 的预测值,我们需要 t+1 的反转预测值。在这里,我们将它们添加到名为 history 的列表末尾,以便在调用 inverse_difference() 时使用。
1 2 3 4 5 6 7 8 |
# 反转差分预测,使其更易于使用 history = [x for x in X] day = 1 for yhat in forecast: inverted = inverse_difference(history, yhat, days_in_year) print('Day %d: %f' % (day, inverted)) history.append(inverted) day += 1 |
完整的示例列在下面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
from pandas import read_csv from statsmodels.tsa.arima.model import ARIMA import numpy # 创建差分序列 def difference(dataset, interval=1): diff = list() for i in range(interval, len(dataset)): value = dataset[i] - dataset[i - interval] diff.append(value) return numpy.array(diff) # 反转差分值 def inverse_difference(history, yhat, interval=1): return yhat + history[-interval] # 加载数据集 series = read_csv('dataset.csv', header=0) # 季节性差分 X = series.values days_in_year = 365 differenced = difference(X, days_in_year) # 拟合模型 model = ARIMA(differenced, order=(7,0,1)) model_fit = model.fit() # 多步样本外预测 forecast = model_fit.forecast(steps=7) # 反转差分预测,使其更易于使用 history = [x for x in X] day = 1 for yhat in forecast: inverted = inverse_difference(history, yhat, days_in_year) print('Day %d: %f' % (day, inverted)) history.append(inverted) day += 1 |
运行示例将打印未来 7 天的预测。
1 2 3 4 5 6 7 |
Day 1: 14.861669 Day 2: 15.628784 Day 3: 13.331349 Day 4: 11.722413 Day 5: 10.421523 Day 6: 14.415549 Day 7: 12.674711 |
预测函数
predict() 函数也可以预测未来 7 个样本外时间步长。
使用时间步长索引,我们可以将结束索引指定为未来 6 个时间步长;例如:
1 2 3 4 |
# 多步样本外预测 start_index = len(differenced) end_index = start_index + 6 forecast = model_fit.predict(start=start_index, end=end_index) |
完整的示例如下所示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
from pandas import read_csv from statsmodels.tsa.arima.model import ARIMA import numpy # 创建差分序列 def difference(dataset, interval=1): diff = list() for i in range(interval, len(dataset)): value = dataset[i] - dataset[i - interval] diff.append(value) return numpy.array(diff) # 反转差分值 def inverse_difference(history, yhat, interval=1): return yhat + history[-interval] # 加载数据集 series = read_csv('dataset.csv', header=0) # 季节性差分 X = series.values days_in_year = 365 differenced = difference(X, days_in_year) # 拟合模型 model = ARIMA(differenced, order=(7,0,1)) model_fit = model.fit() # 多步样本外预测 start_index = len(differenced) end_index = start_index + 6 forecast = model_fit.predict(start=start_index, end=end_index) # 反转差分预测,使其更易于使用 history = [x for x in X] day = 1 for yhat in forecast: inverted = inverse_difference(history, yhat, days_in_year) print('Day %d: %f' % (day, inverted)) history.append(inverted) day += 1 |
运行示例将产生与上一节中调用 forecast() 函数相同的结果,正如您所料。
1 2 3 4 5 6 7 |
Day 1: 14.861669 Day 2: 15.628784 Day 3: 13.331349 Day 4: 11.722413 Day 5: 10.421523 Day 6: 14.415549 Day 7: 12.674711 |
总结
在本教程中,您学习了如何使用 Python 中的 statsmodels 进行样本外预测。
具体来说,你学到了:
- 如何进行单步样本外预测。
- 如何进行 7 天多步样本外预测。
- 在预测时如何使用 forecast() 和 predict() 函数。
您对样本外预测或本帖子有任何疑问吗?请在评论中提问,我将尽力回答。
您的教程是我在互联网上找到的最有帮助的机器学习资源,它们对我工作和个人项目非常有帮助。我不知道您是否接受请求,但我很希望有一天能看到一系列关于推荐系统的帖子!
谢谢 Steve,还有很棒的建议!谢谢。
你好,
这是一个非常好的例子。您是否知道 ARIMA 类是否允许在不经过拟合过程的情况下定义模型规范?假设我有一些参数是使用我不再拥有的数据集估计的,但我仍然想进行预测。
谢谢
我预计您可以在 ARIMA 模型中显式设置系数。
抱歉,我没有示例,这篇帖子可能有关联
https://machinelearning.org.cn/make-manual-predictions-arima-models-python/
您好, sir,您解决这个问题了吗?我也想在手动 ARIMA 预测模型中进行多步样本外预测。请回答我的问题。
您好 Tim
请问我们如何设置一个 for 循环来进行滚动预测原点,以便预测数据集之外的新值?
先生,
是否可以使用 LSTM RNN 来实现相同的目标?
如果是,您能否提供一篇博文?
谢谢你
是的。
我的任何 LSTM 教程都显示了如何进行样本外预测。例如:
https://machinelearning.org.cn/multi-step-time-series-forecasting-long-short-term-memory-networks-python/
我尝试运行上面的示例,不进行任何季节性差分,使用以下代码。
from pandas import Series
from matplotlib import pyplot
from pandas import Series
from statsmodels.tsa.arima_model import ARIMA
# 加载数据集
series = Series.from_csv(‘daily-minimum-temperatures.csv’, header=0)
print(series.head(20))
series.plot()
pyplot.show()
split_point = len(series) – 7
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’)
series = Series.from_csv(‘dataset.csv’, header=None)
model = ARIMA(series, order=(7,0,1))
model_fit = model.fit(disp=0)
forecast = model_fit.forecast(steps=7)[0]
print(‘Forecast: %f’ % forecast)
对于这段代码,我收到一个错误。
TypeError: only length-1 arrays can be converted to Python scalars
我该如何解决这个问题?它对于单步预测做得很好。
我建议仔细检查您的数据,确保任何页脚信息都已删除。
“季节性差分”是什么意思?
以及...
“一旦做出预测,我们就可以反转季节性差分,并将值转换回原始尺度。”
这段代码是否值得用非季节性数据进行测试,或者此网站上是否有其他针对非季节性方法的ARIMA教程?
请看这篇文章
https://machinelearning.org.cn/seasonal-persistence-forecasting-python/
还有这篇文章
https://machinelearning.org.cn/time-series-seasonality-with-python/
请使用博客的搜索功能。
如果我假装测试分区中的数据未给出,那么除了季节性清理之外,此教程是否也做了同样的事情?
https://machinelearning.org.cn/tune-arima-parameters-python/
嗨 Jason,这篇文章确实非常棒。
我有一个疑问,假设来自气象站的未来数据由于某些故障而丢失,如果我们随机丢失传感器的一些数据,我需要使用ARIMA通过预测方法来填充它。
但是这里需要开始和结束日期参数,所以我可以只传递开始日期并留空结束日期吗?这样可行吗?
也许您可以自己尝试一下,看看哪种最适合您的用例。
我能从这个例子中获得训练RMSE吗?这里涉及训练吗?
模型会进行训练,然后使用训练好的模型进行预测。
考虑阅读并完成该教程。
我已经做了好几次了。
我如何从模型中获得训练RMSE?
请参阅这篇关于在使用模型进行样本外预测之前如何评估模型的方法。
https://machinelearning.org.cn/backtest-machine-learning-models-time-series-forecasting/
请参阅这篇帖子,以了解评估模型与使用最终模型进行预测之间的区别。
https://machinelearning.org.cn/train-final-machine-learning-model/
我实际上是指从示例中的模型获取训练RMSE。
据我理解,模型在进行样本外预测之前已经训练过了。
如果我们放入一个
print(model_fit.summary())
在拟合/训练之后立即打印一些信息,但没有训练RMSE。
A)
是否有一种方法可以使用summary信息来获得训练RMSE?
B)
在Python中是否有方法可以像其他语言一样获取model_fit对象的所有属性和方法?
是的,本教程假定您已经估计了模型的技能,并且现在已准备好使用它来进行预测。
估计模型的技能是另一项任务。您可以使用前向验证或训练/测试拆分评估来完成此操作。
这是发生训练的行吗?
model = ARIMA(differenced, order=(7,0,1))
不是这里
是的,我知道。我实际上认为A)和B)会有直接的答案。
我将用于存档。
如果我写:‘split_point = len(series) – 0’,而我数据集的最后数据点是今天的。
明天会有有效的预测吗?
非常感谢您这篇精彩的文章,我遵循了所有步骤,它们似乎都运行正常,我寻求您的支持,博士,以帮助我组织我的项目。
我有一些节点的原始温度读数数据(每小时读数),我选择了训练集,并将其分为测试集和训练集。
我使用了ARINA模型进行训练和测试,并获得了测试MSE:3.716。
现在我需要将大量的原始数据暴露给训练好的模型,然后将预测值与实际值在同一个csv文件中得到。
我该怎么办?
*ARIMA
我不确定我是否理解。考虑这篇关于如何评估时间序列模型的文章。
https://machinelearning.org.cn/backtest-machine-learning-models-time-series-forecasting/
感谢Jason发表这篇精彩的文章……它非常详细且易于理解……
您是否有类似的关于LSTM神经网络算法的内容?例如——如何在Python中使用LSTM进行样本外预测。
如果没有,您是否会写一篇像这样详细解释的博客?我相信有很多人有同样的问题。
我关于LSTM的几乎所有帖子都展示了如何进行样本外预测。代码被封装在前向验证中。
嗨,Jason,
非常感谢您这堂课。它非常直接且易于遵循。通过标准指标来评估预测将是一个很好的补充。我们分离了验证集并预测了该周的值,但没有进行比较以查看预测的准确性。
在此基础上,我想问,使用R^2来评估时间序列预测与测试数据相比是否合理?我正在尝试为我正在分析的时间序列创建绝对基准,并希望报告单位无关的指标,即不一定是必需以问题单位尺度表示的标准RMSE。通过标准化数据,使其均值为零且方差为一,拟合ARIMA,进行预测并报告该RMSE怎么样?我一直在这样做并取得R^2,结果相当可解释。RMSE:0.149 / R^2:0.8732,但我只是想知道这样做是否会使某些东西无效。只想确保我的过程是正确的。
谢谢!
我们在其他帖子中也这样做。事实上,还有几十篇帖子。
这篇帖子是关于“我如何进行预测,但我不知道真实答案”的。
是的,如果R^2对您有意义,您可以在您的领域中对其进行解释。
总的来说,我建议将所有转换反转到预测上,然后至少对RMSE或MAE进行模型技能评估,如果您想要苹果对苹果的比较。对于R^2来说,这可能不太重要。
真的太棒了。非常感谢教授
谢谢。另外,我不是教授。
我的代码出现这个错误
回溯(最近一次调用)
File “..”, line 22, in
differenced = difference(X, days_in_year)
File “..”, line 9, in difference
value = dataset[i] – dataset[i – interval]
TypeError: unsupported operand type(s) for -: ‘str’ and ‘str’
Cant tell where the problem is.
也许检查您是否正确加载了数据(作为实数值),并且您已从帖子中复制了所有代码而没有多余的空格。
我遇到了同样的问题,而且我发现很多人也遇到了。问题在于参数index_col=0一开始就存在,但在很多人可能复制的最终代码块中却丢失了。
所以,请确保您有这行
series = read_csv(url, header=0, index_col=0)
感谢您的反馈和建议Yogesh!
嗨,Jason,
感谢您如此详细的解释。非常清楚。
您知道是否可以将ARMA模型的拟合参数(ARMAResults.params)应用于其他数据集吗?
我有一个在线过程可以进行预测,我只想有一个学习过程(使用fit()函数一次)。其余时间,我想将之前找到的参数应用于数据。
提前感谢!
是的,您可以使用网格搜索。
https://machinelearning.org.cn/grid-search-arima-hyperparameters-with-python/
你解决问题了吗?
期待您的回复。
Ciao Jason,
感谢这个教程以及所有与时间序列相关的教程。您的帖子和代码总是有条理的。
顺便说一句,我仍然对ARIMA的一些可能更概念性的东西感到困惑。
ARIMA参数指定了它用于预测的滞后。
在您的情况下,您使用了p=7作为示例,以便考虑到前一周。
第一个愚蠢的问题是,如果我只查看我的窗口/滞后,为什么我需要拟合一整年的数据?
第二个问题是,我在拟合模型时得到一个误差,即使我使用较短的训练集(2天vs 1年),这个误差也非常小,这进一步支持了我的第一点。
我错过了什么?
谢谢
模型需要大量的示例才能泛化到新案例。
数据越多通常越好,直到模型技能达到边际效益递减点。
嗨Jason。感谢这篇精彩的文章。
但我有一个问题,是否可以使用ARIMA模型拟合多变量时间序列?假设数据集中每个时间步都有一个312维。
谢谢!
是的,但是您需要使用ARIMA的扩展,称为ARIMAX。抱歉,我没有示例。
布朗利博士,非常感谢您的教程!
我搜索过了但没找到任何东西——也许是我的错…
但是您是否有关于预测有限历史观测值的教程或建议?具体来说,我遇到一些传感器只有非常有限的历史观测值(完整但很短,比如说只在线一个月),但我有很多传感器可能用作历史类比(多年数据)。
我考虑过构建一个过程,该过程使用每个大型历史传感器作为“训练”集,并遍历每个传感器,找到哪个传感器最能预测新传感器的观测读数。
但是,我很难找到任何既定的最佳实践。您有什么建议吗?
如果没有,我理解,但我真的很感激您在这些教程和您的书中提供的所有见解!
很好的问题。
您或许可以使用历史数据或不同但相似传感器的模型(在某个维度上)。发挥创意!
我主要会关注RMSE和MAE来衡量准确性,对吧?我是否还应该考虑其他衡量适应性的指标?
不,MSE和RMSE是回归问题的误差得分。准确性是分类问题的(预测标签)。
嗨,很棒的教程。关于差分函数的一个问题。它是如何考虑闰年的?
它不考虑,这将会是这个教程的一个很好的扩展。
由于这是一个每日预测,是否可以将seasonal_decompose应用于本教程中使用的数据集?我见过的seasonal_decompose的大多数应用通常都是针对月度和季度数据。
是的,您可以在此数据上使用它。
感谢您提供的精彩教程。我想问一下,是否可以将您教程末尾预测的多个步长值存储到一个变量中,以便与实际/真实值进行比较?
当然,您可以将它们分配给变量或保存到文件中。
感谢您提供的精彩博客!我很难将多步值赋给变量,您能帮我一下吗?
提前感谢!
问题究竟是什么?
嗨Jason。感谢您提供的精彩博客,您能帮我将多步预测值赋给变量吗。
您可以使用forecast()函数并指定步数。
感谢您的回复Jason,我使用forecast()函数和predict()函数得到的值不同,Predict函数的值更准确,所以我想将它们赋给变量,可以吗?如果可以,我需要做哪些更改。
提前感谢!
这很令人惊讶,如果不是不可能的话。
也许请确认您在这两种情况下都提供了相同的参数/数据/模型?
没问题,我明白了——谢谢
@Jason,谢谢您,但我的数据集格式不同,它是YYYY-MM-DD HH:MI:SS格式,数据是每小时数据,假设我们有直到2017年11月25日23:00 5.486691952的数据
我们需要预测第二天的数据,所以我们需要预测接下来的24个步骤,需要怎么做?
这方面需要帮助。
当然,您可以在加载Pandas Series时指定日期时间格式。
您可以使用predict()函数预测多个步长。
在我之前的问题之上再问一个问题,
假设我的数据是每小时数据,我现在有一个一周的数据,根据您的代码,days_in_year参数是否应该设置为7?
根据我的数据的ACF和PACF,我的模型应该是ARIMA(xyz, order=(4,1,2))
并将days_in_year参数设置为7,我的结果是正确的,但我不确定有多正确……请@Jason详细说明一下。
我建议针对您的特定数据调整模型。
嗨,Jason,
我真是打扰您了,但这是我的最后一个问题,我的模型已经准备好了,并且根据ACF、PACF图预测了p、d、q值。
现在我的代码看起来是这样的
这里,当我将obs添加到历史数据时,如果我将我的预测添加到历史记录中,然后将其传递给模型,我是否必须在循环中运行它来再次预测pdq值?
我的问题是,如果我们进行递归多步预测,是否必须运行历史数据来构建多个ARIMA模型,还是可以只使用history.append(yhat)在上面的代码中得到我的结果?
递归多步意味着您将使用预测作为历史来重新拟合模型。
回复我之前的回复,所以预测要添加为历史,这没问题,我们将使用history.append(yhat)而不是history.append(obs),但我们是否必须使用相同的ARIMA模型,即6,1,2运行上述代码,或者对于每个历史记录,我们将确定pdq值并运行多个ARIMA模型来获得下一个预测?
我希望您能明白我的意思。
这取决于您。
你好,
我实际上正在做一个关于隐含波动率预测的项目。我的预测是多输出的,您的教程非常有帮助,但我只想澄清一件事。
1. 在所有数据集上进行训练而不将其分为训练/测试集是否可以?
2. 预测函数选择的数据样本是什么?我的意思是它是原始数据集的最后7个值吗?
谢谢你
您必须在训练期间未见过的数据上评估模型的技能。以下是使用时间序列进行此操作的方法。
https://machinelearning.org.cn/backtest-machine-learning-models-time-series-forecasting/
我们如何添加更多输入参数?例如,我想根据历史预测来预测天气,但我也想考虑,比如过去10年下雨天的总数,并让两者都影响我的预测?
您可能需要使用不同的线性模型,如ARIMAX。
谢谢你。
您是否有我可以学习或作为基础来构建自己预测的示例?类似于您上面分享的文章?
也许可以尝试搜索博客,看看是否有合适的教程?
我会做的。谢谢!
嗨Jason,假设我想预测未来365天的值,我是否只需将下面的行更改为
forecast = model_fit.forecast(steps=365)[0]
这样可以吗?谢谢!
是的,但预计准确度会非常差。
非常感谢Jason!但只是快速向您确认一下,为什么您要将数据集分成两个不同的csv:dataset.csv和validation.csv?每个csv的目的是什么?
这篇帖子可能会澄清一些问题。
https://machinelearning.org.cn/difference-test-validation-datasets/
嗨,Jason,
感谢您与我们分享如此精彩的文章,我一直在寻找这样的文章。
但是,当我运行“我们可以将所有这些内容组合如下:”下面的代码块5时,我遇到了“ValueError:计算出的初始AR系数不是平稳的。”错误。
如果我在Sypder下运行它,我得到“无法导入名称‘recarray_select’”的错误。
如果您能给我一些关于如何解决此问题的线索,我将不胜感激。
谢谢!
Chuck
这是使用帖子中提供的数据还是您自己的数据?
您可以在此处了解有关平稳性的更多信息
https://machinelearning.org.cn/time-series-data-stationary-python/
我们如何计算总RMSE?
预测值和期望值之间均方差的平方根。
嗨,Jason,
感谢这篇精彩的帖子。
我无法理解的一点是,我们正在对训练模型的数据集(dataset.csv)的相同数据集进行未来7天的预测。
换句话说,在最初的步骤中,我们将数据分为“dataset.csv”和“validation.csv”,然后我们在“dataset.csv”上拟合ARIMA,但我们在进行预测之前从未调用过“validation.csv”。它是如何工作的?
不,我们正在对 dataset.csv 的末尾进行预测,就好像 validation.csv 不存在一样。然后我们可以查看 validation.csv 来比较我们的预测。
也许重读一下教程?
是的!明白了。实际上,我还有外生输入。所以,我也不得不使用“validation”数据集。
很棒。
嗨,jason
你能告诉我为什么我们那样对待测试数据吗?
那么,如果我们不分离训练和测试数据,会怎么样?
在上面的教程中,我们假装我们在进行样本外预测,也就是说,我们不知道真实的结果值。
如果进行多元分析,即数据集中有3个额外特征,您能否告诉我代码中应该更改什么?
需要使用不同的方法。我希望很快有示例。
你好 Jason,感谢您的帖子……非常直观。我正在进行第3步:开发模型。我回顾了另一篇关于如何选择 ARIMA 配置网格参数的文档,并得出了 (10,0,0) 且 MSerror 最低。我这样做:
# 季节性差分
X = series.values
days_in_year = 365
differenced = difference(X, days_in_year)
# 拟合模型
model = ARIMA(differenced, order=(10,0,0))
然后得到错误:“自由度不足,无法估计”。
我的数据是月度级别(例如,2014年1月31日,2014年2月28日,2014年3月31日)……从2014年到2017年,每年的数据有12个读数,外加2018年的3个读数,总共52个读数。我需要根据这个来更改#季节性差分吗?
谢谢
如果数据具有季节性成分,最好进行季节性调整,或通过SARIMA直接对其进行建模。
我遇到了同样的问题,我该怎么办?
@ Jason
感谢您的文章,这很有帮助。
我使用了洗发水销售数据集,并使用了ARIMA Forecast & Predict 函数来预测未来12个月,但我得到了不同的结果。
也许您所做的与教程不同?
你好,先生,
您能告诉我如何将预测输出保存到CSV吗?
谢谢!
您可以通过 numpy 将数组保存为 CSV 文件。
https://docs.scipy.org.cn/doc/numpy-1.14.0/reference/generated/numpy.savetxt.html
你好,@Jason
我尝试使用 predict(start, end),但我发现只有整数参数才有效。我想通过日期指定开始和结束,但它给了我一个错误:
‘仅整数、切片(
:
)、省略号(...
)、numpy.newaxis(None
)和整数或布尔数组是有效的索引器’我在网上搜索了很多,但都没有成功。非常感谢!
API 说它支持日期,我假设您的数据必须是 pandas Series。但我没有尝试过,抱歉。
如果我的数据集少于365天,它会在以下代码中显示错误:如果我的数据集只有50行,该如何执行?
from pandas import Series
from statsmodels.tsa.arima_model import ARIMA
import numpy
# 创建差分序列
def difference(dataset, interval=1)
diff = list()
for i in range(interval, len(dataset))
value = dataset[i] – dataset[i – interval]
diff.append(value)
return numpy.array(diff)
# 反转差分值
def inverse_difference(history, yhat, interval=1)
return yhat + history[-interval]
# 加载数据集
series = Series.from_csv(‘dataset.csv’, header=None)
# 季节性差分
X = series.values
days_in_year = 365
differenced = difference(X, days_in_year)
# 拟合模型
model = ARIMA(differenced, order=(7,0,1))
model_fit = model.fit(disp=0)
# 多步样本外预测
forecast = model_fit.forecast(steps=7)[0]
# 反转差分预测,使其更易于使用
history = [x for x in X]
day = 1
for yhat in forecast
inverted = inverse_difference(history, yhat, days_in_year)
print(‘Day %d: %f’ % (day, inverted))
history.append(inverted)
day += 1
抱歉,我无法调试您的示例。
我正试图将此代码应用于其他数据集,但出现了此错误。请,任何帮助?
C:\Users\Fel\Anaconda3\lib\site-packages\statsmodels\tsa\tsatools.py:676: RuntimeWarning: divide by zero encountered in true_divide
invmacoefs = -np.log((1-macoefs)/(1+macoefs))
C:\Users\Fel\Anaconda3\lib\site-packages\statsmodels\tsa\tsatools.py:650: RuntimeWarning: invalid value encountered in true_divide
newparams = ((1-np.exp(-params))/(1+np.exp(-params))).copy()
C:\Users\Fel\Anaconda3\lib\site-packages\statsmodels\tsa\tsatools.py:651: RuntimeWarning: invalid value encountered in true_divide
tmp = ((1-np.exp(-params))/(1+np.exp(-params))).copy()
—————————————————————————
LinAlgError Traceback (most recent call last)
in ()
24 # fit model
25 model = ARIMA(differenced, order=(7,0,1))
-> 26 model_fit = model.fit(disp=0)
27 # multi-step out-of-sample forecast
28 forecast = model_fit.forecast(steps=period_forecast)[0]
~\Anaconda3\lib\site-packages\statsmodels\tsa\arima_model.py in fit(self, start_params, trend, method, transparams, solver, maxiter, full_output, disp, callback, start_ar_lags, **kwargs)
957 maxiter=maxiter,
958 full_output=full_output, disp=disp,
-> 959 callback=callback, **kwargs)
960 params = mlefit.params
961
~\Anaconda3\lib\site-packages\statsmodels\base\model.py in fit(self, start_params, method, maxiter, full_output, disp, fargs, callback, retall, skip_hessian, **kwargs)
464 callback=callback,
465 retall=retall,
-> 466 full_output=full_output)
467
468 # NOTE: this is for fit_regularized and should be generalized
~\Anaconda3\lib\site-packages\statsmodels\base\optimizer.py in _fit(self, objective, gradient, start_params, fargs, kwargs, hessian, method, maxiter, full_output, disp, callback, retall)
189 disp=disp, maxiter=maxiter, callback=callback,
190 retall=retall, full_output=full_output,
-> 191 hess=hessian)
192
193 optim_settings = {‘optimizer’: method, ‘start_params’: start_params,
~\Anaconda3\lib\site-packages\statsmodels\base\optimizer.py in _fit_lbfgs(f, score, start_params, fargs, kwargs, disp, maxiter, callback, retall, full_output, hess)
408 callback=callback, args=fargs,
409 bounds=bounds, disp=disp,
-> 410 **extra_kwargs)
411
412 if full_output
~\Anaconda3\lib\site-packages\scipy\optimize\lbfgsb.py in fmin_l_bfgs_b(func, x0, fprime, args, approx_grad, bounds, m, factr, pgtol, epsilon, iprint, maxfun, maxiter, disp, callback, maxls)
197
198 res = _minimize_lbfgsb(fun, x0, args=args, jac=jac, bounds=bounds,
-> 199 **opts)
200 d = {‘grad’: res[‘jac’],
201 ‘task’: res[‘message’],
~\Anaconda3\lib\site-packages\scipy\optimize\lbfgsb.py in _minimize_lbfgsb(fun, x0, args, jac, bounds, disp, maxcor, ftol, gtol, eps, maxfun, maxiter, iprint, callback, maxls, **unknown_options)
333 # until the completion of the current minimization iteration.
334 # Overwrite f and g
-> 335 f, g = func_and_grad(x)
336 elif task_str.startswith(b’NEW_X’)
337 # new iteration
~\Anaconda3\lib\site-packages\scipy\optimize\lbfgsb.py in func_and_grad(x)
278 if jac is None
279 def func_and_grad(x)
-> 280 f = fun(x, *args)
281 g = _approx_fprime_helper(x, fun, epsilon, args=args, f0=f)
282 return f, g
~\Anaconda3\lib\site-packages\scipy\optimize\optimize.py in function_wrapper(*wrapper_args)
291 def function_wrapper(*wrapper_args)
292 ncalls[0] += 1
-> 293 return function(*(wrapper_args + args))
294
295 return ncalls, function_wrapper
~\Anaconda3\lib\site-packages\statsmodels\base\model.py in f(params, *args)
438
439 def f(params, *args)
-> 440 return -self.loglike(params, *args) / nobs
441
442 if method == ‘newton’
~\Anaconda3\lib\site-packages\statsmodels\tsa\arima_model.py in loglike(self, params, set_sigma2)
778 method = self.method
779 if method in [‘mle’, ‘css-mle’]
-> 780 return self.loglike_kalman(params, set_sigma2)
781 elif method == ‘css’
782 return self.loglike_css(params, set_sigma2)
~\Anaconda3\lib\site-packages\statsmodels\tsa\arima_model.py in loglike_kalman(self, params, set_sigma2)
788 Compute exact loglikelihood for ARMA(p,q) model by the Kalman Filter.
789 “””
-> 790 return KalmanFilter.loglike(params, self, set_sigma2)
791
792 def loglike_css(self, params, set_sigma2=True)
~\Anaconda3\lib\site-packages\statsmodels\tsa\kalmanf\kalmanfilter.py in loglike(cls, params, arma_model, set_sigma2)
647 loglike, sigma2 = kalman_loglike.kalman_loglike_double(y, k,
648 k_ar, k_ma, k_lags, int(nobs), Z_mat,
-> 649 R_mat, T_mat)
650 elif issubdtype(paramsdtype, np.complex128)
651 loglike, sigma2 = kalman_loglike.kalman_loglike_complex(y, k,
kalman_loglike.pyx in statsmodels.tsa.kalmanf.kalman_loglike.kalman_loglike_double()
kalman_loglike.pyx in statsmodels.tsa.kalmanf.kalman_loglike.kalman_filter_double()
~\Anaconda3\lib\site-packages\numpy\linalg\linalg.py in pinv(a, rcond)
1722 return wrap(res)
1723 a = a.conjugate()
-> 1724 u, s, vt = svd(a, full_matrices=False)
1725
1726 # discard small singular values
~\Anaconda3\lib\site-packages\numpy\linalg\linalg.py in svd(a, full_matrices, compute_uv)
1442
1443 signature = ‘D->DdD’ if isComplexType(t) else ‘d->ddd’
-> 1444 u, s, vh = gufunc(a, signature=signature, extobj=extobj)
1446 u = u.astype(result_t, copy=False)
1447 s = s.astype(_realType(result_t), copy=False)
~\Anaconda3\lib\site-packages\numpy\linalg\linalg.py in _raise_linalgerror_svd_nonconvergence(err, flag)
96
97 def _raise_linalgerror_svd_nonconvergence(err, flag)
-> 98 raise LinAlgError(“SVD did not converge”)
99
100 def get_linalg_error_extobj(callback)
LinAlgError: SVD did not converge
也许可以尝试其他模型配置?
也许可以先对数据进行缩放或差分?
也许尝试更多或更少的数据?
真是杰出的工作。我一直在网上搜索预测和预测函数,这让我的日子变得美好。谢谢你提供的宝贵知识。
如果您有 YouTube 频道,请分享您的 YouTube 频道链接,我很乐意订阅。
谢谢。
我不制作视频。开发者通过实践学习,而不是观看。
我的代码出现这个错误
回溯(最近一次调用)
File “..”, line 22, in
differenced = difference(X, days_in_year)
File “..”, line 9, in difference
value = dataset[i] – dataset[i – interval]
TypeError: unsupported operand type(s) for -: ‘str’ and ‘str’
Cant tell where the problem is.
请确保您复制了完整的示例并保留了缩进。
谢谢 Jason。这非常有帮助。
当我运行原始数据集,进行训练和测试时,我得到了 0.09 的 MSE,这非常好,我使用的是 (p,d,q) 为 2,1,0。
我的数据集包含 60 个观测值,我将其中 12 个放入验证集。
当我使用 step=12 进行预测,并与验证集进行 MSE 计算时,我得到了 0.42 的 MSE。
这是预期的吗?这是一个好的衡量标准吗?
致敬
Bhadri。
“好”的概念确实是特定于问题的,我在以下内容中对此进行了更详细的解释
https://machinelearning.org.cn/faq/single-faq/how-to-know-if-a-model-has-good-performance
嗨,Jason,
非常感谢您的帖子!您的帖子都非常清晰易懂。我无法理解那些数学性很强的东西,它们只会让我感到困惑。
我有一个问题。如果我的日数据是周一至周五,我应该将一年中的天数调整为 194 天而不是 365 天吗?这是今年除去德国节假日和周末的总天数。
此致,
S:N
这确实取决于您是否需要进行季节性调整。
在这里了解更多
https://machinelearning.org.cn/remove-trends-seasonality-difference-transform-python/
亲爱的 Jason,非常感谢您的教程。如果我进行长期预测(例如,200 步),预测器的性能会下降,这是正常的吗?特别是,我观察到预测会收敛到一个特定的值。我该如何进行长期的样本外预测?
是的,预测的未来越远,性能越差。预测未来非常困难。
嗨 Jason,非常感谢您的帖子。
我使用 Augmented Dickey-Fuller 方法测试了提供数据集的平稳性,结果如下:
Test Statistic -4.445747
p-value 0.000246
#Lags Used 20.000000
Number of Observation Used 3629.000000
Critical Value (1%) -3.432153
Critical Value (5%) -2.862337
Critical Value (10%) -2.567194
结果表明数据看起来是平稳的。所以我的问题是:
1. 即使数据是平稳的,为什么您还要应用季节性差分?
2. 您对数据进行了季节性差分,并且 ARIMA 模型的参数 d 仍然是 0(ARIMA 模型 7 0 1)。当对实际数据进行差分时,难道不需要将 d 设为 > 0(差分次数)吗?
移除季节性后,问题更容易建模。
d 参数旨在抵消任何趋势,没有趋势,因此 d 可以保持为零。
你好,这太棒了。
我有一个关于多日样本外一步预测的小问题。例如,我需要预测 1990-12-25 到 1990-12-31 的数据,并且我想为每一天都使用一步预测。我该如何使用 api predict 或 forecast 来实现?谢谢。
我相信教程中的示例就是这样做的。也许我不理解你的问题?
嗯,感谢您的回复。
让我们来谈谈需要预测的7天数据,从1990-12-25到1990-12-31。在您的教程中,您使用 forecast(period=7) 函数一次性获得预测。但我只想使用 forecast(period=1) 函数7次来进行预测。对于 forecast(period=7),新的预测数据会影响到下一个要预测的数据(例如,预测数据1990-12-25会影响到1990-12-26的数据)。对于 forecast(period=1),每一个预测数据都受到真实数据的影响。也就是说,在预测1990-12-26时,真实数据1990-12-25会被加入模型,而不是像forecast(period=7)那样使用预测数据1990-12-25。我的问题是如何使用statsmodels来编程实现动态数据更新。
请原谅我拙劣的表达。
啊,我明白了,谢谢。
我假设在每次预测后都会提供实际观测值,以便它们可以作为输入。
最简单的答案是使用新观测值重新拟合模型并进行一步预测。
更复杂的答案是研究 API/代码并找出如何提供动态输入,我目前无法确定 statsmodel API 是否支持这种用法。
另外,这可能对后者有帮助
https://machinelearning.org.cn/make-manual-predictions-arima-models-python/
再次感谢您的回复。
我一直在研究您提到的第一种方法。这是符合我需求的正确方法。但它的时间花费非常高。我在股票指数数据(例如 DJI.NYSE)上进行了测试,数据量超过 3000 条。ARIMA 方法很难进行良好的回归。也许股票数据无法预测。
股市是无法预测的。
https://machinelearning.org.cn/faq/single-faq/can-you-help-me-with-machine-learning-for-finance-or-the-stock-market
嘿,我在这里导入 series 时出错,但错误来自 csv 文件方面。
请注意,一些默认参数不同,因此在更改函数调用时,请参考文档中的 from_csv。
infer_datetime_format=infer_datetime_format)
回溯(最近一次调用)
File “sarima.py”, line 10, in
series = Series.from_csv(‘/home/techkopra/Documents/Sarima_machine-learnig/daily-minimum-temperatures1.csv’, header=None)
File “/home/techkopra/Documents/Sarima_machine-learnig/env/lib/python3.6/site-packages/pandas/core/series.py”, line 3728, in from_csv
result = df.iloc[:, 0]
File “/home/techkopra/Documents/Sarima_machine-learnig/env/lib/python3.6/site-packages/pandas/core/indexing.py”, line 1472, in __getitem__
return self._getitem_tuple(key)
File “/home/techkopra/Documents/Sarima_machine-learnig/env/lib/python3.6/site-packages/pandas/core/indexing.py”, line 2013, in _getitem_tuple
self._has_valid_tuple(tup)
File “/home/techkopra/Documents/Sarima_machine-learnig/env/lib/python3.6/site-packages/pandas/core/indexing.py”, line 222, in _has_valid_tuple
self._validate_key(k, i)
File “/home/techkopra/Documents/Sarima_machine-learnig/env/lib/python3.6/site-packages/pandas/core/indexing.py”, line 1957, in _validate_key
self._validate_integer(key, axis)
File “/home/techkopra/Documents/Sarima_machine-learnig/env/lib/python3.6/site-packages/pandas/core/indexing.py”, line 2009, in _validate_integer
raise IndexError(“single positional indexer is out-of-bounds”)
IndexError: single positional indexer is out-of-bounds
您能支持我解决这个错误吗?
谢谢
我在这里有一些建议
https://machinelearning.org.cn/faq/single-faq/why-does-the-code-in-the-tutorial-not-work-for-me
嗨,伙计,
我遇到了这个问题
回溯(最近一次调用)
File “hello.py”, line 23, in
differenced = difference(X, days_in_year)
File “hello.py”, line 10, in difference
value = dataset[i] – dataset[i – interval]
TypeError: unsupported operand type(s) for -: ‘str’ and ‘str’
谢谢
您使用的是 Python 3 吗?
是的。
这个项目是在 python 2 环境下运行的吗?
我使用 Python 3.6。
我预计它应该可以在 Python 2.7 中使用。
为什么需要使数据平稳?当您获取前一年同一天的每日观测值时,这是否会影响数据以及结果?
这大大简化了预测问题,并符合线性模型的期望。
尝试使用/不使用,并比较结果!
我使用了您的代码来预测未来365天。但是,在逆差分之前,预测值从第96步开始收敛到0.0131662。这意味着逆差分后的预测值几乎等于去年的值+0.0131662。这几乎相当于没有预测。在实际操作中,人们如何进行更长时间的未来预测?
这是很多天的预测!
根据我的经验,在大多数问题中,预测超过十几步的未来会导致过多的误差,使其无法使用——当然,这取决于数据集。
那么,人们在生产环境中通常如何使用 ARIMA 模型?他们只用它来预测未来几个数据点?每当有新数据点出现时,他们会使用它们来更新未来预测吗?例如,假设今天是 2 月 1 日。我使用截至 2 月 1 日的历史数据来预测 2 月 2 日至 2 月 10 日。一旦 2 月 2 日的数据出现,我就会将 2 月 2 日的数据纳入历史数据中,以预测/更新 2 月 3 日至 2 月 10 日以及 2 月 11 日的预测。这是在部署中使用 ARIMA 的正确流程吗?
这可能是有用的,这实际上取决于您的生产环境。
例如,在某些情况下,系数可能被直接用于进行预测,例如使用另一种语言。在其他环境中,模型可能可以直接使用。
此外,在更新模型时,我建议测试不同的计划,看看哪种对您的特定数据最有效。
嗨,您如何同时处理多个时间序列?例如,df 有 50 列左右。
也许每个时间序列一个模型。
或者使用能够支持多个输入变量的方法,例如神经网络。
https://machinelearning.org.cn/start-here/#deep_learning_time_series
Jason,您好!这个教程真的太棒了……
您能帮我绘制图形来比较预测值和实际值,并计算 RMSE 分数吗?
您可以在这里开始学习绘图:
https://machinelearning.org.cn/load-explore-time-series-data-python/
先生,
您的博客非常有帮助。与其他博客相比,我只有在阅读您的博客时才感觉理解更深入。非常感谢。
我还有一个疑问。ARIMA 模型可以检测异常值吗?
谢谢。
不,ARIMA 并不真正适合异常值检测。
“不,ARIMA 并不真正适合异常值检测。” 您能推荐一些适合时间序列异常值检测的方法吗?
我希望将来能非常详细地涵盖这个主题。
也许可以考虑将这个问题作为不平衡分类任务来研究?
我的数据是月度数据,但有些月份的信息缺失了,我能用 ARIMA 处理这类数据吗?
您可以用均值/中位数来填充缺失值。
但如果我的数据有很强的季节性呢?
那么前一个周期的相同时间点的值会更好。
你好,
如果我使用了以下函数进行预测,我该如何进行未来预测?
for timepoint in range(len(TestData))
ActualValue = TestData[timepoint]
#forcast value
Prediction = StartARIMAForecasting(Actual, 1,1,1)
print(‘Actual=%f, Predicted=%f’ % (ActualValue, Prediction))
#add it in the list
Predictions.append(Prediction)
Actual.append(ActualValue)
非常感谢!
您可以按照帖子中的说明使用 model.predict() 或 model.forecast()。
你好,
请告诉我为什么它不能正常工作
a=[1,2,3,4,1,2,3,4]
da = difference(a)
X=a
forecast=da
forecast
[1, 1, 1, -3, 1, 1, 1]
days_in_year=4
history = [x for x in X]
day = 1
for yhat in forecast
inverted = inverse_difference(history, yhat, days_in_year)
print(‘Day %d: %f’ % (day, inverted))
history.append(inverted)
day += 1
history
Day 1: 2.000000
Day 2: 3.000000
Day 3: 4.000000
Day 4: 1.000000
Day 5: 3.000000
Day 6: 4.000000
Day 7: 5.000000
为什么第五天不正确?
我在这里有一些建议
https://machinelearning.org.cn/faq/single-faq/can-you-read-review-or-debug-my-code
你好,
如何计算 RMSE 和其他性能指标?
谢谢你
您可以使用 sklearn metrics 来计算预测数组和预期值数组之间的误差。
https://scikit-learn.cn/stable/modules/classes.html#sklearn-metrics-metrics
嗨,Jason,
您的博客非常有帮助。我通过设置训练和测试数据的比例(例如 90:10, 80:20, 70:30…)来应用 ARIMA 进行预测。我以为随着训练数据的增加,RMSE 值会减小。但当我预测了 5 年的数据时,我得到了以下结果:
Ratio MSE RMSE
90-10 116.18 10.779
80-20 124.336 11.151
70-30 124.004 11.136
60-40 126.268 11.237
50-50 127.793 11.305
40-60 137.029 11.706
30-70 133.29 11.545
所以,我现在很困惑。RMSE 应该随着训练集增加而减小,还是 RMSE 是变化的?如果变化,您能告诉我变化的可能原因吗?
谢谢你
报告的误差分数的变化取决于用于训练模型的数据和正在预测的时间间隔。
最好使用前向验证来总结模型的性能,并在一个大的时间间隔上进行。
您好,感谢您的博客,但我需要支持。当我运行代码时
def difference(dataset, interval=1)
diff =list()
for i in range(interval, len(dataset))
value = dataset[i]-dataset[i-interval]
diff.append(value)
return numpy.array(diff)
df = pd.read_csv(‘dataset.csv’,header=None)
X = df.values
day_in_year = 365
differenced = difference(X,day_in_year)
model =ARIMA(differenced,order=(7,0,1))
model_fit=model.fit(disp=0)
print(model_fit.summary())
和
TypeError Traceback (most recent call last)
in
9 X = df.values
10 day_in_year = 365
--> 11 differenced = difference(X,day_in_year)
12
13 model =ARIMA(differenced,order=(7,0,1))
在 difference(dataset, interval) 中
2 diff =list()
3 for i in range(interval, len(dataset))
--> 4 value = dataset[i]-dataset[i-interval]
5 diff.append(value)
6 return numpy.array(diff)
TypeError: unsupported operand type(s) for -: ‘str’ and ‘str’
我不知道这是什么意思。我在 python3 中运行它,你能帮我吗?谢谢
很抱歉听到这个消息,我在这里有一些建议。
https://machinelearning.org.cn/faq/single-faq/why-does-the-code-in-the-tutorial-not-work-for-me
请问我想将此代码应用于时间序列数据,但我想构建一个滑动窗口模型,该模型读取前五个值并预测第六个值,然后滑动到下一个,我应该更改什么才能构建此模型?
您可以将阶数更改为类似 (5,1,0) 的值,并使用 forecast() 函数,将步数设置为 6。
嗨,Jason!
我想进行样本外预测。但是,根据我在您的教程和网上其他帖子中看到的内容,大多数预测似乎更像是对他们已有的数据的验证。
例如,我有 1950-2019 年的年度人口数据。
我将数据分为训练数据(1950-1998 年)和测试数据(1998 年至今 2019 年)。
当然,我首先使用样本数据创建模型,然后使用测试数据进行验证。但是,我如何预测 2019 年之后的人口年度数量呢?
非常感谢!
好问题。
使用所有可用数据拟合模型以创建最终模型。然后通过调用 forecast() 或 predict() 来使用最终模型进行您希望预测的时间间隔。
非常感谢您的及时回复!
另一个问题。我实际上在使用 Python 中的 auto_arima。但是,我对 predict 函数在 auto_arima 中的工作方式感到有些困惑。与 ARIMA 中的 predict 不同,它没有 start 或 end 参数。据我所知,参数是 n_periods。如果是这样,算法该如何知道您是在进行样本内预测还是样本外预测?
这是我在代码中的用法。
test 是测试数据,而 train 是训练数据。
newforecast basically is the predicted value for the test data. However, I would like to do a out-sample prediction instead.
import pmdarima as pm
for ctry in seadict.keys()
dataa = seadict[ctry]
slicing = int(len(dataa)*0.7)
train = dataa[0:slicing]
test=dataa[slicing:len(dataa)]
mod = pm.auto_arima(train, error_action=’ignore’, suppress_warnings = True)
mod.fit(train)
forecast = mod.predict(n_periods=len(test))
newforecast = pd.Series(forecast, index=test.index)
抱歉,我对那个库不太熟悉。
我这里有我自己的实现,也许会有帮助。
https://machinelearning.org.cn/how-to-grid-search-sarima-model-hyperparameters-for-time-series-forecasting-in-python/
您好,如何安装数据集?
链接只是在网页上显示了数据。
将数据集下载为 .csv 文件,并将其放在与您的 .py Python 文件相同的目录中。
我有一个月度时间序列,但缺少某些月份的数据。我想用 ARIMA 模型填充这些值,但当我尝试使用 “start=missing_date end=missing_date” 来指定其中一个缺失日期时,我总是从 “predict” 方法收到错误。当我尝试使用 “exog = [ missing_date ]” 进行 “predict” 时,没有错误,但我得到的是用于拟合 ARIMA 模型的原始时间序列(带有间隙)。我开始怀疑 ARIMA 是否无法进行 “插值”;这是正确的吗?
用 ARIMA 填充缺失值很困难,您可能需要拟合一个在每个间隙之前的模型,然后预测该间隙。
也可以试试 forecast() 函数,它更简单。
difference 函数进行的是当前值与前一天的值之间的差,而不是与前一年的值之间的差。您在帖子中将其描述为“年”。希望我说的对。
看看我们是如何调用该函数的,以及如何传入 365 的。
你好,
感谢您的教程。它们非常棒。
我需要进行以下更改才能使代码正常工作。请注意,我不得不在第 5 行和最后一行使用索引 [1]。我是否做错了什么?
如果您能指出我的错误,我将不胜感激。我使用的是 Anaconda 3.5。
# 创建差分序列
def difference(dataset, interval=1)
diff = list()
for i in range(interval, len(dataset))
value = dataset[i][1] – dataset[i – interval][1]
diff.append(value)
return numpy.array(diff)
# 反转差分值
def inverse_difference(history, yhat, interval=1)
return yhat + history[-interval][1]
不客气,感谢您的好评!
很遗憾听到这个消息,也许可以确认您使用的是 Python 3.6+,并且您复制了所有代码和数据,完全一样。
这也许会有帮助。
https://machinelearning.org.cn/faq/single-faq/why-does-the-code-in-the-tutorial-not-work-for-me
我认为我知道问题所在了。问题出在读取语句中。我正在尝试找出正确读取的方法。
太棒了!
一个很棒但简洁的教程,Jason Brownlee 博士!
我有一个基本问题,我仍然没有得到答案:arima.model.ARIMAResults.forecast() 的输出包含哪些组件?
根据其文档,输出是“样本外预测数组。一个 (steps x k_endog) 数组。” 我确定 endog 表示用作历史进行训练的输入数组,而 steps 是指定的整数参数。我不确定 k_endog 是什么意思。
您能告诉我们吗?
谢谢
谢谢!
我相信是每个点预测的预测区间和置信区间。
编译代码时,会出现此错误。
File “C:/Users/D.T/.spyder-py3/untitled1.py”, line 9, in difference
value = dataset[i] – dataset[i – interval]
TypeError: unsupported operand type(s) for -: ‘str’ and ‘str’
请帮助!
很抱歉听到这个消息,这可能会有帮助
https://machinelearning.org.cn/faq/single-faq/why-does-the-code-in-the-tutorial-not-work-for-me
The
end
argument could not be matched to a location related to the index of the data.’这是我使用时得到的结果
pred = res.predict(start = ‘2014-11-05’, end = ‘2019-02-01’)
当我们的索引是日期时,如何进行样本外预测?
抱歉,我手头上没有现成的例子。
嗨,Jason,
首先,非常感谢您的有用博客!
我在这方面有一个疑问:https://machinelearning.org.cn/make-sample-forecasts-arima-python/
您使用了 predict 函数来进行样本外预测。
但是当我尝试时:
1) 我只能使用数字而不是日期作为 start 和 end 索引来运行 predict 函数。
2) 如果我给出的数字小于 len(series)(在本例中为 differenced),我能得到训练数据子集的预测吗?也就是说,我可以像在线性回归中那样轻松地比较实际值/预测值吗?
因为在所有地方,您都讨论了样本外预测,而不是样本内预测。
谢谢,
Abhay
抱歉,我没有关于使用日期进行预测的示例。
您可以预测训练集,但最好使用前向验证来评估模型。
https://machinelearning.org.cn/backtest-machine-learning-models-time-series-forecasting/
我只有一年中四个月的每日数据,并且我想预测未来几年的销售情况。我该如何做?因为从差值来看,您是将与上一年同期的数据进行比较,而我没有这些数据。我该如何用有限的数据进行预测?
在可用数据上拟合模型并调用 model.predict()。
也许我没有完全理解您遇到的问题?
Jason 您好,我正在使用 Python 3.7.4
但是仍然存在问题
TypeError Traceback (most recent call last)
in
16 X = series.values
17 days_in_year = 365
--> 18 differenced = difference(X, days_in_year)
19 # fit model
20 model = ARIMA(differenced, order=(7,0,1))
在 difference(dataset, interval) 中
7 diff = list()
8 for i in range(interval, len(dataset))
--> 9 value = dataset[i] – dataset[i – interval]
10 diff.append(value)
11 return numpy.array(diff)
TypeError: unsupported operand type(s) for -: ‘str’ and ‘str’
您的教程对我帮助很大,我通过关注您的网站和电子邮件时事通讯开始了我的机器学习之旅。
请帮我解决这个问题,我已经尝试了所有方法。
很抱歉听到这个消息,这可能会有所帮助。
https://machinelearning.org.cn/faq/single-faq/why-does-the-code-in-the-tutorial-not-work-for-me
RNN 中是否可以使用相同的功能?
如果您有帖子,请分享。
是的,您可以从这里开始。
https://machinelearning.org.cn/start-here/#deep_learning_time_series
你好~ 这篇文章对我帮助很大。
但是我有一个关于 arma 模型的问题。
我知道 arma 模型是一个线性模型,当我使用 fit() 函数训练模型时,我得到了参数,如何使用学习到的参数来预测另一个时间序列的未来值?
您可以为每个时间序列拟合一个单独的模型。
你好,
我理解您定义了差分和逆差分函数,因为您可能需要那些来验证序列的平稳性,但您为什么不使用模型的差分特性呢?我的意思是,这难道不更容易吗?而不是手动进行预测的逆差分。
那会更容易。我不记得为什么了。
尊敬的 Brownlee 先生,
非常感谢您的示例和解释!非常有帮助!
您应用了 statsmodel 函数 ARIMA,参数为 (p=7,d=0,q=1)。将滞后参数设置为 d=0 实际上使 ARIMA 模型变成了一个 ARMA 模型:请参见 https://statsmodels.cn/dev/_modules/statsmodels/tsa/arima_model.html#ARIMA。
另一方面,您通过您的 difference 函数手动生成了一个平稳时间序列。如果我理解正确,这使得整个示例又变成了 ARIMA。
您为什么不使用 ARIMA 内置的生成离散差的功能呢?
如果我理解正确,这是通过 statmodel arima 类中的以下行完成的:self.endog = np.diff(self.endog, n=d)。您的 “difference” 函数(我认为它做了同样的事情)有什么优势?
诚挚的问候,
Wolfgang
是的,直接使用 ARIMA 更好。
我试图将数据预处理的重要性灌输给人们。
谢谢,这让我明白了。抱歉拼写错误,Brownlee 先生。
诚挚的问候,
Wolfgang
不客气。
您是否发现您的差分预测值(model_fit.forcast())几乎为 0,所以您的最终预测结果只是 360 天(或一年)前的值?
我不记得了,抱歉。也许您自己探索一下?
Jason 您好。我正在处理一个时间序列问题。我的模型预测的是一条直线,这与 test_data 非常不同。
所以,起初,我使用 “加法” 方法分解了序列(肉眼可以看到没有季节性),正如预期的那样,季节性为零,同时 “残差” 的值也为零。
我使用 ARIMA 对序列进行了建模。“model_fit.resid” 是 “白噪声”,我通过 ACF 图、均值和方差值进一步验证了这一点。
但我的模型仍然预测的是一条直线,这与 test_data 非常不同。您能帮帮我吗。
也许可以尝试替代模型或模型配置?
也许在模型之前测试不同的数据预处理方法?
也许您的问题是不可预测的?
代码的这一部分正在引发错误,但它在您使用我的数据集时创建了 dataset.csv 和 validation.csv。
# 加载数据集
series = read_csv(‘dataset.csv’, header=None)
# 季节性差分
X = series.values
days_in_year = 365
differenced = difference(X, days_in_year)
# 拟合模型
model = ARIMA(differenced, order=(7,0,1))
错误,作为
18 differenced = difference(X, days_in_year)
19 # fit model
—> 20 model = ARIMA(differenced, order=(7,0,1))
21 model_fit = model.fit(disp=0)
22 # print summary of fit model
ValueError: Insufficient degrees of freedom to estimate
您可能需要更改模型的配置以更好地匹配您的数据。
在此示例中,您对数据集中已有的数据进行了预测,即从12月25日起,它就在数据集中……如何预测未来几天??
您可以通过调用model.predict()或model.forecast()来预测您想要的任何内容。
我很高兴知道有像您这样的人在帮助大家。您真是我的榜样,先生。
我现在需要您的帮助,我正在进行多步 ARIMA 预测,但它也是滚动预测。我的意思是我想预测未来7天,但不是一次,而是对我的30个验证集进行预测。您有什么教程可以帮助我吗?
是的,我有很多关于使用前向验证的教程,也许可以从这里开始
https://machinelearning.org.cn/arima-for-time-series-forecasting-with-python/
我想写一个应用程序来预测。但我仍然不知道模型的输出是什么
上面的教程没有帮助吗?
输出是 start_index 和 end index。我认为这是正确的。非常感谢
我有一个关于 inverse_difference() 的问题。这段代码:yhat + history[-interval] 会将 yhat 添加到 1990.12.25 的值到 1989.12.24 的真实值,因为 history 序列的最后一个条目是 1990.12.24。我们难道不应该将差值 yhat 加回到一年前的真实值,即 1989.12.25 吗?
差分可能会令人困惑,也许这会有所帮助
https://machinelearning.org.cn/difference-time-series-dataset-python/
谢谢你,Jason。在我提问之前,我注意到评论中有一些人遇到了这个错误:“TypeError: unsupported operand type(s) for -: ‘str’ and ‘str’”。一个快速的修复方法(可能还有其他方法)是,从任何引用 dataset.csv 头的代码(例如,series = read_csv(‘dataset.csv’, header=None))中,只需删除“, header = None”,它们就可以正常工作了。我不确定现在与您最初编写此代码时有什么不同?
至于我的问题,如果我想预测到未来某一年,比如 1,1,2030,无论是单步还是多步预测或预测?Dataset.csv 已删除日期。我不确定这会如何运作?祝好 Alex
谢谢提示。
如果您知道最后一个已知观测值的日期,并对所有数据进行模型拟合,那么您可以计算达到所需日期的步数,并使用 predict() 或 forecast() 函数。
你好 Jason,
感谢以上教程!
我也收到了同样的错误。我检查了我的数据,数据没有问题。
起初我收到 TypeError: unsupported operand type(s) for -: ‘str’ and ‘str’
当我将代码从
value =dataset[i] -dataset[i – interval]
推广到
value =int(dataset[i]) -int(dataset[i – interval])
我得以解决了上述错误。
在此之后,我收到了以下错误
TypeError: only size-1 arrays can be converted to Python scalars
不确定如何解决上述错误。请帮帮我。
Python Version 3.7.6
很抱歉听到这个消息,我无法立刻说出您的故障原因。这可能有所帮助
https://machinelearning.org.cn/faq/single-faq/why-does-the-code-in-the-tutorial-not-work-for-me
我也想在手动 ARIMA 预测模型中进行多步样本外预测。你能告诉我怎么做吗,因为我不知道。请回答我的问题
调用 forecast() 并指定要预测的步数。
嘿 Jason,感谢您的这篇文章。
1. 我们如何解释 ARIMA 摘要?除了 p 值和回归系数之外?
2. 另外,对于上面的代码,我创建了多个回溯7天窗口作为验证数据集。观察到了不同的 RMSE。我如何确定模型的拟合优度?
3. 另外,如果我们想知道 ARIMA 的参数,我们需要查看原始序列而不是差分序列的 ‘acf’ 和 ‘pacf’ 图,对吗?
谢谢!!
抱歉,我没有关于解释摘要的教程,也许可以查看文档。
您可以通过计算保留数据上的误差度量来评估模型的技能。拟合优度具有技术含义,可以通过预测值和预期值之间的 R^2 度量来计算。
您可以使用 ACF/PACF 图或网格搜索来估计 ARIMA 模型的配置。后者通常更有效。
嗨,Jason,
感谢您的综合教程,我想知道您是否有什么想法可以添加新的实际值作为时间窗口滚动前进,而无需重新拟合 ARIMA 模型
假设我拟合了一个 ARIMA 模型(Model_100),从第 1 周到第 100 周,我认为这是一个很好的模型,我不想重新拟合。如何将第 101-109 周的实际值输入到第 110 周的预测中,而无需重新拟合?
https://stackoverflow.com/questions/56335992/how-to-perform-multi-step-out-of-time-forecast-which-does-not-involve-refitting
我暂时不确定。
也许可以查看 API?
也许可以深入研究代码,看看是否有直接的方法?
也许可以编写一个具有此支持的备用库?
也许可以使用备用模型类型?
也许可以编写自定义实现?
你好,
当我运行代码行“from statsmodels.tsa.arima_model import ARIMA”时
我收到错误:ModuleNotFoundError: No module named ‘statsmodels.tools.sm_exceptions’
您能提供建议吗?
谢谢
听到这个消息我很难过。
您安装了哪个版本的 statsmodels?
版本 0.12.0,看起来是最新版本
谢谢,我找到了问题并更新了代码。
你好 Jason,
感谢您的内容。非常有用。目前我正在尝试使用 ARIMA 模型进行单变量预测。主要是每周五天(周一至周五)的数据。有时,如果该周有公共假期,商店会关闭,公共假期的销售额为零。如何在 ARIMA 模型中表示这些公共假期?在测试数据中,如果有一个公共假期,模型在预测时会如何考虑?请告诉我您的评论。
致敬
Solomon
也许可以将其作为节假日或非节假日的外部二元变量。
嗨 Jason,感谢您的教程,非常有帮助。我有一些问题。
首先,一旦我拟合了模型并对其进行了测试,如果我想预测模型使用的数据(即测试数据之后)之后的几天(例如 1991/1/1)该怎么办?
此外,我看到在另一个教程中您使用了 ARIMA(5,1,0)。在这种情况下,您使用了 ARIMA(7,0,1),但您包含了天差,而不是在第一种情况下将积分项设置为 1。这个选择的意义是什么?
谢谢!
上面的示例准确地展示了如何预测训练集之外的数据。调用 predict() 或 forecast() 并指定索引或日期。
本教程中的模型配置/性能是任意的,重点在于如何进行样本外预测。
我建议您配置模型以获得最佳性能。
嘿,Jason。
我想知道,你为什么要做这个预测
forecast = model_fit.forecast(steps=7)[0]
你为什么加 [0]?这不只会得到预测值列表中的第一个数字吗?如果你要绘制它,难道你不想要整个列表吗?
forecast() 以前返回预测值和置信区间,而 [0] 需要仅访问预测值。API 最近已更改。
我可能需要更新示例。
更新:好的,我已经修复了样本外代码示例。
嗨 Jason。感谢您的出色教程。我想知道是否可以使用差分参数而不是定义差分及其逆函数?是否可以只向模型提供 d 参数,而不是为差分定义函数?
不客气。
是的,您可以使用 ARIMA 的 d 参数进行差分,而不是手动差分。
感谢您的精彩详细教程
我们知道如何使用测试数据验证我们的预测。首先,我们进行了训练,然后验证了我们的预测。
我有一个关于能否预测测试数据/验证数据之外的第二天的温度的问题?
我们可以训练 – 测试 – 然后预测吗?
我非常感谢您提供的答案,它可能会帮助我完成作业
不客气!
您可以,但这很奇怪。通常,您会评估您的模型/配置,选择一个最终模型和配置,然后使用它开始进行预测。
感谢您的教程。但是在使用 MRIAR 模型时遇到了问题。我使用了 predict() 函数。如下所示
split_point = len(df_diff)-7
df_train = df_diff[:split_point]
df_test = df_diff[split_point:]
model = ARIMA(df_train, order=(1,0,1))
arima_result = model.fit()
pred_vals = arima_result.predict(start=’2021-02-15′)
我想用训练数据集训练 ARIMA,然后预测测试数据。但是,出现了一些错误,“The
start
argument could not be matched to a location related to the index of the data.” 确实,时间索引 2021-02-15 是测试数据集中的第一个数据。为什么我不能预测训练样本外的数据?我不知道 predict() 函数最近是否改变了?谢谢!
也许可以尝试使用数组索引而不是日期?
谢谢!我尝试使用索引,它有效!
干得好!
你好,教授。我做了一个关于 forecast 和 predict 这两个函数的实验。但是,我被一些有趣的结果弄糊涂了。如下
准确地说,我首先使用 prediction 函数对最后 5 个数据进行样本内测试,并将参数 dynamic == true 设置为这里,因为我知道 forecast 函数的预测值将被添加到下一个预测中,对吧?
然后我从训练数据集中删除了最后 5 个数据,现在使用 forecast 函数进行样本外测试来预测它们。
但是结果两次尝试都不一样。我不知道为什么?您能帮帮我吗?非常感谢!
我暂时不确定,也许可以仔细检查代码?仔细检查 API 文档?用一个简单的构造数据集进行实验?
谢谢!我尝试使用您的数据和代码重试此实验。我发现我得到的结果与您在网站上发布的结果不符,我使用的是 0.12 版本包。我猜最近有一些更新。无论如何,感谢您的教程,它帮助了我很多!我会继续关注您的博客🙂
是的,我们可以预料到会有小的差异,请看这里
https://machinelearning.org.cn/faq/single-faq/why-do-i-get-different-results-each-time-i-run-the-code
如果我们要在 ARIMAX、SARIMAX 和 VARMAX 模型中使用外生变量,如何预测未来值以及我们如何知道未来的外生变量?我不知道如何预测我的模型是用内生和外生变量训练的未来时期。
这里的示例可能有所帮助
https://machinelearning.org.cn/time-series-forecasting-methods-in-python-cheat-sheet/
from statsmodels.tsa.statespace.varmax import VARMAX
from random import random
# contrived dataset with dependency
data = list()
for i in range(100)
v1 = random()
v2 = v1 + random()
row = [v1, v2]
data.append(row)
data_exog = [x + random() for x in range(100)]
# 拟合模型
model = VARMAX(data, exog=data_exog, order=(1, 1))
model_fit = model.fit(disp=False)
# 进行预测
data_exog2 = [[100]]
yhat = model_fit.forecast(exog=data_exog2)
print(yhat)
这里您正在预测,并且有 exog 数据,但在未来时期,例如,如果我想预测接下来的 12 个月,我怎么知道未来的 exog 变量。没有 exog 变量,forecast 函数就无法工作。对于这种情况,如何处理。
该示例假设您知道预测区间的外生变量的值。
我想,如果数据不可用,那么也许该模型不适合您的问题?例如,预测是以预测时不可用的数据为条件的。
解决 TypeError: unsupported operand type(s) for -: ‘str’ and ‘str’
使用 >>> differenced = difference(X[:,1], days_in_year)
或直接 difference(series.Temp, days_in_year)
顺便说一下,如果让 ARIMA 进行差分
>>> model = ARIMA(series.Temp, order=(7,1,1))
很抱歉听到这个消息,也许这些提示会有帮助。
https://machinelearning.org.cn/faq/single-faq/why-does-the-code-in-the-tutorial-not-work-for-me
在使用外生变量时,如何预测未来 12 个月的数据。
也许这会有帮助。
https://machinelearning.org.cn/time-series-forecasting-methods-in-python-cheat-sheet/
嗨,我从模型拟合摘要中看到,几个滞后项,如 ar.L4、ar.L5 等,其 p 值大于 0.05,这是否意味着它们在统计上不显著,或者即使其中一些大于 0.05,也可以继续将其视为一个好的模型?
VAR 模型是否也适用?
好问题,说实话,我不分析模型,只分析模型性能。
嗨,Jason,
我的数据集是从 2016 年 1 月 1 日到 2018 年 12 月 31 日。我使用了 MLP 并训练了模型。那么,我可以使用“ model_fit.forecast (steps=7) ”来预测下一个 7 天(2019 年 1 月 7 日)吗?
谢谢你。
我不这么认为。model_fit.forecast(steps=7) 语法来自 statsmodels,您的 MLP 模型可能无法接受。
嗨,Jason,
非常感谢您的博客,但更重要的是感谢您回答所有回复,我认为有时回复和博客本身一样有信息量。
我只有两个相关的小问题。
首先,在使用 model_fit.forecast(steps=7) 时,模型是使用步骤 1 到 6 的预测值来预测步骤 7 吗?还是它只使用可用的真实数据来预测所有 7 个步骤?
第二个问题与第一个相关。我过去三年的每日销售数据,目标是预测下个月的销售额。我知道这没有确切的答案,但您认为将我的每日数据转换为每月数据,对这些每月数据拟合模型然后预测 1 个未来步骤,会比使用每日数据预测 30 个未来步骤产生更好的结果吗?
我问的原因是我觉得将每日数据转换为每月数据会丢失一些信息,尤其是因为数据具有每周季节性(不知道这是否会产生影响,因为我需要下个月的数据)
这两个问题是相关的,因为我觉得预测未来 30 天的销售额在最后几天会产生较差的结果,尤其是当模型使用 20 个“预测”值来预测第 21 天时。
非常感谢您的帮助。
您需要参考 ARIMA 方程。您应该会看到 ARIMA 是确定性的,但它依赖于之前的步骤。在这种情况下,它会预测第 1 步,然后将其用于第 2 步,依此类推。它在一定程度上依赖于所有步骤的真实数据,但预测值也涉及其中。
对于您第二个问题:是的。因为通过将每日数据汇总为每月数据,您通过平均化来减少了噪声。
谢谢,但你不是 Jason 吗?
我是 Adrian。协助 Jason 管理这个博客。
谢谢!
嗨,Jason,
非常感谢您的博客,都很欣赏。也感谢您回复所有回复。
我只有两个相关的问题。
首先,当调用 model_fit.forecast(steps=7) 时,模型是直接使用可用数据来预测接下来的 7 个步骤吗?还是它也会在预测第 7 步时重用步骤 1 到 6 的预测值?
问题是,我过去三年的每日销售数据,目标是预测下个月的销售额。我不确定处理这种情况的最佳方法是将每日销售数据转换为每月数据并预测 1 步,还是将数据保留为每日数据并预测 30 步。我问的原因是,我觉得在将数据集转换为每月时会丢失一些信息(尤其是在数据中存在每周季节性时)。您怎么看?
再次感谢您!
它会预测第 1 步到第 7 步,并且由于 ARIMA 模型的性质,它会重用预测值来进行后续的步骤。
将每日数据汇总为每月数据可能会丢失一些信息。但您也可能减少信号中的噪声影响。这就是为什么您应该尝试不同的设置以查看哪种效果最好。
对于收到以下错误的人
TypeError: unsupported operand type(s) for -: ‘str’ and ‘str’
确保您运行的代码部分是将 daily-minimum-temperatures.csv 文件拆分为 dataset.csv 和 validation.csv。
使用 ARIMA 的绝佳示例。非常感谢 Jason。我可以知道使用 p = 7 和 q = 1 的基本原理吗?d = 0 是非常清楚的,因为日期集已经被差分了。非常感谢。
Shuqing,非常欢迎您!以下资源可能对您有帮助
https://stats.stackexchange.com/questions/187735/how-can-i-determine-the-arima-orders-p-d-q-from-this-correlogram
https://pypi.ac.cn/project/pmdarima/
那是因为数据集是数组的数组。您需要改用以下方法,它选择温度进行计算。
def difference(dataset, interval=1)
diff = list()
for i in range(interval, len(dataset))
value = dataset[i][1] – dataset[i – interval][1]
diff.append(value)
return numpy.array(diff)
非常感谢!这使得很容易了解函数如何接收输入。您知道有关于 Matlab regARIMA 函数的“指南”/“比较”吗?我正在尝试将 Matlab 的 ARIMA 模型代码迁移到 Python,其中一些工作可以说是“盲目摸索” 🙂
祝好,
Thomas Hemming
Thomas,您太客气了!以下资源是一个很好的起点
https://machinelearning.org.cn/arima-for-time-series-forecasting-with-python/
您好!我想问一下我遇到的错误,这是我的代码
# 季节性差分
X = df.values
months_in_year = 12
differenced = difference(X, months_in_year)
# 拟合模型
model_diff = ARIMA(differenced, order=(1,0,0))
model_fit_diff = model_diff.fit()
我将“days_in_year”更改为“months_in_year”,因为我使用的是月度数据,而且我的最佳模型实际上是 ARIMA(1,1,0),所以我的阶数应该是 ARIMA(1,0,0),对吧?因为我们已经对数据进行了差分(如果我说错了请纠正我)。问题是我得到了一个错误“all the input arrays must have same number of dimensions, but the array at index 0 has 1 dimension(s) and the array at index 1 has 2 dimension(s)”,并且在我检查数据时,差分只包含一个数组。我在这里遗漏了什么?
提前谢谢!
尊敬的Jason先生,
为带来如此优秀的在线教育系列而喝彩!
一个小小的抱怨,不过……
有大量的广告(大多是零价值的)占据了页面的大部分实际空间。多到我不得不策略性地放置打开的文件,以便能够避开它们。
更重要的是——广告导致页面部分重新加载(这感觉像是延迟滚动)。
谢谢
附注:在您的常见问题解答页面上,我认为有一个部分说明没有广告支持。我读对了吗?