返回目錄
A
掌握時序預測:Python 與統計學的實務指南 - 第 6 章
第六章:多模型集成與增強學習
發布於 2026-02-21 14:04
# 第六章:多模型集成與增強學習
> **「多樣性是強大之源」** – 這句話在統計學裡常被用來說明為何不同模型搭配能互補、提升預測性能。
在前幾章中,我們已經完成了單一模型的建立、評估與部署,接下來要把「多樣性」帶回模型堆疊,並引入 **增強學習** 的思路,將預測視為一個連續決策過程。這一章將帶你從理論到實作,一步步拆解如何把多模型集成與增強學習結合到時序預測的工作流中。
---
## 6.1 多模型集成概念
- **多樣性原則**:兩個模型若對同一個資料集產生截然不同的誤差,組合起來往往能減少總誤差。
- **集成策略**:
1. **Bagging** – 透過不同資料子集訓練模型,最後平均或投票。
2. **Boosting** – 以前一模型的錯誤為導向,調整下一個模型的權重。
3. **Stacking** – 用基層模型預測作為特徵,訓練元學習器做最終決策。
- **為什麼時序**:時序資料常伴隨季節性、趨勢與突發事件,單一模型往往難以一次抓住所有面向;集成能把不同模型擅長的領域拼接在一起。
## 6.2 常見集成方法
| 方法 | 特色 | 典型 Python 實作 | 何時適用 |
|------|------|-----------------|------------|
| Averaging | 直接平均或加權平均 | `np.mean(preds, axis=0)` | 當模型預測分布相似時 |
| Weighted Averaging | 自定權重 | `np.average(preds, axis=0, weights=w)` | 模型表現差異明顯時 |
| Stacking | 使用 meta‑learner | `sklearn.ensemble.StackingRegressor` | 多種類型基層模型 |
| Boosting (e.g., XGBoost) | 迭代學習 | `xgboost.XGBRegressor` | 基層模型難以改進時 |
### 6.2.1 代碼範例:Averaging + Weighted Averaging
python
import numpy as np
from sklearn.metrics import mean_absolute_error
# 假設已經訓練好三個模型
pred_arima = arima_forecast # shape: (n_samples,)
pred_prophet = prophet_forecast
pred_lstm = lstm_forecast
preds = np.vstack([pred_arima, pred_prophet, pred_lstm]) # shape: (3, n_samples)
# 1. 簡單平均
ensemble_simple = preds.mean(axis=0)
print('MAE (simple):', mean_absolute_error(y_true, ensemble_simple))
# 2. 加權平均,權重可根據驗證集 MAE 反向調整
w = np.array([0.4, 0.3, 0.3]) # 事先設定
ensemble_weighted = np.average(preds, axis=0, weights=w)
print('MAE (weighted):', mean_absolute_error(y_true, ensemble_weighted))
## 6.3 進階集成:ARIMA + Prophet + LSTM
### 6.3.1 為何結合這三個?
| 模型 | 擅長 | 缺點 |
|------|------|------|
| ARIMA | 線性趨勢、季節性 | 無法捕捉非線性、突發事件 |
| Prophet | 易於設定季節性與假日效應 | 過度平滑,對小樣本敏感 |
| LSTM | 捕捉長期依賴、非線性 | 需要大量資料與調參 |
結合後可將線性與季節成分分離,剩餘信號由 LSTM 進行補充。
### 6.3.2 實作流程
1. **先用 ARIMA+Prophet 分解**:得到趨勢 + 季節 + 殘差。
2. **將殘差作為 LSTM 的輸入**:學習未捕捉的非線性。
3. **最終預測 = 趨勢 + 季節 + LSTM 殘差預測**。
python
# Step 1: ARIMA + Prophet
trend_prophet, seasonality_prophet, residual = decompose_with_prophet(df['sales'])
# Step 2: LSTM on residual
lstm_model = build_lstm_model()
lstm_model.fit(X_train_residual, y_train_residual)
residual_pred = lstm_model.predict(X_test_residual)
# Step 3: Combine
final_pred = trend_prophet + seasonality_prophet + residual_pred
### 6.3.3 評估
使用 RMSE、MAPE、MASE 等多指標比較單模型與集成模型的差異。實際案例中,集成模型在零售需求預測的 30 天預測窗口上平均下降 12% RMSE。
## 6.4 集成效能評估
| 指標 | 定義 | 作用 |
|------|------|------|
| RMSE | 根號平均平方誤差 | 敏感於大誤差 |
| MAPE | 平均絕對百分比誤差 | 易解釋 |
| MASE | Mean Absolute Scaled Error | 相對於 naive 模型的尺度 |
| R² | 係數決定 | 變異量說明度 |
**注意**:在時序預測中,直接使用 MAPE 可能因為零值導致無法計算,建議使用 **MASE** 或 **sMAPE**。
## 6.5 增強學習在時序預測
### 6.5.1 為什麼要用 RL?
- **動態決策**:預測往往不是一次性,而是需要隨時更新與調整。
- **長期回報**:RL 可考慮未來成本與收益,類似「預測 + 採取行動」的結構。
### 6.5.2 基本框架
1. **環境(Environment)**:以未來的市場需求作為狀態,採取「預測調整」作為動作。
2. **觀測(Observation)**:歷史價格、銷售量、促銷活動等。
3. **報酬(Reward)**:根據預測精度與庫存成本計算。
4. **策略(Policy)**:使用 DQN、PPO 等深度 RL 演算法。
### 6.5.3 代碼片段(簡化版)
python
import gym
import torch
from stable_baselines3 import PPO
class ForecastEnv(gym.Env):
def __init__(self, data):
super().__init__()
self.data = data
self.current_step = 0
self.action_space = gym.spaces.Box(low=0, high=1, shape=(1,)) # 1 表示預測調整比例
self.observation_space = gym.spaces.Box(low=-np.inf, high=np.inf, shape=(10,))
def step(self, action):
# 用 action 調整基線預測
pred = base_forecast[self.current_step] * (1 + action[0])
true_val = self.data[self.current_step]
reward = -abs(pred - true_val) # 惩罚绝对误差
self.current_step += 1
done = self.current_step >= len(self.data)
return self._get_obs(), reward, done, {}
def _get_obs(self):
return self.data[self.current_step-10:self.current_step]
env = ForecastEnv(series)
model = PPO('MlpPolicy', env, verbose=1)
model.learn(total_timesteps=20000)
### 6.5.4 實務建議
- **報酬設計**:不要只考慮短期誤差,還要加入庫存成本、缺貨成本等實際商業指標。
- **樣本效率**:RL 通常需要大量交互,可透過**仿真環境**或**歷史回測**加速。
- **結合傳統模型**:將傳統統計模型作為初始策略,然後讓 RL 微調,能兼顧穩定性與創新。
## 6.6 案例:零售需求預測的多模型 + RL 混合
- **背景**:某電商平台需要預測每日銷售量,並根據預測調整補貨量。
- **方法**:
1. 建立 **ARIMA、Prophet、LSTM** 三個基層模型,使用 **Weighted Averaging** 組合。
2. 將集成預測作為 RL 環境的基線,RL 進行微調以降低缺貨與庫存成本。
3. 評估結果:RMSE 從 15.3% 降至 9.8%,缺貨率下降 40%。
## 6.7 實務建議與常見陷阱
| 建議 | 說明 |
|------|------|
| **模型不一定要多** | 過度複雜的集成會導致維護成本高,建議先評估單模型性能再決定是否增添。 |
| **權重調整要動態** | 隨著時間變化,基層模型的表現也會變化,使用滑動窗口或 Bayesian 更新權重。 |
| **避免「過度擬合」** | 集成也可能放大基層模型的過擬合,採用交叉驗證與外部測試集檢驗。 |
| **RL 報酬設計關鍵** | 若報酬設計不合理,RL 可能學到「最大化短期損失」的策略,務必進行理論與實驗驗證。 |
| **資料品質** | 多模型集成與 RL 皆對資料缺失、異常敏感,務必先做完整的資料清洗與異常檢測。 |
## 6.8 結語
多模型集成提供了一種兼顧不同統計假設與非線性特徵的有效方式,而增強學習則為時序預測帶來動態調整與長期成本考量的視角。兩者結合,可在商業應用中取得顯著性能提升。實務工程師在推廣時,必須平衡模型複雜度、維護成本與商業收益,才能真正落地並持續產生價值。
---
> **後續閱讀**:
> - *The Elements of Statistical Learning*(第 2 章)
> - *Deep Learning for Time Series Forecasting*(Coursera)
> - *Reinforcement Learning: An Introduction*(Sutton & Barto)
> - *Stable Baselines 3 官方文檔*(https://stable-baselines3.readthedocs.io)