LSTM模型

LSTM(Long Short-Term Memory)是一種特殊的RNN,能夠記憶較長的歷史信息,適合處理非線性和長短期依賴的序列數(shù)據(jù)。LSTM的核心是通過門機(jī)制(輸入門、遺忘門、輸出門)控制信息流。

LSTM模型公式:

LSTM單元的計(jì)算包含以下步驟:

混合模型的組成與公式

數(shù)據(jù)生成與特征分析

數(shù)據(jù)生成

我們生成包含趨勢、季節(jié)性和噪聲的時(shí)間序列,模擬現(xiàn)實(shí)中可能遇到的復(fù)雜數(shù)據(jù)。假設(shè)時(shí)間范圍為0到200,趨勢線性增加、季節(jié)性為正弦波、噪聲為正態(tài)分布。

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

# 生成合成數(shù)據(jù)
np.random.seed(0)
time = np.arange(0, 400)
trend = time * 0.1 # 趨勢項(xiàng)
seasonal = 10 * np.sin(time * 0.2) # 周期性
noise = np.random.normal(0, 1, len(time)) # 噪聲項(xiàng)
series = trend + seasonal + noise

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

數(shù)據(jù)可視化

# 繪制時(shí)間序列圖
plt.figure(figsize=(12, 6))
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擬合時(shí)間序列的線性部分

參數(shù)選擇與模型擬合

我們使用AIC準(zhǔn)則尋找最佳的?p,?d,?q?參數(shù)組合。此處手動(dòng)設(shè)定為 ARIMA(5, 1, 2),并使用模型擬合。

from statsmodels.tsa.arima.model import ARIMA

# 使用ARIMA模型擬合時(shí)間序列的線性部分
model_arima = ARIMA(df['Value'], order=(5, 1, 2))
arima_result = model_arima.fit()

# 生成預(yù)測值并繪制圖形
df['ARIMA_Prediction'] = arima_result.predict(start=1, end=len(df)-1, dynamic=False)
plt.figure(figsize=(12, 6))
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模型能夠有效捕捉數(shù)據(jù)中的趨勢和部分周期性,但在高頻噪聲部分表現(xiàn)不佳,這為LSTM捕捉非線性模式留出了空間。

使用LSTM擬合殘差序列的非線性部分

殘差計(jì)算與數(shù)據(jù)歸一化

# 計(jì)算殘差序列
df['Residual'] = df['Value'] - df['ARIMA_Prediction']

# 數(shù)據(jù)歸一化處理
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler(feature_range=(0, 1))
residual_scaled = scaler.fit_transform(df['Residual'].values.reshape(-1, 1))

LSTM模型的數(shù)據(jù)準(zhǔn)備

LSTM模型需要將數(shù)據(jù)轉(zhuǎn)換為適合RNN輸入格式的三維張量,定義一個(gè)函數(shù)來創(chuàng)建序列化的數(shù)據(jù)集。

# 創(chuàng)建LSTM數(shù)據(jù)集
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模型構(gòu)建與訓(xùn)練

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

# 構(gòu)建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模型預(yù)測殘差
lstm_predictions = model_lstm.predict(X_train)
lstm_predictions = scaler.inverse_transform(lstm_predictions)

混合模型預(yù)測與最終可視化

混合模型預(yù)測

ARIMA模型預(yù)測的線性部分與LSTM模型預(yù)測的非線性部分相加,得到最終的預(yù)測結(jié)果。這里假設(shè)ARIMA和LSTM的預(yù)測在時(shí)間上是對齊的,因此可以直接相加。

# 混合模型預(yù)測
df['Hybrid_Prediction'] = df['ARIMA_Prediction'][:len(lstm_predictions)] + lstm_predictions.flatten()

# 繪制最終的混合模型預(yù)測結(jié)果
plt.figure(figsize=(12, 6))
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()

混合模型的最終預(yù)測效果。混合模型通過結(jié)合ARIMA模型的線性部分和LSTM模型捕捉的非線性殘差,提供了比單獨(dú)使用ARIMA或LSTM更精確的預(yù)測。

模型優(yōu)化與調(diào)參流程

ARIMA模型的優(yōu)化

ARIMA模型的核心優(yōu)化在于選擇合適的參數(shù)?、、。通常可以通過AIC(Akaike信息準(zhǔn)則)或者BIC(貝葉斯信息準(zhǔn)則)來進(jìn)行模型選擇,優(yōu)化這三個(gè)參數(shù)。

ARIMA參數(shù)優(yōu)化的步驟:

  1. 差分次數(shù)d:使用差分可以去除時(shí)間序列中的非平穩(wěn)性。通常通過ADF檢驗(yàn)(單位根檢驗(yàn))來判斷是否需要差分。
  2. 自回歸階數(shù)?p:通過觀察ACF(自相關(guān)函數(shù))圖來確定。
  3. 移動(dòng)平均階數(shù)?q:通過觀察PACF(偏自相關(guān)函數(shù))圖來確定。
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf

# 畫出ACF和PACF圖,幫助選擇p和q
plt.figure(figsize=(12, 6))
plot_acf(df['Value'], lags=40, ax=plt.gca())
plt.title('ACF Plot')
plt.show()

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

AIC和BIC優(yōu)化:

from pmdarima import auto_arima

# 自動(dòng)選擇最優(yōu)ARIMA模型
auto_model = auto_arima(df['Value'], seasonal=False, trace=True, error_action='ignore', suppress_warnings=True)
auto_model.summary()

LSTM模型的優(yōu)化

LSTM模型的優(yōu)化主要涉及以下幾個(gè)方面:

LSTM模型的超參數(shù)優(yōu)化

  1. 層數(shù)與神經(jīng)元數(shù):通過增加LSTM的層數(shù)或每層的神經(jīng)元數(shù)量可以增加模型的學(xué)習(xí)能力,但也會(huì)增加計(jì)算復(fù)雜度。
  2. 訓(xùn)練批量大小和學(xué)習(xí)率:調(diào)整批量大小(batch_size)和學(xué)習(xí)率(learning_rate)來提高訓(xùn)練的收斂速度和預(yù)測精度。
  3. 訓(xùn)練輪次:增加訓(xùn)練輪次可以進(jìn)一步提高模型的預(yù)測精度,直到達(dá)到收斂。
# 使用GridSearchCV或隨機(jī)搜索來調(diào)優(yōu)LSTM的超參數(shù)
from sklearn.model_selection import GridSearchCV

# 設(shè)定參數(shù)網(wǎng)格
param_grid = {
'batch_size': [16, 32],
'epochs': [50, 100],
'optimizer': ['adam', 'rmsprop'],
'lstm_units': [50, 100]
}

# 使用GridSearch進(jìn)行調(diào)參
# 實(shí)際操作時(shí)需要定義一個(gè)合適的LSTM模型訓(xùn)練函數(shù)

交叉驗(yàn)證

LSTM訓(xùn)練過程中可以使用交叉驗(yàn)證來檢測是否發(fā)生過擬合。交叉驗(yàn)證可以幫助選擇最佳超參數(shù),避免因數(shù)據(jù)劃分不當(dāng)導(dǎo)致結(jié)果偏差。

# 可以使用KFold交叉驗(yàn)證來評估模型
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))

綜合優(yōu)化

綜合優(yōu)化時(shí),我們不僅要考慮ARIMA和LSTM的單獨(dú)優(yōu)化,還需要關(guān)注兩者結(jié)合的效果。混合模型優(yōu)化的關(guān)鍵在于如何選擇ARIMA的線性部分與LSTM的非線性部分的加權(quán)比例,以及如何處理預(yù)測誤差。

一種常用方法是加權(quán)平均法,根據(jù)ARIMA和LSTM的預(yù)測誤差來動(dòng)態(tài)調(diào)整兩者的權(quán)重。

# 根據(jù)誤差調(diào)整權(quán)重
arima_error = np.abs(df['Value'] - df['ARIMA_Prediction'])
lstm_error = np.abs(df['Residual'] - lstm_predictions.flatten())

# 計(jì)算加權(quán)系數(shù)
arima_weight = arima_error / (arima_error + lstm_error)
lstm_weight = lstm_error / (arima_error + lstm_error)

# 生成加權(quán)混合預(yù)測
df['Weighted_Hybrid_Prediction'] = arima_weight * df['ARIMA_Prediction'] + lstm_weight * lstm_predictions.flatten()

# 繪制加權(quán)混合預(yù)測
plt.figure(figsize=(12, 6))
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模型捕捉時(shí)間序列中的線性趨勢部分,并通過LSTM模型捕捉非線性部分,我們構(gòu)建了一個(gè)混合時(shí)間序列預(yù)測模型。與單獨(dú)使用ARIMA或LSTM模型相比,混合模型能夠更好地?cái)M合復(fù)雜的時(shí)間序列數(shù)據(jù),提供更加準(zhǔn)確的預(yù)測。

文章轉(zhuǎn)自微信公眾號(hào)@深夜努力寫Python

上一篇:

突破K-means,與DTW時(shí)間序列聚類分析 !!

下一篇:

突破XGBoost!時(shí)間序列預(yù)測 !!
#你可能也喜歡這些API文章!

我們有何不同?

API服務(wù)商零注冊

多API并行試用

數(shù)據(jù)驅(qū)動(dòng)選型,提升決策效率

查看全部API→
??

熱門場景實(shí)測,選對API

#AI文本生成大模型API

對比大模型API的內(nèi)容創(chuàng)意新穎性、情感共鳴力、商業(yè)轉(zhuǎn)化潛力

25個(gè)渠道
一鍵對比試用API 限時(shí)免費(fèi)

#AI深度推理大模型API

對比大模型API的邏輯推理準(zhǔn)確性、分析深度、可視化建議合理性

10個(gè)渠道
一鍵對比試用API 限時(shí)免費(fèi)