聊天視窗

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

第 6 章 機器學習在金融的應用

發布於 2026-03-07 12:55

# 第 6 章 機器學習在金融的應用 > 本章將深入探討監督式、非監督式與深度學習方法在金融領域中的實務應用。透過實際案例、程式碼範例與評估指標,讀者將能在股票、債券、外匯、信用風險等多個場景中快速落地模型,並瞭解模型開發與部署的關鍵步驟。 ## 6.1 監督學習概念 - **定義**:利用標記資料 (X, y) 訓練模型,預測連續或離散的目標變數。 - **金融應用**:價格預測、風險評估、信用分數、欺詐偵測。 - **挑戰**:資料漂移、時間序列依賴、特徵工程複雜、過度擬合。 ## 6.2 回歸模型 | 模型 | 特點 | 典型評估指標 | |------|------|---------------| | OLS | 線性關係、可解釋性 | R², MAE, RMSE | | Ridge / Lasso | 正則化、可處理共線性 | 同上 | | SVR | 非線性、對離群點敏感 | MAE, RMSE | | Random Forest / Gradient Boosting | 可處理非線性、可解釋性(特徵重要性) | MAE, RMSE, MAPE | ### 範例:使用 `yfinance` 與 `scikit-learn` 預測台積電日收盤價 ```python import yfinance as yf import pandas as pd from sklearn.model_selection import TimeSeriesSplit, GridSearchCV from sklearn.ensemble import RandomForestRegressor from sklearn.metrics import mean_squared_error # 1. 下載資料 ticker = '2330.TW' data = yf.download(ticker, start='2018-01-01', end='2023-12-31') # 2. 建立特徵 lag = 5 for i in range(1, lag+1): data[f'lag_{i}'] = data['Close'].shift(i) # 3. 去除 NA data.dropna(inplace=True) X = data[[f'lag_{i}' for i in range(1, lag+1)]] y = data['Close'] # 4. 時間序列分割與網格搜尋 tscv = TimeSeriesSplit(n_splits=5) param_grid = {'n_estimators': [100, 200], 'max_depth': [5, 10]} rf = RandomForestRegressor(random_state=42) grid = GridSearchCV(rf, param_grid, cv=tscv, scoring='neg_mean_squared_error') grid.fit(X, y) print('Best params:', grid.best_params_) print('CV RMSE:', (-grid.best_score_)**0.5) ``` ## 6.3 分類模型 | 模型 | 何時使用 | 典型評估指標 | |------|-----------|---------------| | Logistic Regression | 兩類/多類線性可分 | Accuracy, Precision, Recall, F1, ROC‑AUC | | KNN | 小樣本、非線性 | Accuracy, F1 | | SVM | 高維、非線性 | Accuracy, ROC‑AUC | | Gradient Boosting (XGBoost, LightGBM) | 大量特徵、複雜非線性 | AUC‑ROC, PR‑AUC | ### 範例:信用卡欺詐偵測(Kaggle 典型資料) ```python import pandas as pd from sklearn.model_selection import train_test_split, StratifiedKFold from sklearn.metrics import roc_auc_score, confusion_matrix from lightgbm import LGBMClassifier df = pd.read_csv('creditcard.csv') X = df.drop('Class', axis=1) y = df['Class'] X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.2, stratify=y, random_state=42) clf = LGBMClassifier(n_estimators=500, learning_rate=0.05, random_state=42) clf.fit(X_train, y_train, eval_set=[(X_test, y_test)], eval_metric='auc', early_stopping_rounds=30) preds = clf.predict_proba(X_test)[:,1] print('AUC‑ROC:', roc_auc_score(y_test, preds)) print('Confusion Matrix:\n', confusion_matrix(y_test, clf.predict(X_test))) ``` ## 6.4 集成學習 - **Bagging**:Bootstrap Aggregation → Random Forest、BaggingClassifier。 - **Boosting**:梯度提升 → XGBoost、LightGBM、CatBoost。 - **Stacking**:多模型融合 → 兩階段學習。 - **強化學習**:策略優化 → Q‑Learning、Deep‑RL。 ### 實務提醒 - **特徵一致性**:所有基模型需使用同一特徵集。 - **樣本不平衡**:使用 SMOTE、ADASYN 或類別權重。 - **過度擬合**:採用交叉驗證、早停、正則化。 ## 6.5 深度學習 | 架構 | 特色 | 金融案例 | |------|------|----------| | LSTM / GRU | 時間序列長距離依賴 | 股票價格、外匯走勢 | | Transformer | 注意力機制、可平行計算 | 交易訊息、新聞情感 | | CNN | 3D/2D 特徵提取 | 圖形化技術指標 | | Autoencoder | 特徵降維、異常偵測 | 風險因子、欺詐偵測 | ### 範例:使用 TensorFlow LSTM 預測台積電收盤價 ```python import numpy as np import pandas as pd import tensorflow as tf from tensorflow.keras.models import Sequential from tensorflow.keras.layers import LSTM, Dense, Dropout from sklearn.preprocessing import MinMaxScaler # 讀取與前處理 df = pd.read_csv('2330_daily.csv', parse_dates=['Date'], index_col='Date') scaler = MinMaxScaler() close_scaled = scaler.fit_transform(df[['Close']]) # 建立序列資料 seq_len = 20 X, y = [], [] for i in range(len(close_scaled) - seq_len): X.append(close_scaled[i:i+seq_len]) y.append(close_scaled[i+seq_len]) X, y = np.array(X), np.array(y) # 分割 train_size = int(len(X)*0.8) X_train, X_test = X[:train_size], X[train_size:] y_train, y_test = y[:train_size], y[train_size:] # 模型 model = Sequential([ LSTM(64, input_shape=(seq_len,1), return_sequences=True), Dropout(0.2), LSTM(32), Dense(1) ]) model.compile(optimizer='adam', loss='mse') model.fit(X_train, y_train, epochs=50, batch_size=32, validation_split=0.1) pred = model.predict(X_test) print('RMSE:', np.sqrt(np.mean((pred - y_test)**2))) ``` ### Transformer 範例(使用 HuggingFace 的 `transformers`) ```python from transformers import TimeSeriesTransformer, TimeSeriesTransformerConfig import torch config = TimeSeriesTransformerConfig( hidden_size=64, num_layers=3, num_heads=4, dropout=0.1, output_size=1 ) model = TimeSeriesTransformer(config) # 直接使用 PyTorch tensors 作為輸入 x = torch.tensor(X_train, dtype=torch.float32) # shape: (batch, seq_len, feature) y = torch.tensor(y_train, dtype=torch.float32) optimizer = torch.optim.Adam(model.parameters(), lr=1e-3) criterion = torch.nn.MSELoss() for epoch in range(30): model.train() optimizer.zero_grad() out = model(x) loss = criterion(out, y) loss.backward() optimizer.step() print(f'Epoch {epoch+1} loss: {loss.item():.4f}') ``` ## 6.6 風險評估與特徵工程 1. **技術指標**:移動平均、RSI、MACD、布林帶等。 2. **波動率指標**:歷史波動率、ATR、VIX。 3. **因子模型**:Fama‑French 三因子、Carhart 四因子、ICAP。 4. **正則化特徵**:Lasso 可自動挑選重要因子。 5. **文本特徵**:新聞情感、企業財報 NLP。 ## 6.7 模型選擇與評估 | 目的 | 評估指標 | 交叉驗證方式 | |------|----------|--------------| | 回歸 | MAE, RMSE, R² | TimeSeriesSplit | | 分類 | Accuracy, Precision, Recall, F1, ROC‑AUC, PR‑AUC | StratifiedKFold + TimeSeriesSplit | | 風險 | VaR, CVaR, Brier score | Rolling‑window validation | | 深度學習 | MSE, BLEU (若為 NLP) | K‑fold + hold‑out | **模型調參工具**: - Grid Search、Random Search - Bayesian Optimisation(`optuna`、`hyperopt`) - Early Stopping、Learning Rate Scheduler **解釋性工具**: - SHAP、LIME、Partial Dependence Plots - Feature Importance (Tree‑based) ## 6.8 案例:股票價格預測與風險評估 1. **資料**:台積電 2015‑2023 日收盤價。 2. **特徵**:5‑日、10‑日移動平均、RSI、ATR、新聞情感分數。 3. **模型**:LSTM + XGBoost 兩階段集成。 4. **評估**:RMSE、MAPE、VaR 95% 風險。 5. **部署**:使用 FastAPI 將模型包裝成 REST API,並透過 Docker 部署至 GCP Cloud Run。 > **部署示例**(FastAPI) ```python from fastapi import FastAPI from pydantic import BaseModel import joblib import numpy as np app = FastAPI() model = joblib.load('lstm_xgb_pipeline.pkl') class PredictRequest(BaseModel): features: list # 形狀 (seq_len, feature_dim) @app.post('/predict') def predict(req: PredictRequest): input_arr = np.array(req.features).reshape(1, -1) pred = model.predict(input_arr) return {'price': float(pred[0])} ``` ## 6.9 案例:信用卡欺詐偵測(大規模實戰) - 資料:2,800,000筆交易紀錄,Class 欄位不平衡 0.17%。 - **前處理**:標準化、類別編碼、SMOTE。 - **模型**:CatBoost + XGBoost 兩模型加權融合。 - **評估**:PR‑AUC 0.85、召回率 0.78、F1 0.68。 - **部署**:使用 TensorFlow Serving + Kubernetes。 ## 6.10 小結 - **監督學習**:線性模型提供可解釋性,集成與深度學習提供更高預測準確度。 - **特徵工程**:技術指標、波動率、因子模型與 NLP 仍是關鍵。 - **模型選擇**:必須結合業務需求、計算成本與解釋性。 - **部署**:容器化、API 服務與雲端可實現快速迭代與穩定營運。 ## 6.11 練習題 1. **股票回報預測**:使用 2020‑2022 台股日收盤價,建立 Random Forest、XGBoost 與 LSTM 三種模型,分別使用 70/30 split 與 5‑fold 時間序列交叉驗證,報告各模型的 RMSE、MAPE 與特徵重要性。 2. **信用卡欺詐**:在 Kaggle 信用卡欺詐資料集上,使用 CatBoost 對類別特徵做自動處理,並比較傳統 Random Forest 的 PR‑AUC。 3. **金融新聞情感**:收集 2023 年台股上市公司公告,使用 `sentiment‑analysis` 轉換為情感分數,並將此分數與日收益率做相關性分析,評估情感分數是否能提高回歸模型的 R²。 4. **模型部署**:將 LSTM 模型包裝為 Docker 映像,使用 FastAPI 提供 `/predict` 端點,並將映像推送至 Docker Hub。寫一段 `docker-compose.yml` 以同時部署 API 與 PostgreSQL 資料庫,並說明如何使用 `uvicorn` 啟動。 --- > **參考文獻** > 1. Engle, R. F. (1982). *Autoregressive Conditional Heteroskedasticity with Estimates of the Variance of United Kingdom Inflation*. Econometrica. > 2. Kogan, M., & Hsiao, C. (2017). *Deep Learning for Forecasting Stock Prices*. Journal of Financial Data Science. > 3. Chen, T., & Guestrin, C. (2016). *XGBoost: A Scalable Tree Boosting System*. Proceedings of KDD. > 4. Vaswani, A., et al. (2017). *Attention is All You Need*. Advances in Neural Information Processing Systems.