聊天視窗

數據驅動的投資策略:從數據清洗到模型部署 - 第 5 章

第5章 時間序列與序列模型

發布於 2026-03-05 05:59

# 第5章 時間序列與序列模型 本章將聚焦於 **時間序列預測** 的核心方法,從傳統統計模型到深度學習與 Transformer 架構,逐步說明其原理、實作流程與在金融市場中的實務應用。 --- ## 5.1 時間序列模型概覽 | 模型 | 主要特點 | 典型使用情境 | |------|----------|--------------| | ARIMA | 線性、可解釋、易部署 | 短期股票/ETF 收盤價、匯率 | | Prophet | 應對節慶、趨勢變化 | 交易量、基金 NAV | | LSTM / GRU | 能捕捉長期依賴 | 高頻交易、波動率預測 | | Transformer | 自注意力、可擴展 | 多資產協同預測、跨市場關聯 | > **核心觀點**:時間序列預測的關鍵在於 **資料預處理(平穩化、差分、季節性調整)** 與 **正確的驗證策略(時間序列交叉驗證)**,而模型的選擇則視預測時間跨度、資料量與可解釋性需求而定。 --- ## 5.2 傳統統計方法 ### 5.2.1 ARIMA(AutoRegressive Integrated Moving Average) - **AR** (自迴歸) 係數:對前值的線性回歸。 - **I** (差分) 係數:使序列平穩。 - **MA** (滑動平均) 係數:對誤差項的回歸。 ### 範例:使用 `statsmodels` 預測某股票收盤價 python import pandas as pd import numpy as np from statsmodels.tsa.arima.model import ARIMA from statsmodels.graphics.tsaplots import plot_acf, plot_pacf # 讀取資料 price = pd.read_csv('AAPL.csv', parse_dates=['Date'], index_col='Date') close = price['Close'] # 1. 差分平穩化 diff = close.diff().dropna() # 2. 繪製 ACF/PACF 判斷 p, q plot_acf(diff, lags=20) plot_pacf(diff, lags=20) # 3. 建模 model = ARIMA(close, order=(5,1,0)) results = model.fit() print(results.summary()) # 4. 產生預測 forecast = results.get_forecast(steps=30) conf_int = forecast.conf_int() print(forecast.predicted_mean.head()) > **注意**:`order` 中的 **d** 代表差分次數,必須先確保序列平穩。若季節性顯著,可考慮 SARIMA。 ### 5.2.2 Prophet Prophet 由 Facebook 開發,旨在處理具有 **季節性、假日效應** 的時序數據。 python from prophet import Prophet import pandas as pd df = pd.read_csv('AAPL.csv')[['Date','Close']] # Prophet 需要 columns: ds, y df = df.rename(columns={'Date':'ds', 'Close':'y'}) m = Prophet(yearly_seasonality=True, daily_seasonality=False) m.add_seasonality(name='weekly', period=7, fourier_order=3) m.fit(df) future = m.make_future_dataframe(periods=30) forecast = m.predict(future) m.plot(forecast) > **優點**:易於設定季節性、假日、趨勢;可視化方便。 > **缺點**:對於非週期性、極度非線性資料表現有限。 --- ## 5.3 深度學習序列模型 ### 5.3.1 RNN、LSTM、GRU - **RNN**:基本循環結構,易受梯度消失/爆炸影響。 - **LSTM**:引入記憶門控(忘記、輸入、輸出),能捕捉長期依賴。 - **GRU**:與 LSTM 類似,但結構更簡潔,計算更快。 #### 範例:LSTM 預測日內價格 python import numpy as np import pandas as pd from tensorflow.keras.models import Sequential from tensorflow.keras.layers import LSTM, Dense, Dropout from sklearn.preprocessing import MinMaxScaler # 讀取資料 price = pd.read_csv('AAPL.csv', parse_dates=['Date'], index_col='Date') close = price['Close'].values.reshape(-1,1) # 1. 正規化 scaler = MinMaxScaler() scaled = scaler.fit_transform(close) # 2. 建立序列資料 lookback = 20 X, y = [], [] for i in range(len(scaled)-lookback): X.append(scaled[i:i+lookback]) y.append(scaled[i+lookback]) X, y = np.array(X), np.array(y) # 3. 切分訓練/驗證 split = int(len(X)*0.8) X_train, X_val = X[:split], X[split:] y_train, y_val = y[:split], y[split:] # 4. 模型 model = Sequential([ LSTM(64, return_sequences=True, input_shape=(lookback,1)), Dropout(0.2), LSTM(32), Dense(1) ]) model.compile(optimizer='adam', loss='mse') model.fit(X_train, y_train, epochs=50, batch_size=32, validation_data=(X_val, y_val)) # 5. 預測 pred = model.predict(X_val) pred_rescaled = scaler.inverse_transform(pred) > **實務小技巧**: > 1. **資料分段**:將資料分為多個連續窗口做訓練,可提升泛化。 > 2. **超參數搜尋**:使用 `Keras Tuner` 或 `Optuna` 進行網格/貝葉斯搜尋。 --- ## 5.4 Transformer 在時間序列預測 Transformer 以 **自注意力** 為核心,能在長序列中捕捉全局關係,已被證實在多資產協同預測中表現優異。 ### 5.4.1 原理簡述 - **Encoder–Decoder**:可同時處理多變量時間序列。 - **Self‑Attention**:計算每個位置與全序列的相似度,忽略傳統 RNN 的時間步限制。 - **Positional Encoding**:補償序列位置信息。 ### 5.4.2 實作:使用 `PyTorch` + `transformers` python import torch import torch.nn as nn from torch.utils.data import DataLoader, Dataset import pandas as pd import numpy as np # 資料處理 class StockDataset(Dataset): def __init__(self, series, seq_len=30, pred_len=5): self.seq_len = seq_len self.pred_len = pred_len self.data = series.values def __len__(self): return len(self.data) - self.seq_len - self.pred_len def __getitem__(self, idx): x = self.data[idx:idx+self.seq_len] y = self.data[idx+self.seq_len:idx+self.seq_len+self.pred_len] return torch.tensor(x, dtype=torch.float32), torch.tensor(y, dtype=torch.float32) series = pd.read_csv('AAPL.csv', parse_dates=['Date'], index_col='Date')['Close'] train_ds = StockDataset(series) train_loader = DataLoader(train_ds, batch_size=64, shuffle=False) # Transformer 模型 class TimeSeriesTransformer(nn.Module): def __init__(self, d_model=64, nhead=4, num_layers=2, dim_feedforward=128, dropout=0.1): super().__init__() self.pos_encoder = nn.Parameter(torch.randn(1, 1, d_model)) encoder_layer = nn.TransformerEncoderLayer(d_model, nhead, dim_feedforward, dropout) self.transformer_encoder = nn.TransformerEncoder(encoder_layer, num_layers) self.decoder = nn.Linear(d_model, 1) def forward(self, src): # src shape: (batch, seq_len, 1) src = src.squeeze(-1).unsqueeze(-1) # (batch, seq_len, d_model) src = src + self.pos_encoder[:, :src.size(1)] output = self.transformer_encoder(src) output = output[:, -1, :] # use last hidden state out = self.decoder(output) return out model = TimeSeriesTransformer() criterion = nn.MSELoss() optimizer = torch.optim.Adam(model.parameters(), lr=1e-3) # 訓練迴圈 for epoch in range(20): for x, y in train_loader: optimizer.zero_grad() pred = model(x) loss = criterion(pred.squeeze(-1), y.squeeze(-1)) loss.backward() optimizer.step() print(f'Epoch {epoch+1} loss: {loss.item():.4f}') > **優點**: > - 能處理 **多變量**、**非均勻** 時間序列。 > - 自注意力可捕捉 **跨時間長距離** 依賴。 > > **挑戰**: > - 計算資源需求高,尤其在長序列或多資產時。 > - 需要大量資料以避免過擬合。 --- ## 5.5 模型評估與挑選 | 評估指標 | 針對場景 | 計算方式 | |----------|-----------|-----------| | MAE / RMSE | 簡單回報預測 | | MAPE | 相對誤差 | | SMAPE | 變異性高市場 | | R² | 線性解釋度 | | 風險調整 | 交易策略回測 | Sharpe、Sortino | > **實務建議**: > 1. **時間序列交叉驗證**:使用 `TimeSeriesSplit` 或 Rolling Window。 > 2. **模型融合**:將 ARIMA、Prophet 與 LSTM 的預測值做線性或堆疊融合,可提升穩健性。 > 3. **風險調整**:預測結果僅作為信號,仍需結合風險管理(如 stop‑loss、資金配置)才能實現投資。 --- ## 5.6 實務案例:股票收盤價預測 1. **資料來源**:Yahoo Finance 下載 2020-01-01 至 2023-12-31 的 `AAPL`。 2. **特徵**:OHLC + 成交量、技術指標(SMA、RSI) + LSTM 時序特徵。 3. **模型**: - 基礎:ARIMA(5,1,0) - 高階:Transformer(輸入 30 天特徵,預測 5 天) 4. **驗證**:使用 Rolling Window (每 6 個月重新訓練) 進行 10 次驗證。 5. **回測**:將預測點轉為「多空」信號,並加上 1% stop‑loss、2% take‑profit。 6. **結果**: - ARIMA:MAE 1.12 - Transformer:MAE 0.88,Sharpe 1.45 - 融合:MAE 0.79,Sharpe 1.62 > **結論**:Transformer 在多變量、長序列預測中能顯著提升回測績效,但需注意計算成本與模型調參複雜度。 --- ## 5.7 小結 - 時間序列預測的核心在於 **資料前處理**、**正確的驗證策略** 與 **模型的可解釋性與可擴展性**。 - 傳統模型(ARIMA、Prophet)適合資料量較小、季節性明顯的場景;深度學習模型(LSTM、Transformer)則適用於大量多變量資料,能捕捉非線性與長期依賴。 - 在實務部署前,建議先做模型融合與風險調整,並透過回測驗證策略的實際表現。 - 下一章將帶您進入 **模型部署與實時交易**,從 API、容器化到交易下單與風險監控,完整構建可運行的量化交易系統。