ARIMA与Prophet的完美结合:AutoARIMAProphet时序模型

技术

AutoARIMAProphet模型

AutoARIMAProphet 是一种将两种流行的时间序列预测模型 AutoARIMA 和 Prophet 结合起来的混合模型。它结合了 AutoARIMA 模型的自动参数选择功能和 Prophet 模型的强大处理非线性趋势和季节性的能力,从而提高了时间序列预测的准确性和鲁棒性

AutoARIMA

AutoARIMA 是一种自动选择最佳ARIMA 模型参数的方法,ARIMA模型通过整合自回归(AR)部分、差分(I)部分和移动平均(MA)部分来进行预测,AutoARIMA 可以通过优化算法自动确定这些参数(p, d, q),从而使模型适应数据的特性,ARIMA模型进阶——具有季节性的SARIMAX模型实现(末尾给出了statsforecast库Github链接这个库除了ARIMA模型自动选择最佳参数以外,还存在其它模型的调用以供读者参考,模型AutoARIMAProphet也将利用这个库实现)

Prophet

Prophet 是由 Facebook 开发的一种时间序列预测模型,设计上特别适合处理具有明显季节性和假日效应的时间序列数据,Prophet 模型基于加法模型,包含趋势、季节性和假日组件,可以灵活地处理缺失数据和异常值,时间序列预测神器Prophet python实现

AutoARIMAProphet 模型 工作流程

picture.image

这样模型构建的优势在于 自动化参数选择

:利用 AutoARIMA 自动选择最佳参数,减少了模型调参的时间和复杂度, 处理非线性趋势和季节性 :通过 Prophet 的组件,模型可以有效处理复杂的趋势和季节性模式, 鲁棒性 :结合两种方法的优点,能够在多种时间序列数据上表现良好

代码构建

数据读取


          
import pandas as pd
          
import numpy as np
          
import matplotlib.pyplot as plt
          
plt.rcParams['font.sans-serif'] = 'SimHei'
          
plt.rcParams['axes.unicode_minus'] = False
          

          
df = pd.read_excel('AutOARIMA-Prophet.xlsx')
          
df['数据时间'] = pd.to_datetime(df['数据时间']) # 把日期列转换为datetime格式
          
plt.figure(figsize=(15, 5))
          
plt.plot(df['数据时间'], df['data'], color='b',  alpha=0.6)
          
plt.title('时序图')
          
plt.grid(True)
          
plt.show()
      

picture.image

数据准备


          
# 准备数据,确保日期列名为 'ds',值列名为 'y', 这里主要是去适应模型输入格式
          
df = df.rename(columns={'数据时间': 'ds', 'data': 'y'})
          

          
from sklearn.model_selection import train_test_split
          
X = df['ds']
          
Y = df['y']
          
# 分割训练集和测试集,保留时间序列的顺序shuffle=False
          
X_train, X_test, Y_train, Y_test = train_test_split(X, Y,test_size = 0.05,
          
                                                    random_state = 0,shuffle=False) 
          
# 合并成一个 DataFrame
          
train_data = pd.DataFrame({'ds': X_train, 'y': Y_train})
          
test_data = pd.DataFrame({'ds': X_test, 'y': Y_test})
          
# 确保索引排序正确
          
train_data = train_data.sort_index()
          
test_data = test_data.sort_index()
      

修改时间序列数据以适应Prophet模型的输入格式,首先将数据框中的日期列名改为'ds',将值列名改为'y'。然后使用train_test_split函数将数据分割成训练集和测试集,保持时间序列的顺序(即shuffle=False),并将它们组合成两个新的数据框,最后确保了两个数据框的索引排序正确

模型训练


          
from statsforecast.adapters.prophet import AutoARIMAProphet
          
from tqdm import tqdm
          
from datetime import datetime
          

          
# 初始化 AutoARIMAProphet 模型配置
          
model_config = {
          
    "growth": "linear",  # 设置增长类型线性增长。适用于数据呈线性增长趋势的情况。
          
    "yearly_seasonality": True,  # 启用年度季节性
          
    "seasonality_mode": "multiplicative",  # 季节性成分的模式为乘法模式
          
    "seasonality_prior_scale": 10,  # 季节性先验尺度
          
    "holidays_prior_scale": 10,  # 节假日效应的先验尺度
          
    "changepoint_prior_scale": 0.05,  # 变化点的先验尺度
          
    "interval_width": 0.75,  # 预测间隔的宽度
          
    "uncertainty_samples": 100  # 用于预测不确定性的样本数量
          
}
          
# 实例化模型
          
model = AutoARIMAProphet(**model_config)
          

          
start = datetime.now() 
          
with tqdm(total=1, desc="Fitting Model") as pbar:
          
    autoarimaprophet = model.fit(train_data, disable_seasonal_features=False)
          
    pbar.update(1)
          
print("Training time:", datetime.now() - start)  # 计算训练时间
          

          
periods = len(test_data)+30 
          
future_data = autoarimaprophet.make_future_dataframe(periods=periods)
          
# 进行预测
          
forecast = model.predict(future_data)
          
forecast.head()
      

picture.image

这里的模型预测将会从测试集的起点开始进行预测,直到定义的往后预测点数量,yhat是预测结果,yhat_lower和yhat_upper是置信区间,下面给出参数解释,具体的参数可参考原文链接

picture.image

在这里模型采用的增长类型是linear如果采用logistic需要指定预测值的上下限,具体代码如下


          
# 初始化 AutoARIMAProphet 模型配置
          
model_config = {
          
    "growth": "logistic",  # 设置增长类型为逻辑斯蒂增长,适用于 S 形增长的数据
          
    "yearly_seasonality": True,  # 启用年度季节性
          
    "seasonality_mode": "multiplicative",  # 季节性成分的模式为乘法模式
          
    "seasonality_prior_scale": 10,  # 季节性先验尺度
          
    "holidays_prior_scale": 10,  # 节假日效应的先验尺度
          
    "changepoint_prior_scale": 0.05,  # 变化点的先验尺度
          
    "interval_width": 0.75,  # 预测间隔的宽度
          
    "uncertainty_samples": 1000  # 用于预测不确定性的样本数量
          
}
          

          
cap = train_data['y'].max()  # 预测值的上限,这里采用测试集的最大值最小值,可根据实际数据进行调整
          
floor = train_data['y'].min()  # 预测值的下限
          
model = AutoARIMAProphet(**model_config)
          
# 为训练数据添加 cap 和 floor 列
          
train_data['cap'] = cap
          
train_data['floor'] = floor
          
# 训练模型
          
start = datetime.now()  # 使用datetime模块中的函数获取当前时间
          
with tqdm(total=1, desc="Fitting Model") as pbar:
          
    autoarimaprophet = model.fit(train_data, disable_seasonal_features=False)
          
    pbar.update(1)
          
print("Training time:", datetime.now() - start)  # 计算训练时间
          

          
# 预测未来30天
          
periods = len(test_data)+30 # 这里时间上是在测试集上进行预测后在往后预测未来30天
          
future_data = autoarimaprophet.make_future_dataframe(periods=periods)
          
future_data['cap'] = cap
          
future_data['floor'] = floor
          
# 进行预测
          
forecast = model.predict(future_data)
      

模型可视化


          
# 获取最后 30 个预测值
          
pred = forecast.tail(30)
          
# 测试集预测
          
start_date = test_data['ds'].iloc[0]
          
end_date = test_data['ds'].iloc[-1]
          
test_pred = forecast[(forecast['ds'] >= start_date) & (forecast['ds'] <= end_date)]
          
# 训练集预测
          
start_date = train_data['ds'].iloc[0]
          
end_date = train_data['ds'].iloc[-1]
          
train_pred = forecast[(forecast['ds'] >= start_date) & (forecast['ds'] <= end_date)]
          

          
plt.figure(figsize=(15, 5))
          
plt.plot(train_data['ds'], train_data['y'], color='r', alpha=0.3, label='训练集真实值')
          
plt.plot(test_data['ds'], test_data['y'], color='r', alpha=0.8, label='测试集真实值')
          

          
plt.plot(train_pred['ds'], train_pred['yhat'], color='blue', linestyle='--', label='训练集预测值')
          
plt.fill_between(train_pred['ds'], train_pred['yhat_lower'], train_pred['yhat_upper'], color='blue', alpha=0.2)
          

          
plt.plot(test_pred['ds'], test_pred['yhat'], color='green', linestyle='--', label='测试集预测值')
          
plt.fill_between(test_pred['ds'], test_pred['yhat_lower'], test_pred['yhat_upper'], color='green', alpha=0.2)
          

          
plt.plot(pred['ds'], pred['yhat'], color='orange', linestyle='--', label='未来预测值')
          
plt.fill_between(pred['ds'], pred['yhat_lower'], pred['yhat_upper'], color='orange', alpha=0.2)
          
plt.title('预测')
          
plt.legend()
          
plt.grid(True)
          
plt.show()
      

picture.image

往期推荐

时间序列预测:CNN-BiLSTM模型实践

Pythorch框架构建Attention-lstm时序模型

利用Pytorch框架构建lstm时间序列预测模型

灰狼优化算法(GWO):从理论到深度学习中的实践应用

梯度提升集成:LightGBM与XGBoost组合预测

基于LSTM模型的多输入多输出单步时间序列预测

如果你对类似于这样的文章感兴趣。

欢迎关注、点赞、转发~

个人观点,仅供参考

0
0
0
0
关于作者

文章

0

获赞

0

收藏

0

相关资源
VikingDB:大规模云原生向量数据库的前沿实践与应用
本次演讲将重点介绍 VikingDB 解决各类应用中极限性能、规模、精度问题上的探索实践,并通过落地的案例向听众介绍如何在多模态信息检索、RAG 与知识库等领域进行合理的技术选型和规划。
相关产品
评论
未登录
看完啦,登录分享一下感受吧~
暂无评论