返回目錄
A
量化投資之道:理論、模型與實戰 - 第 3 章
第三章 資料科學基礎:從數據收集到清洗
發布於 2026-02-23 19:03
# 第三章 資料科學基礎:從數據收集到清洗
> **墨羽行**
> 量化投資的根基不在於算法,而在於數據本身。若資料像砂砾,精雕細琢才能成為堅實的基石。
## 1. 資料來源:多元化、可靠與可持續
| 資料類型 | 典型來源 | 主要考量 |
|---|---|---|
| **價格數據** | Bloomberg、Reuters、Yahoo Finance、Tushare | 交易時間、時間戳對齊、重複觀測 |
| **基本面數據** | 國家統計局、公司年報、產業報告 | 會計標準差異、公告頻率 |
| **市場情緒** | Twitter、新聞 RSS、FinViz | 文字雜訊、API 限速 |
| **替代數據** | 天氣、地理資訊、衛星影像 | 資料稀疏、存取成本 |
> **提醒**:永遠要留意 *資料授權* 與 *版權合規*。即使資料免費,也要確定可用於商業分析。
## 2. 時間頻率與對齊
> **說明**:不同頻率的資料在同一個分析框架中必須對齊,否則模型會因為時點錯位而產生「虛假因子」。
python
import pandas as pd
# 假設我們有日報酬與週因子
daily = pd.read_csv('daily_returns.csv', parse_dates=['date'], index_col='date')
weekly = pd.read_csv('weekly_factors.csv', parse_dates=['date'], index_col='date')
# 先將週因子升級為日頻率
weekly_daily = weekly.resample('B').ffill() # 以商業日為頻率向前填充
# 對齊後合併
df = daily.join(weekly_daily, how='inner')
print(df.head())
> **關鍵技巧**:使用 `ffill`、`bfill` 或 `interpolate` 時務必考慮市場交易日與非交易日的影響。
## 3. 缺失值處理:不只是填補
| 方法 | 何時適用 | 風險 |
|---|---|---|
| **刪除** | 缺失值佔比 < 1% | 失去樣本,可能削弱樣本代表性 |
| **單一填補** | 僅偶發缺失 | 低偏差,但易於產生自相關 |
| **多重插補** | 缺失值集中 | 需要較多參數,計算成本 ↑ |
| **模型推斷** | 重要因子缺失 | 依賴假設,需驗證 |
python
# 多重插補示例:MICE
from sklearn.experimental import enable_iterative_imputer
from sklearn.impute import IterativeImputer
import numpy as np
imp = IterativeImputer(random_state=42)
X_imp = imp.fit_transform(df)
df_imputed = pd.DataFrame(X_imp, index=df.index, columns=df.columns)
> **提示**:在插補前先檢查缺失模式,若缺失與觀測值相關,可能需要更複雜的模型。
## 4. 特徵工程:從原始數據到因子
1. **基本財務比率**:市盈率 (PE)、市淨率 (PB)、股息殖利率 (DY)。
2. **技術指標**:移動平均 (MA)、相對強弱指標 (RSI)、布林帶。
3. **統計特徵**:波動率、偏度、峰度。
4. **主成分分析 (PCA)**:減少維度,去除共線性。
python
# 計算簡單的技術指標
prices = pd.read_csv('prices.csv', parse_dates=['date'], index_col='date')
prices['MA20'] = prices['close'].rolling(window=20).mean()
prices['MA50'] = prices['close'].rolling(window=50).mean()
prices['RSI'] = (prices['close'].diff() > 0).astype(int).rolling(window=14).mean() * 100
> **創新點**:使用 `rolling` 與 `expanding` 的組合,讓每個時間點的特徵更具前瞻性。
## 5. 標準化與歸一化
> **原因**:因子量級差異會影響模型的收斂與權重分配。
python
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_scaled = scaler.fit_transform(df_imputed)
> **備註**:對於時間序列資料,建議在 *train* 集上 fit,再 *transform* 所有資料,以避免資訊泄露。
## 6. 資料分割:保證回測的真實性
| 步驟 | 目的 |
|---|---|
| **時間序列分割** | 防止未來資訊被回測使用 |
| **交叉驗證** | 在同一時間段內測試多種參數 |
| **滑動窗口** | 模擬實際策略的持續更新 |
python
# 以 80% 訓練、20% 測試為例
split_date = df_imputed.index[-int(0.2 * len(df_imputed))]
X_train, X_test = df_imputed.loc[:split_date], df_imputed.loc[split_date:]
> **實務建議**:若使用滑動窗口回測,務必同步更新因子與回測參數,才能保持策略的可比性。
## 7. 小結
- **數據是投資模型的血液**,任何分析都要建立在乾淨且可信的數據之上。
- **缺失處理、時間對齊與特徵工程** 這三環節決定了模型能否捕捉到真實的市場訊號。
- **標準化與分割** 是防止過度擬合與資訊泄露的關鍵手段。
> **結語**:正如一位大師曾說,*「在黑夜裡,只有最亮的星星能指引你前行」*。在量化投資的海洋中,資料是那束照亮前路的星光。