返回目錄
A
決策者的資料科學:分析基礎與實務應用 - 第 6 章
第六章:特徵工程與模型調優
發布於 2026-03-06 03:49
# 第六章:特徵工程與模型調優
> **目標**:在機器學習專案中,特徵工程與模型調參是提高預測性能與解釋力的關鍵環節。本章將從概念、方法到實務工具,帶領決策者與分析師系統化地構建、選擇並優化特徵與模型參數,確保在真實商業環境中得到可執行且穩健的洞察。
---
## 6.1 特徵選擇(Feature Selection)
### 6.1.1 為何選擇特徵?
- **降低維度**:高維資料會導致計算成本上升、模型易過擬合。
- **提升可解釋性**:決策者能更容易理解哪些因素最具影響力。
- **提高泛化能力**:剔除噪音與無關特徵能使模型對未知資料表現更好。
### 6.1.2 方法分類
| 類型 | 優點 | 缺點 | 典型工具 |
|------|------|------|----------|
| **Filter** | 計算簡單,速度快 | 無考慮模型交互 | `SelectKBest`, `f_classif`, `mutual_info_classif` |
| **Wrapper** | 考慮模型性能 | 計算成本高 | `RFE`, `SequentialFeatureSelector` |
| **Embedded** | 兼具速度與模型參考 | 依賴特定模型 | `Lasso`, `Tree-based` feature importance |
### 6.1.3 典型實作範例(Python + scikit‑learn)
```python
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.feature_selection import SelectKBest, f_classif
from sklearn.ensemble import RandomForestClassifier
# 讀取資料
X = pd.read_csv('data/features.csv')
y = pd.read_csv('data/target.csv').values.ravel()
# 先用 Filter 方法挑選 20 個最具統計相關性的特徵
selector = SelectKBest(score_func=f_classif, k=20)
X_selected = selector.fit_transform(X, y)
# 再用 Wrapper 方法進一步優化
from sklearn.feature_selection import RFE
clf = RandomForestClassifier(n_estimators=100, random_state=42)
wrapper = RFE(estimator=clf, n_features_to_select=10)
X_wrapped = wrapper.fit_transform(X_selected, y)
```
### 6.1.4 商業案例:信用卡風險評估
> 在銀行風控場景中,僅保留「交易頻率」、「平均交易額」與「逾期次數」三個特徵,模型的 AUC 由 0.81 提升至 0.85,決策層能快速定位高風險客戶。
---
## 6.2 特徵構造(Feature Construction)
### 6.2.1 概念
透過數學運算、文字處理或領域知識,將原始資料轉換為更具資訊量的新特徵,常見手段包括:
- **時間特徵**:年、月、日、星期、季節、工作日與假期。
- **遲滯特徵**:前一日/週/月的值,用於時序模型。
- **交互特徵**:兩個變數相乘或相加,捕捉非線性關係。
- **文字特徵**:詞頻、TF‑IDF、情感分數。
- **正則化/標準化**:Z‑score、Min‑Max 等。
### 6.2.2 工具 & 技術
| 工具 | 特色 |
|------|------|
| `pandas` | 方便日期處理、欄位變換 |
| `featuretools` | 自動化特徵工程,支援多表關聯 |
| `scikit‑feature` | 提供多種特徵變換函式 |
| `tsfresh` | 時序資料自動特徵萃取 |
### 6.2.3 實作範例
```python
import pandas as pd
from datetime import datetime
# 讀取行為日誌
log = pd.read_csv('data/user_log.csv')
# 轉為 datetime
log['timestamp'] = pd.to_datetime(log['timestamp'])
# 時間特徵
log['hour'] = log['timestamp'].dt.hour
log['day_of_week'] = log['timestamp'].dt.dayofweek
log['is_weekend'] = log['day_of_week'].isin([5, 6]).astype(int)
# 遲滯特徵:前 7 天平均消費
log['avg_spend_lag7'] = log.groupby('user_id')['amount'].transform(lambda x: x.shift(1).rolling(7).mean())
```
### 6.2.4 商業案例:線上零售客戶行為
> 透過「最後一次購買距今天數」與「平均購買頻率」兩個新特徵,客戶流失預測模型的精度提升 12%。
---
## 6.3 超參數調整(Hyper‑parameter Tuning)
### 6.3.1 為何重要?
模型的表現不僅取決於資料與特徵,還取決於 **算法的內部參數**。這些參數若設定不當,模型可能過擬合或欠擬合。
### 6.3.2 常見超參數
| 算法 | 重要參數 |
|------|-----------|
| `RandomForest` | `n_estimators`, `max_depth`, `min_samples_split` |
| `XGBoost` | `learning_rate`, `max_depth`, `subsample`, `colsample_bytree` |
| `SVM` | `C`, `kernel`, `gamma` |
| `Neural Network` | `learning_rate`, `batch_size`, `layers`, `dropout_rate` |
### 6.3.3 調參方法
| 方法 | 特點 |
|------|------|
| **網格搜尋 (Grid Search)** | 系統搜尋預定範圍內的所有組合,穩健但計算成本高 |
| **隨機搜尋 (Random Search)** | 隨機抽樣參數空間,常能在較少試驗中找到較好解 |
| **貝葉斯優化 (Bayesian Optimization)** | 以過往試驗結果預測最佳參數,效率高 |
| **Hyperband / Optuna** | 結合自適應資源分配與貝葉斯搜索 |
### 6.3.4 典型實作範例(GridSearchCV)
```python
from sklearn.model_selection import GridSearchCV
from sklearn.ensemble import GradientBoostingClassifier
param_grid = {
'n_estimators': [100, 200, 300],
'learning_rate': [0.01, 0.05, 0.1],
'max_depth': [3, 5, 7]
}
gbc = GradientBoostingClassifier(random_state=42)
search = GridSearchCV(estimator=gbc, param_grid=param_grid,
cv=5, scoring='roc_auc', n_jobs=-1)
search.fit(X_train, y_train)
print('Best params:', search.best_params_)
print('Best AUC:', search.best_score_)
```
### 6.3.5 貝葉斯優化範例(Optuna)
```python
import optuna
from sklearn.ensemble import RandomForestClassifier
def objective(trial):
n_estimators = trial.suggest_int('n_estimators', 50, 300)
max_depth = trial.suggest_int('max_depth', 3, 15)
min_samples_split = trial.suggest_int('min_samples_split', 2, 10)
clf = RandomForestClassifier(
n_estimators=n_estimators,
max_depth=max_depth,
min_samples_split=min_samples_split,
random_state=42
)
clf.fit(X_train, y_train)
return cross_val_score(clf, X_val, y_val, cv=3, scoring='roc_auc').mean()
study = optuna.create_study(direction='maximize')
study.optimize(objective, n_trials=50)
print('Best trial:', study.best_trial.params)
```
---
## 6.4 網格搜尋實務策略
1. **先做預測**:先用 Random Search 或 Optuna 找出參數範圍,再進行細粒度 Grid Search。
2. **交叉驗證**:選擇適合的 CV 方法(如 StratifiedKFold)以保證結果穩定。
3. **資源管理**:利用 `n_jobs=-1` 或使用雲端計算,避免單機耗時過久。
4. **結果記錄**:用 MLflow 或 TensorBoard 追蹤參數與效能。
5. **迴圈調整**:每個迭代後檢視模型在驗證集與測試集的差距,確定是否仍需要調參。
---
## 6.5 特徵工程與調參的協同工作流程
| 步驟 | 目的 | 工具 |
|------|------|------|
| 1. 資料探索 | 了解資料分佈、缺失率 | `pandas_profiling`, `sweetviz` |
| 2. 初始特徵選擇 | 去除噪音 | `SelectKBest`, `RFE` |
| 3. 特徵構造 | 補充資訊 | `featuretools`, 自訂轉換 |
| 4. 模型訓練 | 基礎模型建立 | `scikit-learn`, `xgboost` |
| 5. 超參數調整 | 優化性能 | `GridSearchCV`, `Optuna` |
| 6. 性能評估 | 檢驗泛化 | ROC‑AUC, PR‑AUC, Calibration |
| 7. 迴圈回饋 | 持續改進 | CI/CD, CI pipeline |
> **關鍵點**:特徵工程與調參往往交叉影響。先得到一個合理的基礎模型,再細調特徵與參數,反覆迭代可達到最優表現。
---
## 6.6 商業案例研討:製造業缺陷預測
| 目標 | 1. 預測產品缺陷率、2. 降低停機成本 |
|------|----------------------------------------|
| 資料 | 機器感測數據、維修紀錄、工單信息 |
| 特徵工程 | - **時間特徵**:工作日/假期、溫度變化;
| | - **交互特徵**:壓力×溫度;
| | - **遲滯特徵**:前 5 分鐘的平均振幅 |
| 模型 | XGBoost、Random Forest |
| 調參 | Optuna 找到 `max_depth=8`, `learning_rate=0.05` |
| 成果 | 缺陷率下降 18%,停機成本節省 12% |
| 決策啟示 | 1) 高頻感測數據即時傳輸;2) 將特徵工程流程納入 CI 以自動更新模型 |
---
## 6.7 小結
1. **特徵是模型的基石**:選擇、構造與縮放特徵決定了模型學習到的資訊。
2. **超參數調整可視為“精調”**:透過系統化搜尋提升模型泛化能力。
3. **迴圈優化是關鍵**:將特徵工程與調參納入持續交付流程,才能在動態商業環境中保持競爭力。
4. **決策者參與**:在特徵設計階段就融入業務邏輯,能使模型結果更具可解釋性與可落地性。
> 在接下來的章節,我們將進一步探討如何將經過優化的模型轉化為可視化洞察,並有效傳達給非技術領導者,協助他們做出更有依據的決策。