聊天視窗

量化投資之道:理論、模型與實戰 - 第 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. 小結 - **數據是投資模型的血液**,任何分析都要建立在乾淨且可信的數據之上。 - **缺失處理、時間對齊與特徵工程** 這三環節決定了模型能否捕捉到真實的市場訊號。 - **標準化與分割** 是防止過度擬合與資訊泄露的關鍵手段。 > **結語**:正如一位大師曾說,*「在黑夜裡,只有最亮的星星能指引你前行」*。在量化投資的海洋中,資料是那束照亮前路的星光。