聊天視窗

決策者的資料科學:分析基礎與實務應用 - 第 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. **決策者參與**:在特徵設計階段就融入業務邏輯,能使模型結果更具可解釋性與可落地性。 > 在接下來的章節,我們將進一步探討如何將經過優化的模型轉化為可視化洞察,並有效傳達給非技術領導者,協助他們做出更有依據的決策。