集成时间序列模型提高预测精度

简介: 使用Catboost从RNN、ARIMA和Prophet模型中提取信号进行预测

集成各种弱学习器可以提高预测精度,但是如果我们的模型已经很强大了,集成学习往往也能够起到锦上添花的作用。流行的机器学习库scikit-learn提供了一个StackingRegressor,可以用于时间序列任务。但是StackingRegressor有一个局限性;它只接受其他scikit-learn模型类和api。所以像ARIMA这样在scikit-learn中不可用的模型,或者来自深度神经网络的模型都无法使用。在这篇文章中,我将展示如何堆叠我们能见到的模型的预测。

我们将用到下面的包:

 pip install --upgrade scalecast
 conda install tensorflow
 conda install shap
 conda install -c conda-forge cmdstanpy
 pip install prophet

数据集

数据集每小时一次,分为训练集(700个观测值)和测试集(48个观测值)。下面代码是读取数据并将其存储在Forecaster对象中:

 importpandasaspd
 importnumpyasnp
 fromscalecast.ForecasterimportForecaster
 fromscalecast.utilimportmetrics
 importmatplotlib.pyplotasplt
 importseabornassns
 
 defread_data(idx='H1', cis=True, metrics= ['smape']):
     info=pd.read_csv(
         'M4-info.csv',
         index_col=0,
         parse_dates=['StartingDate'],
         dayfirst=True,
     )
     train=pd.read_csv(
         f'Hourly-train.csv',
         index_col=0,
     ).loc[idx]
     test=pd.read_csv(
         f'Hourly-test.csv',
         index_col=0,
     ).loc[idx]
     y=train.values
     sd=info.loc[idx,'StartingDate']
     fcst_horizon=info.loc[idx,'Horizon']
     cd=pd.date_range(
         start=sd,
         freq='H',
         periods=len(y),
     )
     f=Forecaster(
         y=y, # observed values
         current_dates=cd, # current dates
         future_dates=fcst_horizon, # forecast length
         test_length=fcst_horizon, # test-set length
         cis=cis, # whether to evaluate intervals for each model
         metrics=metrics, # what metrics to evaluate
     )
     
     returnf, test.values
 
 f, test_set=read_data()
 f# display the Forecaster object

结果是这样的:

模型

在我们开始构建模型之前,我们需要从中生成最简单的预测,naive方法就是向前传播最近24个观测值。

 f.set_estimator('naive')
 f.manual_forecast(seasonal=True)

然后使用ARIMA、LSTM和Prophet作为基准。

ARIMA

Autoregressive Integrated Moving Average 是一种流行而简单的时间序列技术,它利用序列的滞后和误差以线性方式预测其未来。通过EDA,我们确定这个系列是高度季节性的。所以最终选择了应用order (5,1,4) x(1,1,1,24)的季节性ARIMA模型。

 f.set_estimator('arima')
 f.manual_forecast(
     order = (5,1,4),
     seasonal_order = (1,1,1,24),
     call_me = 'manual_arima',
 )

LSTM

如果说ARIMA是时间序列模型中比较简单的一种,那么LSTM就是比较先进的方法之一。它是一种具有许多参数的深度学习技术,其中包括一种在顺序数据中发现长期和短期模式的机制,这在理论上使其成为时间序列的理想选择。这里使用tensorflow建立这个模型

 f.set_estimator('rnn')
 f.manual_forecast(
     lags=48,
     layers_struct=[
         ('LSTM',{'units':100,'activation':'tanh'}),
         ('LSTM',{'units':100,'activation':'tanh'}),
         ('LSTM',{'units':100,'activation':'tanh'}),
     ],
     optimizer='Adam',
     epochs=15,
     plot_loss=True,
     validation_split=0.2,
     call_me='rnn_tanh_activation',
 )
 
 f.manual_forecast(
     lags=48,
     layers_struct=[
         ('LSTM',{'units':100,'activation':'relu'}),
         ('LSTM',{'units':100,'activation':'relu'}),
         ('LSTM',{'units':100,'activation':'relu'}),
     ],
     optimizer='Adam',
     epochs=15,
     plot_loss=True,
     validation_split=0.2,
     call_me='rnn_relu_activation',
 )

Prophet

尽管它非常受欢迎,但有人声称它的准确性并不令人印象深刻,主要是因为它对趋势的推断有时候很不切实际,而且它没有通过自回归建模来考虑局部模式。但是它也有自己的特点。1,它会自动将节日效果应用到模型身上,并且还考虑了几种类型的季节性。可以以用户所需的最低需求来完成这一切,所以我喜欢把它用作信号,而不是最终的预测结果。

 f.set_estimator('prophet')
 f.manual_forecast()

比较结果

现在我们已经为每个模型生成了预测,让我们看看它们在验证集上的表现如何,验证集是我们训练集中的最后48个观察结果。

 results=f.export(determine_best_by='TestSetSMAPE')
 ms=results['model_summaries']
 ms[
     [
         'ModelNickname',
         'TestSetLength',
         'TestSetSMAPE',
         'InSampleSMAPE',
     ]
 ]

每个模型的表现都优于naive方法。ARIMA模型表现最好,百分比误差为4.7%,其次是Prophet模型。让我们看看所有的预测与验证集的关系:

 f.plot(order_by="TestSetSMAPE",ci=True)
 plt.show()

所有这些模型在这个时间序列上的表现都很合理,它们之间没有很大的偏差。下面让我们把它们堆起来!

堆叠模型

每个堆叠模型都需要一个最终估计器,它将过滤其他模型的各种估计,创建一组新的预测。我们将把之前结果与Catboost估计器叠加在一起。Catboost是一个强大的程序,希望它能从每个已经应用的模型中充实出最好的信号。

 f.add_signals(
     f.history.keys(), # add signals from all previously evaluated models
 )
 f.add_ar_terms(48)
 f.set_estimator('catboost')

上面的代码将来自每个评估模型的预测添加到Forecaster对象中。它称这些预测为“信号”。 它们的处理方式与存储在同一对象中的任何其他协变量相同。 这里还添加了最后 48 个系列的滞后作为 Catboost 模型可以用来进行预测的附加回归变量。 现在让我们调用三种 Catboost 模型:一种使用所有可用信号和滞后,一种仅使用信号,一种仅使用滞后。

 f.manual_forecast(
     Xvars='all',
     call_me='catboost_all_reg',
     verbose=False,
 )
 f.manual_forecast(
     Xvars=[xforxinf.get_regressor_names() ifx.startswith('AR')], 
     call_me='catboost_lags_only',
     verbose=False,
 )
 f.manual_forecast(
     Xvars=[xforxinf.get_regressor_names() ifnotx.startswith('AR')], 
     call_me='catboost_signals_only',
     verbose=False,
 )

下面可以比较所有模型的结果。我们将研究两个度量:SMAPE和平均绝对比例误差(MASE)。这是实际M4比赛中使用的两个指标。

 test_results=pd.DataFrame(index=f.history.keys(),columns= ['smape','mase'])
 fork, vinf.history.items():
     test_results.loc[k,['smape','mase']] = [
         metrics.smape(test_set,v['Forecast']),
         metrics.mase(test_set,v['Forecast'],m=24,obs=f.y),
     ]
     
 test_results.sort_values('smape')

可以看到,通过组合来自不同类型模型的信号生成了两个优于其他估计器的估计器:使用所有信号训练的Catboost模型和只使用信号的Catboost模型。这两种方法的样本误差都在2.8%左右。下面是对比图:

 fig, ax=plt.subplots(figsize=(12,6))
 f.plot(
     models= ['catboost_all_reg','catboost_signals_only'],
     ci=True,
     ax=ax
 )
 sns.lineplot(
     x=f.future_dates, 
     y=test_set, 
     ax=ax,
     label='held out actuals',
     color='darkblue',
     alpha=.75,
 )
 plt.show()

哪些信号最重要?

为了完善分析,我们可以使用shapley评分来确定哪些信号是最重要的。Shapley评分被认为是确定给定机器学习模型中输入的预测能力的最先进的方法之一。得分越高,意味着输入在特定模型中越重要。

 f.export_feature_importance('catboost_all_reg')

上面的图只显示了前几个最重要的预测因子,但我们可以从中看出,ARIMA信号是最重要的,其次是序列的第一个滞后,然后是Prophet。RNN模型的得分也高于许多滞后模型。如果我们想在未来训练一个更轻量的模型,这可能是一个很好的起点。

总结

在这篇文章中,我展示了在时间序列上下文中集成模型的力量,以及如何使用不同的模型在时间序列上获得更高的精度。这里我们使用scalecast包,这个包的功能还是很强大的,如果你喜欢,可以去它的主页看看:

https://avoid.overfit.cn/post/cd910a41e6b94852b762cd6f2abf8b16

作者:Michael Keith

目录
相关文章
|
4月前
|
API UED 开发者
如何在Uno Platform中轻松实现流畅动画效果——从基础到优化,全方位打造用户友好的动态交互体验!
【8月更文挑战第31天】在开发跨平台应用时,确保用户界面流畅且具吸引力至关重要。Uno Platform 作为多端统一的开发框架,不仅支持跨系统应用开发,还能通过优化实现流畅动画,增强用户体验。本文探讨了Uno Platform中实现流畅动画的多个方面,包括动画基础、性能优化、实践技巧及问题排查,帮助开发者掌握具体优化策略,提升应用质量与用户满意度。通过合理利用故事板、减少布局复杂性、使用硬件加速等技术,结合异步方法与预设缓存技巧,开发者能够创建美观且流畅的动画效果。
84 0
|
4月前
|
开发者 算法 虚拟化
惊爆!Uno Platform 调试与性能分析终极攻略,从工具运用到代码优化,带你攻克开发难题成就完美应用
【8月更文挑战第31天】在 Uno Platform 中,调试可通过 Visual Studio 设置断点和逐步执行代码实现,同时浏览器开发者工具有助于 Web 版本调试。性能分析则利用 Visual Studio 的性能分析器检查 CPU 和内存使用情况,还可通过记录时间戳进行简单分析。优化性能涉及代码逻辑优化、资源管理和用户界面简化,综合利用平台提供的工具和技术,确保应用高效稳定运行。
85 0
|
4月前
|
机器学习/深度学习
【机器学习】模型融合Ensemble和集成学习Stacking的实现
文章介绍了使用mlxtend和lightgbm库中的分类器,如EnsembleVoteClassifier和StackingClassifier,以及sklearn库中的SVC、KNeighborsClassifier等进行模型集成的方法。
58 1
|
5月前
|
机器学习/深度学习 分布式计算 算法
Java中的机器学习模型集成与训练实践
Java中的机器学习模型集成与训练实践
|
6月前
|
机器学习/深度学习 人工智能 Java
Java与AI集成开发:机器学习模型部署
Java与AI集成开发:机器学习模型部署
|
5月前
|
机器学习/深度学习 数据采集 TensorFlow
深度学习与传统模型的桥梁:Sklearn与Keras的集成应用
【7月更文第24天】在机器学习领域,Scikit-learn(Sklearn)作为经典的传统机器学习库,以其丰富的预处理工具、模型选择和评估方法而闻名;而Keras作为深度学习领域的明星框架,以其简洁易用的API,支持快速构建和实验复杂的神经网络模型。将这两者结合起来,可以实现从传统机器学习到深度学习的无缝过渡,充分发挥各自的优势,打造更强大、更灵活的解决方案。本文将探讨Sklearn与Keras的集成应用,通过实例展示如何在Sklearn的生态系统中嵌入Keras模型,实现模型的训练、评估与优化。
128 0
|
6月前
|
机器学习/深度学习 人工智能 自然语言处理
【机器学习】集成语音与大型语音模型等安全边界探索
【机器学习】集成语音与大型语音模型等安全边界探索
270 5
|
5月前
|
机器学习/深度学习 PyTorch TensorFlow
在深度学习中,数据增强是一种常用的技术,用于通过增加训练数据的多样性来提高模型的泛化能力。`albumentations`是一个强大的Python库,用于图像增强,支持多种图像变换操作,并且可以与深度学习框架(如PyTorch、TensorFlow等)无缝集成。
在深度学习中,数据增强是一种常用的技术,用于通过增加训练数据的多样性来提高模型的泛化能力。`albumentations`是一个强大的Python库,用于图像增强,支持多种图像变换操作,并且可以与深度学习框架(如PyTorch、TensorFlow等)无缝集成。
|
6月前
|
存储 缓存 安全
LLM应用实战:当图谱问答(KBQA)集成大模型(三)
本文主要是针对KBQA方案基于LLM实现存在的问题进行优化,主要涉及到响应时间提升优化以及多轮对话效果优化,提供了具体的优化方案以及相应的prompt。
362 1
|
5月前
|
机器学习/深度学习 人工智能 分布式计算
Java中的机器学习模型集成与训练
Java中的机器学习模型集成与训练