聊天視窗

金融資料科學:從數據到決策的完整流程 - 第 4 章

第四章:統計建模 ─ 從線性迴歸到時序預測

發布於 2026-03-07 11:59

# 第四章:統計建模 ─ 從線性迴歸到時序預測 在上一章,我們已將原始台股日成交資料經過清理、特徵工程,最終得到一個乾淨、結構化的 **DataFrame**,準備投入下一個階段:**統計建模**。此章將聚焦於 1. 基礎統計模型(線性迴歸、邏輯迴歸) 2. 時序模型(ARIMA、Prophet) 3. 評估指標與交叉驗證 4. 模型選擇與部署的實務建議 > 章節結構簡述:\ > - **4.1** 何謂統計建模?\ > - **4.2** 線性迴歸實務示範\ > - **4.3** 邏輯迴歸與風險分類\ > - **4.4** 時序分析:從 ARIMA 到 Prophet\ > - **4.5** 評估指標、交叉驗證與模型比較\ > - **4.6** 模型部署與持續監控 --- ## 4.1 何謂統計建模? 統計建模本質上是「用數學公式描述觀測資料之間的關係」,並藉由此關係預測未知事件。對金融資料科學來說,我們往往關心: - **價格走勢**:哪些因子能解釋或預測個股、指數的收盤價? - **風險事件**:哪些特徵能提高預測停損或停利的成功率? - **交易策略**:基於歷史資料,能否構造出「多空雙向」的投資指令? 在實務上,統計建模可分為兩大類:**線性模型**(回歸、分類)與**時序模型**(自迴歸、滑動平均)。接下來,先從線性迴歸開始,逐步過渡到更複雜的時序預測。 --- ## 4.2 線性迴歸實務示範 ### 4.2.1 需求說明 假設我們想用過去三個月的技術指標(RSI、MACD、移動平均差)來預測未來一天的收盤價。這是一個典型的**回歸問題**。 ### 4.2.2 資料準備 python # 從資料倉庫載入已清理完的 DataFrame import pandas as pd path = 'data/cleaned_ta_daily.parquet' df = pd.read_parquet(path) # 選擇特徵與目標 features = ['rsi_14', 'macd', 'sma_20', 'sma_50'] X = df[features] y = df['close'] > **小提醒**:在金融資料中,**時間順序**不可被打亂。雖然 `train_test_split` 方便,但在實際投資前,必須採用 **時序切分**。 ### 4.2.3 模型訓練 python from sklearn.model_selection import TimeSeriesSplit from sklearn.linear_model import LinearRegression from sklearn.metrics import mean_squared_error # 時序交叉驗證:保證未來資料不進入訓練集 tscv = TimeSeriesSplit(n_splits=5) mse_scores = [] 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] model = LinearRegression() model.fit(X_train, y_train) preds = model.predict(X_test) mse = mean_squared_error(y_test, preds) mse_scores.append(mse) print('平均 MSE:', np.mean(mse_scores)) ### 4.2.4 模型解釋 - **係數解讀**:`model.coef_` 直接顯示每個技術指標對收盤價的貢獻度。 - **R²**:若 `r2_score(y_test, preds)` 接近 1,模型解釋力良好;若接近 0,則需重新檢查特徵選擇或引入非線性變換。 > **實務建議**:在金融環境下,模型的 **穩健性**(robustness)比單純的 MSE 更重要。可以使用 `statsmodels` 進行 **多重共線性** 檢查、**異方差檢驗** 等。 --- ## 4.3 邏輯迴歸與風險分類 ### 4.3.1 需求說明 在風控領域,我們經常需要預測某筆交易是否會觸發停損(binary classification)。邏輯迴歸是一種簡單但有效的二元分類模型。 ### 4.3.2 資料標籤 python # 以前一天收盤價與當天收盤價之差作為標籤 threshold = -0.02 # 例如跌幅超過 2% 觸發停損 labels = (df['close'].pct_change() < threshold).astype(int) ### 4.3.3 模型訓練與評估 python from sklearn.linear_model import LogisticRegression from sklearn.metrics import classification_report, roc_auc_score X = df[features] y = labels tscv = TimeSeriesSplit(n_splits=5) reports = [] roc_scores = [] for train_idx, test_idx in tscv.split(X): X_train, X_test = X.iloc[train_idx], X.iloc[test_idx] y_train, y_test = y.iloc[train_idx], y.iloc[test_idx] clf = LogisticRegression(max_iter=200) clf.fit(X_train, y_train) pred = clf.predict(X_test) reports.append(classification_report(y_test, pred, output_dict=True)) roc_scores.append(roc_auc_score(y_test, clf.predict_proba(X_test)[:,1])) print('平均 ROC AUC:', np.mean(roc_scores)) > **風險管理小貼士**:在模型部署前,請務必執行 **類別不平衡處理**(如 `SMOTE`、`class_weight`),否則模型可能過度偏向大類別。 --- ## 4.4 時序分析:從 ARIMA 到 Prophet ### 4.4.1 為何要用時序模型? 股價、指數等金融時間序列往往呈現 **自相關**(autocorrelation)與 **趨勢**。線性迴歸忽略了時間上的依賴關係,容易產生偏差。時序模型能捕捉「過去的行為」對「未來的影響」。 ### 4.4.2 ARIMA 基礎 ARIMA(自迴歸整合移動平均)模型由三個參數構成:`(p,d,q)`。 - **p**:自迴歸階數 - **d**:差分階數(使序列平穩) - **q**:滑動平均階數 python import statsmodels.api as sm # 取收盤價 series = df['close'] # 差分一次 diff_series = series.diff().dropna() # 自動選擇 (p,d,q) from pmdarima import auto_arima arima_model = auto_arima(diff_series, seasonal=False, stepwise=True) print(arima_model.summary()) # 預測未來 5 天 forecast = arima_model.predict(n_periods=5) print('5 天預測:', forecast) > **技巧**:ARIMA 的假設是「線性」且「高斯分布」。若資料存在季節性或長尾分布,請考慮 **SARIMA** 或 **Prophet**。 ### 4.4.3 Prophet 簡介 Prophet(由 Facebook 發布)允許更直觀的季節性、假日效應設定,並可處理缺失值與異常點。 python from prophet import Prophet # Prophet 要求 DataFrame 為 {ds, y} prophet_df = df[['date', 'close']].rename(columns={'date':'ds', 'close':'y'}) model = Prophet(yearly_seasonality=True, daily_seasonality=False) model.fit(prophet_df) future = model.make_future_dataframe(periods=5, freq='D') forecast = model.predict(future) print(forecast[['ds', 'yhat', 'yhat_lower', 'yhat_upper']].tail(5)) > **比較**:ARIMA 需要大量手動調參;Prophet 內建自動季節性檢測,適合初學者。兩者皆可在 **Python + Jupyter** 環境中輕鬆跑起來。 --- ## 4.5 評估指標、交叉驗證與模型比較 | 模型類型 | 常用評估指標 | 交叉驗證方式 | 風險提示 | |-----------|---------------|----------------|-----------| | 迴歸 | MSE / RMSE / MAE / R² | 時序切分(TimeSeriesSplit) | 欠擬合/過擬合;需監控季節性漂移 | | 分類 | Accuracy / Precision / Recall / F1 / ROC AUC | 時序切分 + StratifiedKFold | 類別不平衡、樣本漂移 | | 時序 | MASE / RMSE (對比基線) | 時序切分 | 風險因子缺失、假日效應 | | > **最佳實務**:在正式投資前,請執行 **「樣本外測試」**(Out‑of‑Sample)與 **「假日效應校正」**,並結合多模型加權(Ensemble)提升預測穩定性。 --- ## 4.6 模型部署與持續監控 ### 4.6.1 服務化建議 - **模型封裝**:將 `scikit‑learn` / `statsmodels` / `prophet` 物件序列化為 **pickle** 或 **joblib**,並存於 **model registry**。 - **REST API**:使用 **FastAPI** 或 **Flask** 將模型暴露為端點,供交易系統或風控平台即時呼叫。 - **容器化**:Docker 化部署,確保依賴一致性,便於在雲端(如 GCP, AWS, Azure)擴展。 ### 4.6.2 監控指標 | 指標 | 目標 | 觸發動作 | |------|------|----------| | 交易成功率 | ≥ 55% | 重新訓練或調參 | | 模型漂移 | > 10% MSE 增長 | 觸發告警、回溯檢測 | | 風險事件比例 | < 2% | 調整停損點或模型阈值 | | 系統延遲 | < 50 ms | 優化 API 或升級硬體 | | > **告警策略**:可整合 **Prometheus + Grafana** 或 **Elasticsearch** 進行日誌聚合與視覺化。 --- ## 小結 本章以台股日成交資料為實驗,從簡單的線性迴歸、邏輯迴歸,到時序模型 ARIMA 與 Prophet,逐步展開統計建模的實務流程。關鍵在於: 1. **時序資料的特殊處理**:使用時序交叉驗證,避免資料洩漏。 2. **模型解釋與穩健性**:結合係數分析、假設檢驗與異常檢測。 3. **部署與監控**:確保模型在實際交易或風控環境中具備持續監控與快速回溯機制。 在下一章,我們將進一步闡述 **機器學習**(Random Forest、XGBoost、深度學習)與 **因子選擇** 的進階技巧,為讀者提供一整套從「資料」到「決策」的數據科學工作流。