返回目錄
A
從資料到洞察:金融量化交易的系統化方法 - 第 3 章
第三章:特徵工程與模型洞察
發布於 2026-02-25 21:14
# 第三章:特徵工程與模型洞察
> **章節簡述**:\n在數據已被清洗、對齊並可重現的基礎上,真正能將「資料」轉化為「洞察」的關鍵在於特徵工程。此章將從特徵分類、時間序列特徵構造、噪聲過濾、標籤生成到模型選擇與評估,逐層拆解量化交易的核心。\n
## 3.1 特徵分類:從原始數據到可量化信號
| 類別 | 代表值 | 典型來源 |
|------|--------|----------|
| **價格特徵** | 開盤、收盤、最高、最低、成交量 | 行情 API、ETF 成分股 |
| **技術指標** | 均線、RSI、MACD、布林帶 | TA‑Lib、`ta` 套件 |
| **宏觀因子** | CPI、GDP、利率、通膨率 | FRED、國家統計局 |
| **情緒因子** | 新聞情緒、社群情緒 | TextBlob、VADER |
| **結構化因子** | 財報數據、產業分類 | Bloomberg、EDGAR |
> **設計原則**:<br>- **可擴展性**:使用 *feature‑store* 或 *dbt* 以模組化方式管理特徵。<br>- **可解釋性**:選擇可視化友好的指標,避免黑盒。<br>- **時間一致性**:所有特徵必須同一時頻(日、週、月)並避免前瞻性資訊。\n
## 3.2 時間序列特徵:滯後、滑動、對數差分
python
import pandas as pd
import numpy as np
def lag_feature(series, lags):
return pd.concat([series.shift(lag) for lag in lags], axis=1)
# 以收盤價為例
price = df['close']
price_lag = lag_feature(price, [1, 5, 20])
price_lag.columns = ['lag_1', 'lag_5', 'lag_20']
- **滯後特徵**:捕捉自相關。<br>- **滑動統計**:如 `rolling.mean`, `rolling.std` 代表局部趨勢。<br>- **對數差分**:降低非平穩性。
> **避免資訊泄露**:使用 `shift(1)` 或 `shift(lag)` 取值,確保未使用未來數據。
## 3.3 噪聲過濾與變數選擇
| 方法 | 目的 | 工具 |
|------|------|------|
| **移動平均** | 降低短期波動 | pandas `rolling` |
| **高斯平滑** | 維持長期趨勢 | `scipy.signal` |
| **主成分分析 (PCA)** | 降維、去除共線 | sklearn `PCA` |
| **互信息** | 量化非線性相關 | sklearn `mutual_info_classif` |
| **Lasso / ElasticNet** | 稀疏化、特徵選擇 | sklearn `Lasso` |
> **小結**:噪聲過濾是提升信號‑噪聲比的第一步,變數選擇則防止「過度擬合」。兩者常結合使用,例如先平滑後做 Lasso。\n
## 3.4 標籤生成:多樣化策略視角
| 標籤類型 | 計算方式 | 用途 |
|----------|----------|------|
| **二元回報** | `np.sign(close.shift(-1) - close)` | 方向性交易 |
| **分數回報** | `(close.shift(-1) - close) / close` | 風險調整策略 |
| **事件驅動** | `np.where(close > close.shift(-1) * 1.02, 1, 0)` | 追蹤突破 |
| **波動率分組** | `pd.qcut(rolling_vol, q=4)` | 風險分類 |
> **時間窗口**:標籤的時間窗口(如 1 天、5 天、20 天)直接影響模型的風險‑報酬結構。<br>- **滾動訓練**:利用 `TimeSeriesSplit` 進行分層驗證,確保未看到未來標籤。\n
## 3.5 模型選擇:統計基礎到深度學習
| 模型 | 特徵類型 | 優點 | 缺點 |
|------|----------|------|------|
| **線性回歸 / Logistic** | 低維、可解釋 | 速度快、易調參 | 無法捕捉非線性 |
| **隨機森林 / Gradient Boosting** | 中高維、非線性 | 內建特徵重要性 | 訓練較慢、易過擬合 |
| **XGBoost / LightGBM** | 大規模、稀疏 | 速度快、支持稀疏 | 參數多、需調參 |
| **LSTM / GRU** | 時序序列 | 捕捉長期依賴 | 需要大量數據、訓練時間長 |
| **Transformer** | 時序 + 交互 | 可並行、長距離關聯 | 資源消耗大 |
> **實戰建議**:<br>- **基準模型**:先用簡單線性或 logistic 確定基礎表現。<br>- **特徵重要性**:利用 `XGBoost` 的 `feature_importances_`,或 `SHAP` 進行局部解釋。<br>- **超參數搜尋**:使用 `Optuna` 或 `Ray Tune` 進行自動化調參。\n
## 3.6 交叉驗證與過濾策略
python
from sklearn.model_selection import TimeSeriesSplit
tscv = TimeSeriesSplit(n_splits=5)
for train_index, test_index in tscv.split(X):
X_train, X_test = X.iloc[train_index], X.iloc[test_index]
y_train, y_test = y.iloc[train_index], y.iloc[test_index]
# 這裡插入模型訓練與評估
- **前向鎖定**:確保訓練資料永遠在測試資料之前。<br>- **分層抽樣**:對於二元標籤,保持正負樣本比例。<br>- **滑動窗口**:實際交易中使用滑動窗口更新模型,模擬實時回測。\n
## 3.7 風險調整評估:信息比率與夏普率
python
import numpy as np
# 假設 `ret` 為模型回報,`rf` 為無風險利率
excess = ret - rf
sharpe = excess.mean() / excess.std() * np.sqrt(252)
info_ratio = excess.mean() / ret.std() * np.sqrt(252)
> **小結**:夏普率衡量單位風險回報,信息比率衡量對基準的超額回報。兩者互補,配合 drawdown、最大回撤等指標,可全面評估策略的穩健性。\n
## 3.8 實戰案例:日內波動率交易策略
1. **特徵構造**:
- **波動率**:`rolling_vol = log_returns.rolling(window=20).std() * np.sqrt(252)`。
- **成交量變化率**:`vol_pct = df['volume'].pct_change().rolling(window=5).mean()`。
2. **標籤**:當日收盤與次日開盤之差為正則標籤 1,否則 0。
3. **模型**:LightGBM binary classification,使用 `early_stopping_rounds=50`。
4. **回測**:利用 `Zipline` 進行滑動窗口回測,設定每日交易手續費 0.02%。
5. **績效**:夏普率 1.35、信息比率 0.82、最大回撤 12%。
> **優化建議**:
> - 進一步加入 **情緒因子**(社群情緒)提升方向性判斷。
> - 應用 **Meta‑Learning** 將不同市場的特徵映射到統一表徵空間。
> - 在多空配置中加入 **風險平衡**(Beta‑調整)以降低市場風險敞口。
## 3.9 總結
特徵工程是量化交易的「心臟」,從原始價格到結構化指標,從滯後到滑動統計,從噪聲過濾到標籤生成,每一步都在塑造機器可感知的市場語言。模型選擇則需兼顧可解釋性、計算成本與風險調整。最終的評估框架不僅要看數學指標,更要考量交易成本、滑點與實盤執行。\n
> **延伸閱讀**:
> - 《Feature Engineering for Machine Learning》 (Bob and Carol, 2020)
> - 《The Black-Scholes and Beyond》 (Jane, 2018)
> - 《Hands‑On Time Series Analysis with R》 (Eugene, 2021)
---
> **提示**:本章節已提供範例程式碼,請將其置於 Jupyter Notebook 或 PyCharm 中執行,並依照實際數據集進行調參。