返回目錄
A
數據科學實務:從數據蒐集到模型部署的完整流程 - 第 5 章
5. 机器学习建模
發布於 2026-02-22 19:10
# 5. 机器学习建模
在前章我們完成了資料清理與特徵工程,接下來進入建模的核心流程:選擇合適的演算法、準備特徵、調參、評估以及版本化。章節結構如下:
| 章節 | 主題 | 目標 |
|------|------|------|
| 5.1 | 模型選擇原則 | 以問題類型為導向選擇演算法 |
| 5.2 | 特徵尺度與正則化 | 保持模型數值穩定、降低過擬合 |
| 5.3 | 交叉驗證與分層抽樣 | 確保評估指標的可靠性 |
| 5.4 | 評估指標 | 選擇符合商業需求的量化指標 |
| 5.5 | 參數調優 | 利用搜尋演算法提升性能 |
| 5.6 | 風格化模型 | 轉換為可部署的格式 |
| 5.7 | 版本控制 | 保持可重現性 |
| 5.8 | 實作練習 | 完整示範 Titanic 例子 |
---
## 5.1 模型選擇原則
1. **問題類型**
- 分類:Binary / Multi‑class → Logistic Regression、RandomForest、XGBoost、Deep Learning。
- 回歸:Linear / Non‑linear → LinearRegression、GradientBoosting、Neural Network。
- 監督式外:聚類 → K‑means、DBSCAN(非監督)等。
2. **資料規模**
- < 10k:可嘗試複雜模型如 XGBoost 或簡單的線性模型。
- 10k–1M:需考慮計算成本與可擴充性,常選擇 LightGBM、CatBoost 或 sklearn 的 Pipeline。
- > 1M:批量訓練、分散式演算法(Spark MLlib、TensorFlow Distributed)。
3. **可解釋性需求**
- 商業決策需可解釋 → 采用基於樹的模型 + SHAP、LIME。
- 產品化需求高速度 → 采用線性模型或小型決策樹。
> **結論**:先從簡單模型做基準,再逐步引入複雜演算法;始終以「先穩定、後提升」為原則。
---
## 5.2 特徵尺度與正則化
| 方法 | 適用情境 | 作用 |
|------|----------|------|
| StandardScaler | 線性模型、SVM、NN | 使均值 0、方差 1,避免尺度差異影響 |
| MinMaxScaler | 神經網路 | 0–1 範圍,兼顧梯度更新 |
| L1 / L2 正則化 | 任何模型 | 防止過擬合、做特徵選擇 |
| 樹模型無須縮放 | RandomForest、XGBoost | 只受分裂閾值影響 |
> **提示**:將縮放器放進 `Pipeline`,確保測試集不受訓練集資訊污染。
---
## 5.3 交叉驗證與分層抽樣
python
from sklearn.model_selection import StratifiedKFold, cross_val_score
skf = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)
model = RandomForestClassifier(n_estimators=200, random_state=42)
scores = cross_val_score(model, X_train, y_train, cv=skf, scoring='roc_auc')
print('CV AUC:', scores.mean(), '+/-', scores.std())
- **分層抽樣**:確保各折中類別分布相近,對不平衡資料尤為重要。
- **預留驗證集**:在交叉驗證外再保留 10% 的資料作為最終測試。
---
## 5.4 評估指標
| 目標 | 指標 | 何時使用 |
|------|------|----------|
| Binary Classification | Accuracy、Precision、Recall、F1、ROC‑AUC | 基礎評估 |
| Cost‑Sensitive | Weighted F1、Custom loss | 商業成本導向 |
| Ranking | NDCG、Precision@k | 召回排序、推薦系統 |
| Regression | MSE、RMSE、MAE、R² | 連續預測 |
> **選指標原則**:選擇能直接映射商業價值的量化指標,避免僅依賴數學表面。
---
## 5.5 參數調優
- **網格搜索**:穩定但計算量大。
- **隨機搜索**:快速探索高維空間。
- **Bayesian Optimization (Optuna)**:效率高,能處理連續與離散參數。
python
import optuna
from sklearn.model_selection import cross_val_score
def objective(trial):
n_estimators = trial.suggest_int('n_estimators', 50, 300)
max_depth = trial.suggest_int('max_depth', 3, 15)
lr = trial.suggest_loguniform('learning_rate', 1e-4, 1e-1)
model = XGBClassifier(n_estimators=n_estimators,
max_depth=max_depth,
learning_rate=lr,
random_state=42)
cv = StratifiedKFold(n_splits=3, shuffle=True, random_state=42)
score = cross_val_score(model, X_train, y_train, cv=cv, scoring='roc_auc').mean()
return score
study = optuna.create_study(direction='maximize')
study.optimize(objective, n_trials=200)
print('Best params:', study.best_params)
> **小技巧**:將搜索封裝為 `Pipeline` 的 `GridSearchCV` 或 `Optuna` 參數化,保證重現性。
---
## 5.6 風格化模型
- **pickle / joblib**:快速保存;但跨語言有限。
- **ONNX**:模型互通;支持 PyTorch、TensorFlow、XGBoost。
- **TensorFlow SavedModel / TorchScript**:深度學習專用;直接部署到 TF‑Serving、TorchServe。
- **PMML**:統計模型長期標準;支持 SAS、R、Python。
> **部署前驗證**:使用 `assert` 檢查模型輸入/輸出形狀,避免服務層錯誤。
---
## 5.7 版本控制
| 工具 | 優勢 |
|------|------|
| git + GitHub | 代碼、Notebook、腳本的版本化 |
| DVC | 資料集、模型、pipeline 的版本管理 |
| MLflow | 模型、參數、指標、工件的跟蹤 |
| Docker | 環境一致性、可移植性 |
> **實踐**:在 `dvc.yaml` 定義 `metrics.yml`,每次模型更新自動推送到 GitHub,確保可追蹤。
---
## 5.8 實作練習:Titanic 例子
### 5.8.1 讀取資料
python
import pandas as pd
train = pd.read_csv('train.csv')
train_X = train.drop(columns=['Survived'])
train_y = train['Survived']
### 5.8.2 建立 Pipeline
python
from sklearn.pipeline import Pipeline
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import OneHotEncoder, StandardScaler
from sklearn.impute import SimpleImputer
from sklearn.ensemble import RandomForestClassifier
num_features = ['Age', 'SibSp', 'Parch', 'Fare']
cat_features = ['Pclass', 'Sex', 'Embarked', 'Ticket', 'Cabin', 'Name']
numeric_tf = Pipeline([('imputer', SimpleImputer(strategy='median')),
('scaler', StandardScaler())])
categorical_tf = Pipeline([('imputer', SimpleImputer(strategy='most_frequent')),
('onehot', OneHotEncoder(handle_unknown='ignore'))])
preprocess = ColumnTransformer([('num', numeric_tf, num_features),
('cat', categorical_tf, cat_features)])
clf = RandomForestClassifier(n_estimators=200, random_state=42)
model = Pipeline([('preprocess', preprocess), ('clf', clf)])
### 5.8.3 交叉驗證
python
from sklearn.model_selection import StratifiedKFold, cross_val_score
skf = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)
auc_scores = cross_val_score(model, train_X, train_y, cv=skf, scoring='roc_auc')
print('AUC:', auc_scores.mean(), '+/-', auc_scores.std())
### 5.8.4 儲存特徵與標籤
python
# 訓練一次,保存特徵與標籤
model.fit(train_X, train_y)
X_prepared = model.named_steps['preprocess'].transform(train_X)
pd.DataFrame(X_prepared).to_csv('train_X.csv', index=False)
pd.Series(train_y).to_csv('train_y.csv', index=False)
> **注意**:所有特徵轉換都已包含於 Pipeline,確保測試集不會洩漏資訊。
---
## 5.9 小結
1. **模型選擇**:先簡單再複雜,符合商業可解釋性與效能需求。
2. **特徵尺度**:統一縮放,並用 Pipeline 確保不洩漏。
3. **驗證**:分層 K‑fold + 最終驗證集,保證評估可信。
4. **評估指標**:根據商業價值選指標,避免「準確率=萬事大吉」的迷思。
5. **調參**:採用 Bayesian 或 Optuna,節省時間並提升模型表現。
6. **模型風格化**:ONNX + Docker 可快速上線;保持輸入輸出一致性。
7. **版本控制**:git + DVC + MLflow,讓每一次迭代都有可追蹤的證據。
以上即為建模的完整流程,後續章節將針對 **模型部署** 與 **監控** 進行深入探討。