聊天視窗

從資料到洞察:金融量化交易的系統化方法 - 第 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 中執行,並依照實際數據集進行調參。