社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  机器学习算法

【深度学习】突破LSTM!结合ARIMA时间序列预测 !!

机器学习初学者 • 1 月前 • 69 次点击  

今儿再来和大家聊聊基于LSTM和ARIMA的混合模型在时间序列预测,这部分很常见也很重要,大家有空可以仔细看看~

另外,传统的统计方法如ARIMA模型能有效捕捉线性结构,但对复杂非线性模式的表现较弱。深度学习方法(如LSTM)在非线性时间序列上有良好表现。混合模型试图结合ARIMA与LSTM各自的优势,使模型既能处理时间序列中的线性趋势,又能捕捉复杂的非线性特征。

混合模型数学原理

ARIMA模型

ARIMA模型(Auto-Regressive Integrated Moving Average)是基于时间序列的自回归和滑动平均过程。它可以表示为 ARIMA(p, d, q),其中:

  •  是自回归(AR)项的阶数。
  •  是差分次数,用于消除非平稳性。
  •  是滑动平均(MA)项的阶数。

ARIMA模型公式:

对于给定的时间序列 ,假设经过  次差分后达到平稳性,则ARIMA模型的表达为:

其中:

  •  为自回归项的系数。
  •  为滑动平均项的系数。
  •  为白噪声项,满足独立同分布。

LSTM模型

LSTM(Long Short-Term Memory)是一种特殊的RNN,能够记忆较长的历史信息,适合处理非线性和长短期依赖的序列数据。LSTM的核心是通过门机制(输入门、遗忘门、输出门)控制信息流。

LSTM模型公式:

LSTM单元的计算包含以下步骤:

  1. 遗忘门 :决定保留多少历史信息。
  1. 输入门  和候选记忆 :决定如何更新单元状态。
  1. 单元状态 :通过组合遗忘门和输入门,更新单元状态。
  1. 输出门  和隐藏状态 :计算最终的输出。

混合模型的组成与公式

对于给定时间序列 ,我们可以将其表示为线性部分  和非线性部分  的组合:

首先,我们用ARIMA对时间序列拟合线性部分 ,然后将残差序列(原序列减去ARIMA预测)用LSTM模型拟合非线性部分 ,得到最终的预测:

数据生成与特征分析

数据生成

我们生成包含趋势、季节性和噪声的时间序列,模拟现实中可能遇到的复杂数据。假设时间范围为0到200,趋势线性增加、季节性为正弦波、噪声为正态分布。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

# 生成合成数据
np.random.seed(0)
time = np.arange(0400)
trend = time * 0.1  # 趋势项
seasonal = 10 * np.sin(time * 0.2)  # 周期性
noise = np.random.normal(01, len(time))  # 噪声项
series = trend + seasonal + noise

# 存储在DataFrame中
df = pd.DataFrame({'Time': time, 'Value': series})

数据可视化

# 绘制时间序列图
plt.figure(figsize=(126))
plt.plot(df['Time'], df['Value'], label='Synthetic Time Series')
plt.title('Synthetic Time Series with Trend, Seasonality, and Noise')
plt.xlabel('Time')
plt.ylabel('Value')
plt.legend()
plt.show()

使用ARIMA拟合时间序列的线性部分

参数选择与模型拟合

我们使用AIC准则寻找最佳的  参数组合。此处手动设定为 ARIMA(5, 1, 2),并使用模型拟合。

from statsmodels.tsa.arima.model import ARIMA

# 使用ARIMA模型拟合时间序列的线性部分
model_arima = ARIMA(df['Value'], order=(512))
arima_result = model_arima.fit()

# 生成预测值并绘制图形
df['ARIMA_Prediction'] = arima_result.predict(start=1, end=len(df)-1, dynamic=False)
plt.figure(figsize=(126))
plt.plot(df['Time'], df['Value'], label='Original Time Series')
plt.plot(df['Time'], df['ARIMA_Prediction'], color='red', label='ARIMA Prediction')
plt.title('ARIMA Model Fitting')
plt.xlabel('Time')
plt.ylabel('Value')
plt.legend()
plt.show()

ARIMA模型输出分析

从拟合图中可以看到,ARIMA模型能够有效捕捉数据中的趋势和部分周期性,但在高频噪声部分表现不佳,这为LSTM捕捉非线性模式留出了空间。

使用LSTM拟合残差序列的非线性部分

残差计算与数据归一化

# 计算残差序列
df['Residual'] = df['Value'] - df['ARIMA_Prediction']

# 数据归一化处理
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler(feature_range=(01))
residual_scaled = scaler.fit_transform(df['Residual'].values.reshape(-11))

LSTM模型的数据准备

LSTM模型需要将数据转换为适合RNN输入格式的三维张量,定义一个函数来创建序列化的数据集。

# 创建LSTM数据集
def create_dataset(data, time_step=1):
    X, Y = [], []
    for i in range(len(data) - time_step - 1):
        X.append(data[i:(i + time_step), 0])
        Y.append(data[i + time_step, 0])
    return np.array(X), np.array(Y)

time_step = 5
X_train, y_train = create_dataset(residual_scaled, time_step)
X_train = X_train.reshape(X_train.shape[0], X_train.shape[1], 1)

LSTM模型构建与训练

from keras.models import Sequential
from keras.layers import LSTM, Dense

# 构建LSTM模型
model_lstm = Sequential([
    LSTM(50, return_sequences=True, input_shape=(time_step, 1)),
    LSTM(50, return_sequences=False),
    Dense(25),
    Dense(1)
])

model_lstm.compile(optimizer='adam', loss='mean_squared_error')
model_lstm.fit(X_train, y_train, epochs=50, batch_size=1 , verbose=2)

# 使用LSTM模型预测残差
lstm_predictions = model_lstm.predict(X_train)
lstm_predictions = scaler.inverse_transform(lstm_predictions)

混合模型预测与最终可视化

混合模型预测

将ARIMA模型预测的线性部分与LSTM模型预测的非线性部分相加,得到最终的预测结果。这里假设ARIMA和LSTM的预测在时间上是对齐的,因此可以直接相加。

# 混合模型预测
df['Hybrid_Prediction'] = df['ARIMA_Prediction'][:len(lstm_predictions)] + lstm_predictions.flatten()

# 绘制最终的混合模型预测结果
plt.figure(figsize=(126))
plt.plot(df['Time'], df['Value'], label='Original Time Series')
plt.plot(df['Time'][:len(df['Hybrid_Prediction'])], df['Hybrid_Prediction'], color='purple', label='Hybrid Model Prediction')
plt.title('Hybrid Model Prediction (ARIMA + LSTM)')
plt.xlabel('Time')
plt.ylabel('Value')
plt.legend()
plt.show()

混合模型的最终预测效果。混合模型通过结合ARIMA模型的线性部分和LSTM模型捕捉的非线性残差,提供了比单独使用ARIMA或LSTM更精确的预测。

模型优化与调参流程

ARIMA模型的优化

ARIMA模型的核心优化在于选择合适的参数 。通常可以通过AIC(Akaike信息准则)或者BIC(贝叶斯信息准则)来进行模型选择,优化这三个参数。

ARIMA参数优化的步骤:

  1. 差分次数:使用差分可以去除时间序列中的非平稳性。通常通过ADF检验(单位根检验)来判断是否需要差分。
  2. 自回归阶数 :通过观察ACF(自相关函数)图来确定。
  3. 移动平均阶数 :通过观察PACF(偏自相关函数)图来确定。
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf

# 画出ACF和PACF图,帮助选择p和q
plt.figure(figsize=(126))
plot_acf(df['Value'], lags=40, ax=plt.gca())
plt.title('ACF Plot')
plt.show()

plt.figure(figsize=(126))
plot_pacf(df['Value'], lags=40, ax=plt.gca())
plt.title('PACF Plot')
plt.show()

AIC和BIC优化:

  • 通过循环不同的  参数组合,使用AIC和BIC选择最佳模型。
  • 代码实现可以使用 auto_arimapmdarima库)来自动选择最优参数。
from pmdarima import auto_arima

# 自动选择最优ARIMA模型
auto_model = auto_arima(df['Value'], seasonal=False, trace=True, error_action='ignore', suppress_warnings=True)
auto_model.summary()

LSTM模型的优化

LSTM模型的优化主要涉及以下几个方面:

  • 网络结构:LSTM层数、每层的神经元数。
  • 学习率:Adam优化器的学习率、批量大小。
  • 训练轮次:过多的训练可能导致过拟合,过少的训练则可能导致欠拟合。

LSTM模型的超参数优化

  1. 层数与神经元数:通过增加LSTM的层数或每层的神经元数量可以增加模型的学习能力,但也会增加计算复杂度。
  2. 训练批量大小和学习率:调整批量大小(batch_size)和学习率(learning_rate)来提高训练的收敛速度和预测精度。
  3. 训练轮次:增加训练轮次可以进一步提高模型的预测精度,直到达到收敛。
# 使用GridSearchCV或随机搜索来调优LSTM的超参数
from sklearn.model_selection import GridSearchCV

# 设定参数网格
param_grid = {
    'batch_size': [1632],
    'epochs': [50100],
    'optimizer' : ['adam''rmsprop'],
    'lstm_units': [50100]
}

# 使用GridSearch进行调参
# 实际操作时需要定义一个合适的LSTM模型训练函数

交叉验证

LSTM训练过程中可以使用交叉验证来检测是否发生过拟合。交叉验证可以帮助选择最佳超参数,避免因数据划分不当导致结果偏差。

# 可以使用KFold交叉验证来评估模型
from sklearn.model_selection import KFold

kf = KFold(n_splits=5)
for train_index, val_index in kf.split(X_train):
    X_train_fold, X_val_fold = X_train[train_index], X_train[val_index]
    y_train_fold, y_val_fold = y_train[train_index], y_train[val_index]
    model_lstm.fit(X_train_fold, y_train_fold, epochs=50, batch_size=32, validation_data=(X_val_fold, y_val_fold))

综合优化

综合优化时,我们不仅要考虑ARIMA和LSTM的单独优化,还需要关注两者结合的效果。混合模型优化的关键在于如何选择ARIMA的线性部分与LSTM的非线性部分的加权比例,以及如何处理预测误差。

一种常用方法是加权平均法,根据ARIMA和LSTM的预测误差来动态调整两者的权重。

# 根据误差调整权重
arima_error = np.abs(df['Value'] - df['ARIMA_Prediction'])
lstm_error = np.abs(df['Residual'] - lstm_predictions.flatten())

# 计算加权系数
arima_weight = arima_error / (arima_error + lstm_error)
lstm_weight = lstm_error / (arima_error + lstm_error)

# 生成加权混合预测
df['Weighted_Hybrid_Prediction'] = arima_weight * df['ARIMA_Prediction'] + lstm_weight * lstm_predictions.flatten()

# 绘制加权混合预测
plt.figure(figsize=(126))
plt.plot(df['Time'], df['Value'], label='Original Time Series')
plt.plot(df['Time'][:len(df['Weighted_Hybrid_Prediction'])], df['Weighted_Hybrid_Prediction'], color='orange', label='Weighted Hybrid Prediction')
plt.title('Weighted Hybrid Model Prediction')
plt.xlabel('Time')
plt.ylabel('Value')
plt.legend()
plt.show()

通过使用ARIMA模型捕捉时间序列中的线性趋势部分,并通过LSTM模型捕捉非线性部分,我们构建了一个混合时间序列预测模型。与单独使用ARIMA或LSTM模型相比,混合模型能够更好地拟合复杂的时间序列数据,提供更加准确的预测。

最后

大家有问题可以直接在评论区留言即可~

喜欢本文的朋友可 收藏、点赞、转发起来!

往期精彩回顾




  • 交流群

请备注:”昵称-学校/公司-研究方向“,例如:”张小明-浙大-CV“加群。

也可以加入机器学习交流qq群772479961


Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/177715
 
69 次点击