返回目錄
A
量化投資策略:理論到實踐的全景指南 - 第 4 章
第4章:機器學習在量化投資中的應用與實務
發布於 2026-03-03 05:56
# 第4章:機器學習在量化投資中的應用與實務
本章將帶領讀者從 **機器學習** 的基礎概念出發,結合前一章的策略構想,實作一個可落地的量化投資框架。整體流程涵蓋資料前處理、特徵工程、模型訓練、交叉驗證、後測、風險調整以及最終部署與監控。
---
## 4.1 背景與挑戰
| **問題** | **解答** |
|---|---|
| **資料量與頻率** | 股票市場每天產生數千筆交易資料,時間序列特性強,須處理缺失值與異常值。 |
| **過度擬合** | 模型在歷史資料上表現良好,卻無法泛化到未來市場。 |
| **資料洩露** | 未經處理的特徵或交易訊號會帶來「未來資訊」污染,導致評估結果不真實。 |
| **計算成本** | 大規模特徵與模型會耗費大量 CPU/GPU 時間,需設計高效流水線。 |
> **提醒**:機器學習的成功不僅取決於算法,更依賴於**資料治理**、**風險管理**與**持續監控**。
---
## 4.2 資料前處理
> **步驟 1**:下載多種市場指標(股價、成交量、技術指標等)。
>
> **步驟 2**:對缺失值進行插補或刪除,並確保時間索引一致。
>
> **步驟 3**:拆分為訓練、驗證、測試三段。
>
> **步驟 4**:對於時間序列資料,採用**滑動窗口**方式保持順序性。
```python
import pandas as pd
import numpy as np
from sklearn.model_selection import TimeSeriesSplit
# 讀取股價資料
price = pd.read_csv('data/price.csv', parse_dates=['date']).set_index('date')
# 讀取成交量
volume = pd.read_csv('data/volume.csv', parse_dates=['date']).set_index('date')
# 合併
df = price.join(volume, how='inner')
# 前處理:填補缺失值
df.fillna(method='ffill', inplace=True)
# 建立滑動窗口
window = 20 # 20 天的歷史作為特徵
features = []
labels = []
for i in range(window, len(df)):
X = df.iloc[i-window:i].values # 20*列數
y = df['close'].iloc[i] - df['close'].iloc[i-1] # 收益
features.append(X)
labels.append(y)
X = np.array(features)
y = np.array(labels)
# 時間序列分割
tscv = TimeSeriesSplit(n_splits=5)
for train_idx, test_idx in tscv.split(X):
X_train, X_test = X[train_idx], X[test_idx]
y_train, y_test = y[train_idx], y[test_idx]
# 後續模型訓練
```
> **技巧**:對於多時間尺度的特徵(如 5 日、20 日、60 日),可使用**rolling mean/variance**等簡單統計量,避免高維度造成「維度災難」。
---
## 4.3 特徵工程
| **特徵** | **說明** |
|---|---|
| 技術指標 | RSI、MACD、布林帶等 |
| 波動率 | ATR、標準差 |
| 基本面 | P/E、PB 等(如可用) |
| 交易量 | 逐日成交量、均量 |
| 時間特徵 | 交易日、周、月 |
> **注意**:所有特徵必須在「訓練資料」內計算,避免使用未來資訊。
```python
import talib
# 技術指標計算(使用 ta-lib)
# 以收盤價為例
close = df['close'].values
high = df['high'].values
low = df['low'].values
# RSI 14 天
rsi = talib.RSI(close, timeperiod=14)
# MACD
macd, macdsignal, macdhist = talib.MACD(close)
# ATR 14 天
atr = talib.ATR(high, low, close, timeperiod=14)
# 合併
feature_df = pd.DataFrame({
'rsi': rsi,
'macd': macd,
'atr': atr,
})
# 轉換為滑動窗口特徵
features = []
for i in range(window, len(feature_df)):
X = feature_df.iloc[i-window:i].values
features.append(X)
X = np.array(features)
```
> **提示**:對於不連續型特徵(如季節性),可使用 one‑hot 編碼;對於數值型特徵,請標準化(`StandardScaler`)。
---
## 4.4 模型選擇與評估
> **常用模型**:
> - 線性回歸 / Lasso / Ridge
> - 隨機森林 / XGBoost
> - 神經網路 (MLP, LSTM, Transformer)
> - 時間序列模型 (ARIMA, Prophet)
### 4.4.1 基本示範:隨機森林
```python
from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import mean_squared_error
# 訓練
rf = RandomForestRegressor(n_estimators=200, max_depth=10, random_state=42)
rf.fit(X_train, y_train)
# 預測
pred = rf.predict(X_test)
# 評估
mse = mean_squared_error(y_test, pred)
print('Test MSE:', mse)
```
### 4.4.2 交叉驗證
```python
from sklearn.model_selection import cross_val_score
# 使用時間序列分割的交叉驗證
scores = cross_val_score(rf, X, y, cv=tscv, scoring='neg_mean_squared_error')
print('CV MSE:', -scores.mean())
```
### 4.4.3 應對過度擬合
- **正則化**:Ridge / Lasso
- **特徵篩選**:使用 `SelectKBest` 或 `RecursiveFeatureElimination`(RFE)
- **模型複雜度控制**:限制樹深、樣本數
- **交叉驗證**:確保訓練/驗證分割順序正確
> **小提醒**:即使模型表現良好,也要檢查「資料洩露」與「未來資訊」問題,尤其是技術指標計算時使用的窗口。
---
## 4.5 後測與風險調整
### 4.5.1 交易訊號生成
```python
# 產生持倉訊號(長期持有)
signal = pred > 0 # 只進場於預測收益為正的日子
```
### 4.5.2 風險管理
| 風險控制 | 方式 |
|---|---|
| 位置大小 | 1% 風險敞口 / 交易金額 |
| 止損 | 3% 下跌時平倉 |
| 風險調整 | 檢查夏普比率、最大回撤 |
```python
# 位置大小(假設每筆交易風險 1%)
capital = 1_000_000
risk_per_trade = 0.01
size = (capital * risk_per_trade) / (3 / 100) # 3% 止損
# 計算每日策略報酬
position = signal.astype(int).shift(1).fillna(0)
strategy_ret = position * df['close'].pct_change()
```
### 4.5.3 回測結果
```python
cumulative_ret = (1 + strategy_ret).cumprod() - 1
print('累積報酬:', cumulative_ret.iloc[-1])
```
> **績效指標**:夏普比率、最大回撤、勝率、平均交易盈虧。
---
## 4.6 部署與監控
1. **模型序列化**:`joblib.dump` 或 `pickle`。
2. **實時資料流**:使用 `websocket` 或 `REST API` 取得行情。
3. **回測框架**:可用 `zipline`、`backtrader` 或自訂腳本。
4. **風險監控**:實時計算 VaR、預警系統。
5. **自動化報告**:每日回報、KPI、異常提醒。
```python
import joblib
# 序列化模型
joblib.dump(rf, 'models/rf_model.pkl')
# 讀取模型
model = joblib.load('models/rf_model.pkl')
```
> **部署注意**:確保 **時區**、**資料延遲**、**交易費用** 等因素被納入考量。
---
## 4.7 小結
本章以機器學習為核心,完整示範了從資料處理、特徵工程、模型訓練、風險控制到實際部署的全流程。關鍵點在於:
- **資料治理**:避免資料洩露與時間偏差。
- **模型選擇**:結合市場特性與投資目標,選擇適合的算法。
- **風險管理**:在策略中嵌入止損、位置控制與風險調整。
- **持續監控**:部署後持續追蹤績效與模型漂移。
在下一章,我們將進一步探討 **深度學習**(LSTM、Transformer)與 **強化學習** 在量化投資中的進階應用,並分享如何結合多因子模型與資產配置,以提升投資組合的整體表現。