聊天視窗

資料驅動決策:從數據探索到模型部署 - 第 5 章

第 5 章 監督式模型建構

發布於 2026-02-27 16:26

# 第 5 章 監督式模型建構 本章將帶領讀者從基礎到進階,深入了解監督式學習模型的建構流程。內容涵蓋線性回歸、決策樹、隨機森林、XGBoost 等常用模型,並說明特徵工程、模型訓練、交叉驗證、超參數調優與模型選擇的完整工作流程。 ## 5.1 監督式學習概念回顧 | 類別 | 目標變量 | 典型演算法 | 常見應用場景 | |------|----------|------------|--------------| | 回歸 | 連續數值 | 線性回歸、SVR、決策樹回歸、隨機森林回歸、XGBoost回歸 | 房價預測、銷售預測、風險評估 | | 分類 | 離散標籤 | 邏輯回歸、KNN、決策樹、隨機森林、XGBoost、SVM | 疾病診斷、信用風險、垃圾郵件過濾 | > **要點**:監督式學習以已標籤資料為基礎,訓練模型預測未來觀測值或分類結果。模型性能的衡量指標取決於問題類型:回歸問題使用 MAE / RMSE / R²,分類問題則使用 Accuracy / Precision / Recall / F1 / ROC‑AUC。 ## 5.2 資料前處理與特徵工程 ### 5.2.1 缺失值處理 - **數值特徵**:均值/中位數填補、KNN 估計 - **類別特徵**:眾數填補、常數 "Missing" ### 5.2.2 標準化與正規化 - `StandardScaler`:均值 0、標準差 1 - `MinMaxScaler`:將特徵縮放到 [0,1] > **備註**:決策樹、隨機森林、XGBoost 對尺度不敏感,但線性模型與 SVM 對尺度敏感。 ### 5.2.3 類別編碼 - `OrdinalEncoder`:有序編碼 - `OneHotEncoder` / `pd.get_dummies`:無序編碼 - `TargetEncoder` / `LeaveOneOutEncoder`:對類別變數的目標變換 ### 5.2.4 特徵交互與多項式 ```python from sklearn.preprocessing import PolynomialFeatures poly = PolynomialFeatures(degree=2, include_bias=False) X_poly = poly.fit_transform(X) ``` > **小技巧**:使用 `VarianceThreshold` 去除方差極低的特徵,可減少維度與過擬合。 ## 5.3 模型建構流程 ### 5.3.1 數據拆分 ```python from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.2, random_state=42, stratify=y) # 分類時用 stratify ``` ### 5.3.2 建立 Pipeline Pipeline 讓前處理與模型訓練串接成一個單一流程,方便交叉驗證與超參數調整。 ```python from sklearn.pipeline import Pipeline from sklearn.preprocessing import StandardScaler from sklearn.ensemble import RandomForestRegressor pipeline = Pipeline([ ('scaler', StandardScaler()), ('rf', RandomForestRegressor(random_state=42)) ]) ``` ### 5.3.3 交叉驗證 ```python from sklearn.model_selection import cross_val_score scores = cross_val_score(pipeline, X_train, y_train, cv=5, scoring='neg_mean_squared_error') print('CV RMSE:', np.sqrt(-scores.mean())) ``` > **提示**:對於不平衡分類問題,可使用 `StratifiedKFold` 或 `RepeatedStratifiedKFold`。 ## 5.4 模型專題 ### 5.4.1 線性回歸 | 變數 | 說明 | |------|------| | `LinearRegression()` | 直接最小化 MSE,最適用於線性關係 | | `Ridge` / `Lasso` | 加入 L2 / L1 正則化,解決多重共線性 | | `ElasticNet` | 同時具備 L1 與 L2 的優點 | ```python from sklearn.linear_model import Ridge ridge = Ridge(alpha=1.0) ridge.fit(X_train, y_train) ``` ### 5.4.2 決策樹 | 參數 | 作用 | |------|------| | `max_depth` | 控制樹的最大深度,防止過擬合 | | `min_samples_split` | 分裂節點所需最小樣本數 | | `min_samples_leaf` | 葉節點最小樣本數 | ```python from sklearn.tree import DecisionTreeRegressor tree = DecisionTreeRegressor(max_depth=5, random_state=42) ``` ### 5.4.3 隨機森林 | 參數 | 作用 | |------|------| | `n_estimators` | 樹的數量,提升穩定性 | | `max_features` | 每棵樹考慮的特徵數量 | | `bootstrap` | 是否採用自助法抽樣 | ```python from sklearn.ensemble import RandomForestRegressor rf = RandomForestRegressor(n_estimators=200, max_features='sqrt', random_state=42) ``` ### 5.4.4 XGBoost | 參數 | 作用 | |------|------| | `learning_rate` | 学習率,控制每棵樹對終端模型的貢獻 | | `n_estimators` | 基學習器數量 | | `max_depth` | 樹深度 | | `subsample` | 隨機子樣本比例 | | `colsample_bytree` | 隨機特徵子集比例 | ```python import xgboost as xgb xgb_reg = xgb.XGBRegressor( objective='reg:squarederror', learning_rate=0.05, n_estimators=500, max_depth=6, subsample=0.8, colsample_bytree=0.8, random_state=42 ) ``` > **備註**:XGBoost 兼具高效與準確,對於非線性關係表現優秀,但需要較多參數調整。 ## 5.5 超參數調優 ### 5.5.1 GridSearchCV ```python from sklearn.model_selection import GridSearchCV param_grid = { 'rf__n_estimators': [100, 200, 300], 'rf__max_depth': [None, 5, 10] } grid = GridSearchCV(pipeline, param_grid, cv=5, scoring='neg_root_mean_squared_error') grid.fit(X_train, y_train) print('Best params:', grid.best_params_) ``` ### 5.5.2 RandomizedSearchCV 更適合大參數空間,節省計算時間。 ```python from sklearn.model_selection import RandomizedSearchCV import scipy param_distributions = { 'rf__n_estimators': scipy.stats.randint(100, 500), 'rf__max_depth': scipy.stats.randint(3, 15) } random_search = RandomizedSearchCV(pipeline, param_distributions, n_iter=50, cv=5, random_state=42) ``` ## 5.6 模型評估指標 | 類別 | 指標 | 解釋 | |------|------|------| | 回歸 | MAE | 平均絕對誤差,對離群點不敏感 | | 回歸 | RMSE | 平方根均方誤差,對離群點敏感 | | 回歸 | R² | 解釋變異比例,越接近 1 越好 | | 分類 | Accuracy | 正確分類比例 | | 分類 | Precision | 召回率的「純度」 | | 分類 | Recall | 抓取正例的能力 | | 分類 | F1 | Precision 與 Recall 的調和平均 | | 分類 | ROC‑AUC | 曲線下的面積,衡量分類器在不同閾值下的性能 | > **實務建議**:對於不平衡資料集,Accuracy 可能誤導;此時應重視 Precision/Recall 或使用 AUC、PR‑AUC。 ## 5.7 模型解釋性 | 工具 | 目的 | |------|------| | `feature_importances_` | 直接由樹模型提供特徵重要度 | | SHAP | 提供局部與全局解釋,符合公平性需求 | | LIME | 針對單一樣本提供局部解釋 | | Partial Dependence Plots (PDP) | 視覺化特徵對預測的邊際效應 | ```python import shap explainer = shap.TreeExplainer(rf) shap_values = explainer.shap_values(X_test) shap.summary_plot(shap_values, X_test) ``` ## 5.8 模型選擇流程 1. **基線模型**:先建立簡單模型(線性回歸、Logistic 回歸)作為基準。 2. **特徵工程**:完成缺失處理、標準化、編碼。 3. **模型比較**:使用交叉驗證同一指標比較多種模型。 4. **超參數優化**:對表現較佳的模型進行 Grid/Randomized Search。 5. **最終評估**:在測試集上評估,並做解釋性分析。 6. **部署前檢查**:確定模型可解釋、訓練時間、推論速度符合業務需求。 ## 5.9 案例實作:波士頓房價預測 ```python from sklearn.datasets import load_boston import pandas as pd import numpy as np # 讀取資料 boston = load_boston() X = pd.DataFrame(boston.data, columns=boston.feature_names) y = pd.Series(boston.target, name='MEDV') # 拆分 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # Pipeline pipeline = Pipeline([ ('scaler', StandardScaler()), ('rf', RandomForestRegressor(n_estimators=200, max_depth=6, random_state=42)) ]) # 訓練與評估 pipeline.fit(X_train, y_train) pred = pipeline.predict(X_test) print('RMSE:', np.sqrt(mean_squared_error(y_test, pred))) ``` > **結論**:在此範例中,隨機森林表現優於線性回歸;若需更高精度,可嘗試 XGBoost 或提升特徵工程。 ## 5.10 小結 - 監督式模型建構需要從資料前處理、特徵工程、模型選擇、超參數調優、評估指標與解釋性多個面向進行考量。 - 建議先用簡單模型建立基線,再逐步引入複雜模型與特徵交互,避免過度擬合。 - 交叉驗證與合理的評估指標能確保模型在未知資料上的穩定性。 - 解釋性工具(SHAP、LIME 等)不僅提升模型透明度,也有助於發現業務洞察。 在下一章「非監督式模型與降維」中,我們將探討 K‑means、層次聚類、PCA 等技術,協助你在無標籤資料中挖掘潛在結構。祝閱讀愉快!