今天给大家分享一个强大的算法模型,AutoARIMAProphet
AutoARIMAProphet (AAP) 是一种混合模型,旨在结合两种突出的时间序列预测技术的优势:AutoARIMA (AA) 和 Facebook Prophet (FBP)。
它由 Nixtla 开发,旨在通过利用 AutoARIMA 的「自动超参数选择功能」和 Facebook Prophet 的趋势季节性分解方法提供更稳健、更准确、更灵活的预测解决方案。
关键概念和组成部分
1.AutoARIMA
AutoARIMA 是 ARIMA(自回归移动平均)模型的高级实现,可自动选择最佳的参数组合,以优化模型的预测性能。
传统的 ARIMA(p, d, q) 模型是一种强大的统计工具,通过结合三个组成部分来预测时间序列数据。
ARIMA 模型组成
- 自回归 (AR) 部分
这部分模型是一个回归模型,使用前 p 个时刻的观测值作为自变量来预测当前值。
其中,ϕϕϕ 是模型参数,ε 是误差项。 - 差分 (I) 部分
为了使时间序列数据稳定,可能需要对原始数据进行一次或多次差分。d 是差分次数。 - 移动平均 (MA) 部分
这部分模型用前几个时间点的预测误差来做预测。q 是MA部分的阶数。
其中,θθθ 是模型参数。
AutoARIMA 的优点
- 参数选择
AutoARIMA 的主要优点是它可以自动选择最合适的 p、d 和 q 参数。 - 交叉验证
为防止过拟合,AutoARIMA 可以使用时间序列的交叉验证方法,例如滚动预测起点,来确保模型在未见数据上也表现良好。 - 模型优化
自动化的过程不仅试图找到最佳的超参数,还会尝试不同的模型组合和转换方法,如对数转换或去趋势方法,以找到最佳的模型。
在 Python 中,可以通过 pmdarima 库中的 auto_arima 函数轻松实现 AutoARIMA 模型。这使得它在商业分析、财务预测、天气预测等领域得到广泛应用。
2.Prophet
Prophet 是一个由 Facebook 开发的开源时间序列预测库,专门设计用于处理表现出强烈季节性影响和趋势的时间序列数据。
基本原理
Prophet 模型基于一个可加模型,其中时间序列被假设为三个主要组成部分的和:趋势、季节性和节假日效应。
数学上可以表示为:
其中
- 是预测值。
- 是趋势组件,用于模拟时间序列的非周期性变化。
- 是季节性组件,捕捉周期性变化如日季节性、周季节性等。
- 是节假日组件,用于模拟节假日对时间序列的影响。
- 是误差项,通常假设为正态分布。
主要特点
- 易于使用
- 灵活性,可以定制处理各种类型的时间序列数据和特定业务场景。
- 稳健性,有效管理异常值和缺失数据,在各种条件下提供可靠的预测。
- 加法模型,它将时间序列数据建模为趋势、季节性和假期的加法组合。
- 处理缺失数据,它对缺失数据点具有很强的鲁棒性,并且可以处理趋势或季节性的变化。
3.AutoARIMAProphet 模型
AutoARIMAProphet 结合了 AutoARIMA 和 Facebook Prophet 的优势,创建了一个强大的混合预测模型。
这种集成旨在利用 AutoARIMA 的自动参数选择和 Facebook Prophet 的趋势季节性分解功能。
图片
如上图所示,它说明了 AutoARIMAProphet (AAP) 算法的一般工作流程。
以下是算法中每个步骤的详细说明。
- 输入历史数据
AutoARIMAProphet 算法的第一步是输入历史时间序列数据。该数据通常包括需要预测的变量的过去观测值以及任何相关日期或时间戳。 - 使用 Prophet 模型检测时间序列特征
Facebook 的 Prophet 模型用于分析和检测时间序列数据的关键特征。
这包括识别趋势、季节性以及可能影响数据的假期或其他事件。 - 生成一组 ARIMA 模型
基于 Prophet 模型检测到的特征,生成一系列 ARIMA 模型。
每个模型代表 ARIMA 参数(p、d、q)和潜在季节性成分的不同组合。 - 在时间序列数据上评估每个模型
评估每个生成的 ARIMA 模型以确定其在时间序列数据上的性能。 - 选择性能最佳的模型
根据评估指标选择性能最佳的 ARIMA 模型。 - 将选定的模型与数据拟合
然后将选定的 ARIMA 模型拟合到整个时间序列数据,以优化其预测参数。 - 使用拟合模型进行预测
拟合模型用于生成时间序列未来值的预测。 - 输出预测和关键模型参数
最后一步输出预测值和模型的关键参数。
案例分享
首先加载数据并切分为训练集和测试集。
from sklearn.model_selection import train_test_split as TTS
import pandas as pd
import time
data_full = pd.read_csv('test.csv',index_col=0)
data_full['ds'] = pd.to_datetime(data_full['ds'])
df_dataCol = data_full.drop('y', axis = 1)
X = data_full[df_dataCol.columns]
Y = data_full['y']
# Y = df["Closing Price"] / df["Closing Price"].max()
X_train, X_test, Y_train, Y_test = TTS(X, Y,
test_size = 0.05,
random_state = 0,
shuffle=False)
df_train = X_train.join(Y_train)
df_test = X_test.join(Y_test)
接下来,构建模型并训练。
from statsforecast.adapters.prophet import AutoARIMAProphet
from tqdm import tqdm
start = time.time()
# Initialize the AutoARIMAProphet model configurations
model_config = {
"growth": "logistic",
"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 = 10
floor = 5.5
# Instantiate models
aap = AutoARIMAProphet(**model_config)
aapM2 = AutoARIMAProphet(**model_config)
df_train['cap'] = cap
df_train['floor'] = floor
# Fit the first model
with tqdm(total=1, desc="Fitting First Model") as pbar:
aap1 = aap.fit(df_train, disable_seasonal_features=False)
pbar.update(1)
# aap = aap.fit(df_train)
print("Train:", time.time() - start)
combined_df = pd.concat([df_train, df_test])
df_train['cap'] = cap
df_train['floor'] = floor
df_test['cap'] = cap
df_test['floor'] = floor
combined_df['cap'] = cap
combined_df['floor'] = floor
# Fit the second model
with tqdm(total=1, desc="Fitting Second Model") as pbar:
aap2 = aapM2.fit(combined_df, disable_seasonal_features=False)
pbar.update(1)
aap_pred_forecast = aap2.make_future_dataframe(periods = 1826, freq = 'D', include_history = True)
aap_pred_forecast['cap'] = cap
aap_pred_forecast['floor'] = floor
# Making predictions
with tqdm(total=2, desc="Making Predictions") as pbar:
aap_pred_test = aap1.predict(df_test)
aap_pred_train = aap1.predict(df_train)
aap_pred_forecast = aap2.predict(aap_pred_forecast)
pbar.update(2)
print("Pred:", time.time() - start)
最后,我们来看一下预测的结果。
import matplotlib.pyplot as plt
plt.figure(figsize=(10, 6))
plt.plot(df_train['ds'], df_train['y'], label='Train Data')
plt.plot(aap_pred_train['ds'], aap_pred_train['yhat'], label='Train Validation - Prediction')
plt.plot(df_test['ds'], df_test['y'], label='Test Data')
plt.plot(aap_pred_test['ds'], aap_pred_test['yhat'], label='Test Validation Data - Prediction')
plt.fill_between(aap_pred_forecast['ds'], aap_pred_forecast['yhat_lower'], aap_pred_forecast['yhat_upper'], color='gray', alpha=0.2)
plt.legend()
plt.xlabel('Date')
plt.ylabel('IDX KOMPAS 100 Stock Price')
plt.show()
图片