返回目錄
A
金融資料科學:從數據到決策的完整流程 - 第 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.