
如何高效爬取全球新聞網站 – 整合Scrapy、Selenium與Mediastack API實現自動化新聞采集
LSTM(Long Short-Term Memory)是一種特殊的RNN,能夠記憶較長的歷史信息,適合處理非線性和長短期依賴的序列數據。LSTM的核心是通過門機制(輸入門、遺忘門、輸出門)控制信息流。
LSTM模型公式:
LSTM單元的計算包含以下步驟:
混合模型的組成與公式
我們生成包含趨勢、季節性和噪聲的時間序列,模擬現實中可能遇到的復雜數據。假設時間范圍為0到200,趨勢線性增加、季節性為正弦波、噪聲為正態分布。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# 生成合成數據
np.random.seed(0)
time = np.arange(0, 400)
trend = time * 0.1 # 趨勢項
seasonal = 10 * np.sin(time * 0.2) # 周期性
noise = np.random.normal(0, 1, len(time)) # 噪聲項
series = trend + seasonal + noise
# 存儲在DataFrame中
df = pd.DataFrame({'Time': time, 'Value': series})
數據可視化
# 繪制時間序列圖
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()
我們使用AIC準則尋找最佳的?p,?d,?q?參數組合。此處手動設定為 ARIMA(5, 1, 2),并使用模型擬合。
from statsmodels.tsa.arima.model import ARIMA
# 使用ARIMA模型擬合時間序列的線性部分
model_arima = ARIMA(df['Value'], order=(5, 1, 2))
arima_result = model_arima.fit()
# 生成預測值并繪制圖形
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模型能夠有效捕捉數據中的趨勢和部分周期性,但在高頻噪聲部分表現不佳,這為LSTM捕捉非線性模式留出了空間。
# 計算殘差序列
df['Residual'] = df['Value'] - df['ARIMA_Prediction']
# 數據歸一化處理
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler(feature_range=(0, 1))
residual_scaled = scaler.fit_transform(df['Residual'].values.reshape(-1, 1))
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=(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()
混合模型的最終預測效果。混合模型通過結合ARIMA模型的線性部分和LSTM模型捕捉的非線性殘差,提供了比單獨使用ARIMA或LSTM更精確的預測。
ARIMA模型的核心優化在于選擇合適的參數?、、。通常可以通過AIC(Akaike信息準則)或者BIC(貝葉斯信息準則)來進行模型選擇,優化這三個參數。
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優化:
auto_arima
(pmdarima
庫)來自動選擇最優參數。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模型的優化主要涉及以下幾個方面:
# 使用GridSearchCV或隨機搜索來調優LSTM的超參數
from sklearn.model_selection import GridSearchCV
# 設定參數網格
param_grid = {
'batch_size': [16, 32],
'epochs': [50, 100],
'optimizer': ['adam', 'rmsprop'],
'lstm_units': [50, 100]
}
# 使用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=(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模型捕捉時間序列中的線性趨勢部分,并通過LSTM模型捕捉非線性部分,我們構建了一個混合時間序列預測模型。與單獨使用ARIMA或LSTM模型相比,混合模型能夠更好地擬合復雜的時間序列數據,提供更加準確的預測。