时间序列预测(在 C# 中)

机器算法验证 r 时间序列 预测 有马 C#
2022-03-28 16:49:48

我正在用 C# (WPF) 开发一个应用程序,除此之外,它可以对销售量进行基于时间序列的预测(未来 4-5 个月)。我是一名工业工程师,所以我不是统计学专业,也不是编程专业(两者都有基本知识)。

我现在正在做的是将我的每日数据汇总到每月数据中,然后我测试每月的季节性,然后根据结果进行Holt的指数平滑或Holt-Winters的指数平滑。

为了确定平滑参数,我使用蛮力(即测试许多可能的组合)并保持预测过去一年(回测)的参数具有最小MAE

出现了一个问题:这种方法很慢(显然,一如既往地使用蛮力)。仅在 0.05 间隔内尝试平滑参数大约需要 0.5 秒,但这并不能提供太多的准确性。我需要用 1000 多个项目执行此操作,因此需要超过 8 分钟(太多)。

所以我有几个问题

  • 有没有什么方法可以在不测试所有参数的情况下确定最佳平滑参数?
  • 使用R.NET使用 R 的预测包会更快吗?
  • 如果是这样,我应该:

    • 使用每日或每月数据?
    • 也制作一个auto.arima?如何确定哪种型号更好?
  • 我的回测方法(仅使用该点之前的数据制作模型)是否有效以确定模型是否优于另一个模型?

编辑:我尝试过实现 R.NET。如果我设置使用哪个模型并且只使用 mae,则时间ets约为 0,1sopt.crit(如果没有,它会上升到 5s)。

如果我能得到我在评论中提到的相同的样本外预测,这就足够了。如果不可能,那么我将不得不运行它 12 次,加起来 1.2 秒,这还不够快。

  • 我怎么能在 R 中做到这一点(在不考虑模型的情况下对最后 12 个数据进行预测)?
1个回答

让我们一次一个地回答你的问题:

  • 有没有什么方法可以在不测试所有参数的情况下确定最佳平滑参数?

您可以将问题投射到状态空间框架中,然后使用标准数值库对参数进行数值优化。指数平滑预测 - Hyndman 等人的状态空间方法。将是一个很好的起点。

  • 使用 R.NET 使用 R 的预测包会更快吗?

很难说。我没有使用 R.NET 的经验。例如,直接ets()在包中使用(确实使用状态空间方法)forecast肯定会更快,特别是如果像您那样指定模型而不是让ets()找到(希望)最好的模型。

如果是这样,我应该:

  • 使用每日或每月数据?

这应该真的取决于你想对预测做什么。您真正需要什么样的预测粒度来做出决策?有时,最好先预测更高频率的数据,然后再进行汇总,但通常情况下,我宁愿汇总历史记录并按我计划稍后使用的粒度进行预测。

另外,每日数据可能是间歇性的,在这种情况下,您不能使用 Holt(-Winters) 或 ARIMA,而应该使用 Croston 的方法。这可能会有所帮助。间歇性需求通常更难预测。

编辑:您写道,您需要确定安全量。好吧,现在您实际上需要考虑您的供应链。也许预测根本不是你的问题——如果销售量都是 0 或 1,并且你可以在一天内补充库存,你最好的策略是手头总是有 1 个单位并在每次销售后补充,完全忘记预测。

如果不是这种情况(您写道,您在总体水平上具有季节性),您可能需要做一些临时的事情,因为我认为没有任何季节性间歇性需求。您可以聚合数据以获取季节性预测,然后将其下推到 SKU 级别以获取该级别的预测(例如,通过根据历史比例分配聚合预测),最后通过获取分位数(例如,泊松)获得安全量分配。正如我所说,这是非常临时的,几乎没有统计基础,但它应该让你达到 90% - 鉴于预测是一门不精确的科学,最后 10% 可能无论如何都不可行。

  • 也制作一个auto.arima?如何确定哪种型号更好?

是的,也试试那个。正如您在评论中描述的那样,使用坚持样本来确定哪个模型更好,这是非常好的做法。

还要查看来自不同方法的预测平均值——通常,这样的平均值比成分预测产生更好的预测。编辑:也就是说,同时拟合 Holt-Winters 和auto.arima模型,计算两个模型的预测,然后,对于未来的每个时间段,取两个模型的两个预测的平均值你也可以用更多的模型来做到这一点——如果组件模型“非常不同”,平均似乎效果最好。从本质上讲,您正在减少预测的方差。

  • 我的回测方法(仅使用该点之前的数据制作模型)是否有效以确定模型是否优于另一个模型?

正如我上面写的:是的,是的。这是样本外测试,这确实是评估预测准确性和方法质量的最佳方式。

  • 编辑:我怎么能在 R 中做到这一点(在不考虑模型的情况下对最后 12 个数据进行预测)?

不幸的是,没有办法获取一个ets()拟合的对象并用一个新的数据点更新它(就像在update()拟合的lm()模型中一样)。你需要打ets()十二次电话。

当然,您可以拟合第一个模型,然后重新使用ets()在第一次拟合中选择的模型进行后续改装。该模型在结果components部分中报告ets()例如,以数据集的前五年为例USAccDeaths

fit <- ets(ts(USAccDeaths[1:60],start=c(1973,1),frequency=12))

使用相同型号改装

refit <- ets(ts(USAccDeaths[1:61],start=c(1973,1),frequency=12),
    model=paste(fit$components[1:3],collapse=""))

这将使改装快很多,但当然改装可能不再找到 MSE 最优模型。再说一次,如果只添加一些观察值,MSE 最优模型不应该发生太大变化。

一如既往,我强烈推荐这本免费的在线预测教科书