返回目錄
A
數據洞見:從原始資料到商業決策 - 第 5 章
5. 預測建模與特徵工程
發布於 2026-03-07 02:27
# 5. 預測建模與特徵工程
## 5.1 前言
預測建模是資料科學流程中將分析結果轉化為可執行商業決策的關鍵步驟。\n\n- **目標**:預測未知事件或數值(如客戶流失、銷售額、設備故障)。\n- **輸入**:經過清洗、探索、特徵工程後的資料集。\n- **輸出**:可評估、可部署、可解釋的模型。\n\n本章將涵蓋從傳統線性模型到高階樹狀模型,再到參數調優與特徵工程的完整流程,並以實務案例說明。\n
---
## 5.2 模型類型概覽
| 類型 | 代表演算法 | 適用場景 | 優點 | 缺點 |
|---|---|---|---|---|
| 線性模型 | 線性迴歸、邏輯迴歸 | 數值預測、二元分類 | 解釋性強、訓練速度快 | 對非線性關係敏感 |
| 決策樹 | CART、C5.0 | 分類、回歸 | 易解釋、可處理類別變數 | 容易過擬合 |
| 集成方法 | 隨機森林、Gradient Boosting, XGBoost | 需要高預測精度 | 抗過擬合、特徵重要性 | 訓練時間較長 |
| 深度學習 | MLP、CNN、RNN | 大規模非結構化資料 | 強大擬合能力 | 需要大量資料、可解釋性差 |
---
## 5.3 線性模型
### 5.3.1 線性迴歸
```python
import pandas as pd
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
# 假設 df 已經完成前處理
X = df.drop(columns=['target'])
y = df['target']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
model = LinearRegression()
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
print('RMSE:', mean_squared_error(y_test, y_pred, squared=False))
```
- **解釋性**:係數可直接解讀變數對預測值的影響。\n- **檢驗**:多重共線性(VIF)、正態性、同方差性。\n
### 5.3.2 邏輯迴歸
```python
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report, confusion_matrix
model = LogisticRegression(max_iter=1000)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
print(confusion_matrix(y_test, y_pred))
print(classification_report(y_test, y_pred))
```
- **輸出**:機率與二元決策。\n- **特徵工程**:需對類別變數進行 one‑hot 或 target encoding。\n
---
## 5.4 決策樹與集成方法
### 5.4.1 CART(分類與回歸樹)
```python
from sklearn.tree import DecisionTreeClassifier, plot_tree
import matplotlib.pyplot as plt
clf = DecisionTreeClassifier(max_depth=5, random_state=42)
clf.fit(X_train, y_train)
plt.figure(figsize=(12,8))
plot_tree(clf, feature_names=X.columns, class_names=['0','1'], filled=True)
plt.show()
```
- **優點**:易解釋、可處理類別資料。\n- **缺點**:易過擬合,單棵樹精度有限。\n
### 5.4.2 隨機森林
```python
from sklearn.ensemble import RandomForestClassifier
rf = RandomForestClassifier(n_estimators=200, max_depth=7, random_state=42)
rf.fit(X_train, y_train)
print('Feature importance:', list(zip(X.columns, rf.feature_importances_)))
```
- **特徵重要性**:可視化排序,協助特徵選擇。\n- **調參**:`n_estimators`, `max_depth`, `min_samples_split` 等。\n
### 5.4.3 XGBoost
```python
import xgboost as xgb
xgb_clf = xgb.XGBClassifier(objective='binary:logistic', eval_metric='auc', n_estimators=300, learning_rate=0.05, max_depth=6, reg_lambda=1)
xgb_clf.fit(X_train, y_train, eval_set=[(X_test, y_test)], early_stopping_rounds=20, verbose=False)
print('Best iteration:', xgb_clf.best_iteration)
```
- **優勢**:高效能、支持缺失值自動處理、可輸出特徵重要性。\n- **調參**:`learning_rate`, `max_depth`, `subsample`, `colsample_bytree` 等。\n
---
## 5.5 特徵工程
特徵工程是模型表現的關鍵,包含以下步驟:
| 步驟 | 內容 | 具體實作 |
|---|---|---|
| 1 | 變數轉換 | Log、Box–Cox、平方根 |
| 2 | 缺失值處理 | 中位數填補、KNN、迴歸填補 |
| 3 | 變數縮放 | StandardScaler、MinMaxScaler |
| 4 | 類別編碼 | One‑Hot、Target Encoding、Frequency Encoding |
| 5 | 特徵選擇 | 相關係數、L1 正則化、Tree feature importance |
| 6 | 特徵創造 | 多項式特徵、交互項、時間特徵分解 |
### 5.5.1 變數縮放範例
```python
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
```
### 5.5.2 類別編碼範例(Target Encoding)
```python
import category_encoders as ce
encoder = ce.TargetEncoder(cols=['category_feature'])
X_train_enc = encoder.fit_transform(X_train, y_train)
X_test_enc = encoder.transform(X_test)
```
---
## 5.6 交叉驗證與參數調優
交叉驗證能減少樣本分割帶來的隨機性,常用的策略:
- **k‑fold CV**:k=5 或 10。\n- **StratifiedKFold**:維持類別比例。\n- **TimeSeriesSplit**:時間序列資料。\n
### 5.6.1 GridSearchCV 範例
```python
from sklearn.model_selection import GridSearchCV
param_grid = {
'n_estimators': [100, 200, 300],
'max_depth': [5, 7, 9],
'min_samples_split': [2, 5, 10]
}
grid = GridSearchCV(RandomForestClassifier(random_state=42), param_grid, cv=5, scoring='roc_auc')
grid.fit(X_train, y_train)
print('Best params:', grid.best_params_)
print('Best CV AUC:', grid.best_score_)
```
### 5.6.2 Bayesian Optimization 範例(Optuna)
```python
import optuna
from sklearn.model_selection import cross_val_score
def objective(trial):
n_estimators = trial.suggest_int('n_estimators', 100, 400)
max_depth = trial.suggest_int('max_depth', 3, 12)
lr = trial.suggest_loguniform('learning_rate', 1e-4, 1e-1)
model = xgb.XGBClassifier(n_estimators=n_estimators, max_depth=max_depth, learning_rate=lr, objective='binary:logistic', eval_metric='auc', use_label_encoder=False)
score = cross_val_score(model, X_train, y_train, cv=5, scoring='roc_auc').mean()
return score
study = optuna.create_study(direction='maximize')
study.optimize(objective, n_trials=50)
print('Best trial:', study.best_trial.params)
```
---
## 5.7 實務案例:零售客戶流失預測
1. **問題定義**:預測下一個月內是否流失(Yes/No)。\n2. **資料來源**:交易記錄、客戶服務、人口統計。\n3. **特徵工程**:
- 總交易額、交易頻率、最近一次交易距離。
- 類別編碼:客戶類型、付款方式。
- 欠缺值填補:使用 KNN。\n4. **模型選擇**:XGBoost 為主,並做 5‑fold CV。\n5. **評估指標**:AUC 0.83、F1 0.72。\n6. **部署**:使用 Docker + FastAPI,並在 CI/CD 中加入測試。\n
---
## 5.8 小結
- **線性模型**:快速、易解釋,適合基礎建模。\n- **決策樹與集成**:高預測精度,需注意過擬合與參數調優。\n- **特徵工程**:往往決定模型表現的上限。\n- **交叉驗證**:避免模型評估偏差。\n- **實務部署**:將模型從研究室快速落地,需重視可解釋性與維護性。\n
在下一章,我們將進一步探討模型評估、解釋與部署的完整流程,並強調模型在商業環境中的持續監控與再訓練。