聊天視窗

從資料到決策:系統化資料科學實踐手冊 - 第 4 章

第 4 章 特徵工程與降維

發布於 2026-03-05 16:15

# 第 4 章 特徵工程與降維 > **關鍵字**:特徵擴充、編碼、PCA、t‑SNE、特徵選擇、資料可視化、模型性能。 --- ## 4.1 引言 特徵工程是資料科學流程中最具「藝術性」的階段之一,直接影響模型的可解釋性與預測表現。這一章將從基礎的數值與類別特徵處理說起,逐步引入特徵擴充、選擇與降維三大技術,並以實務案例示範如何將這些工具組合成一條高效、可重複的流程。 > **為什麼特徵工程重要?** > > - **提升模型準確度**:合適的特徵能讓模型更容易捕捉資料內在規律。 > - **減少過擬合**:剔除冗餘或噪音特徵能降低模型複雜度。 > - **加速訓練**:降維與特徵選擇能縮減維度,節省計算資源。 > - **增強可解釋性**:透過可解釋的特徵表徵,方便業務人員理解模型決策。 --- ## 4.2 數值特徵處理 | 步驟 | 目的 | 常見方法 | |------|------|----------| | 缺失值補值 | 防止 NaN 影響模型 | 均值、中位數、KNN、迴歸補值 | | 標準化 (StandardScaler) | 讓特徵符合 N(0,1) | `sklearn.preprocessing.StandardScaler` | | 正規化 (MinMaxScaler) | 使特徵落在 [0,1] | `sklearn.preprocessing.MinMaxScaler` | | 取對數/平方根 | 處理偏態分布 | `np.log1p`, `np.sqrt` | | 標籤加噪聲 | 防止過擬合 | 隨機噪聲、Dropout | python import pandas as pd from sklearn.preprocessing import StandardScaler, MinMaxScaler # 假設 df 為原始 DataFrame numeric_cols = df.select_dtypes(include=['int64', 'float64']).columns # 補值:以中位數為例 df[numeric_cols] = df[numeric_cols].fillna(df[numeric_cols].median()) # 標準化 scaler = StandardScaler() df[numeric_cols] = scaler.fit_transform(df[numeric_cols]) > **實務提醒**: > - **不要對分類標籤進行標準化**; > - **在分割訓練/測試集前先 Fit**,避免資訊洩漏。 --- ## 4.3 類別特徵編碼 | 編碼方式 | 適用情境 | 優點 | 缺點 | |----------|----------|------|------| | One‑Hot | 低卡類別 | 易於模型解讀 | 高維度、稀疏 | | Target Encoding | 需保持信息量 | 把類別映射到目標變量的統計量 | 可能引入過擬合、需要交叉驗證 | | Frequency / Count Encoding | 需要保持頻率資訊 | 直接利用頻率 | 無法捕捉類別間關係 | | Embedding | 大卡類別 (如 user_id) | 降維、捕捉關係 | 需要神經網路、複雜度高 | python from sklearn.preprocessing import OneHotEncoder from category_encoders import TargetEncoder # One‑Hot 示例 enc = OneHotEncoder(handle_unknown='ignore', sparse=False) encoded = enc.fit_transform(df[['category_col']]) encoded_df = pd.DataFrame(encoded, columns=enc.get_feature_names_out(['category_col'])) # Target Encoding 示例 te = TargetEncoder(cols=['category_col']) df['category_target_enc'] = te.fit_transform(df['category_col'], df['target']) > **技巧**: > - **對頻繁出現的類別做 One‑Hot**,對稀疏類別可合併為 `Other` 再做 Target Encoding; > - **使用交叉驗證**,避免 Target Encoding 的「泄露」現象。 --- ## 4.4 特徵擴充 | 擴充方法 | 範例 | |----------|------| | Polynomial Features | `sklearn.preprocessing.PolynomialFeatures(degree=2, include_bias=False)` | | Interaction Terms | `df['age_income'] = df['age'] * df['income']` | | Domain Knowledge | 如電商中的「商品相似度」或「用戶活躍度」指標 | | Text Embedding | `TfidfVectorizer`, `Word2Vec`, `SentenceTransformer` | python from sklearn.preprocessing import PolynomialFeatures poly = PolynomialFeatures(degree=2, include_bias=False) X_poly = poly.fit_transform(df[numeric_cols]) poly_feature_names = poly.get_feature_names_out(numeric_cols) X_poly_df = pd.DataFrame(X_poly, columns=poly_feature_names) > **注意**:特徵擴充會顯著增大維度,須配合特徵選擇或降維處理。 --- ## 4.5 特徵選擇(Feature Selection) | 類型 | 方法 | 何時使用 | |------|------|-----------| | **Filter** | *ANOVA F‑test*, *Chi‑Squared*, *Mutual Information* | 先行快速篩選,適用大資料量 | | **Wrapper** | Recursive Feature Elimination (RFE), Sequential Feature Selection | 需評估模型性能,計算成本高 | | **Embedded** | L1 正則化 (Lasso), Tree‑based importance | 與模型訓練同時進行,效果好 | python from sklearn.feature_selection import SelectKBest, chi2 from sklearn.linear_model import LogisticRegression # Filter 範例 selector = SelectKBest(score_func=chi2, k=20) X_new = selector.fit_transform(X, y) # Embedded 範例 clf = LogisticRegression(penalty='l1', solver='saga', max_iter=5000) clf.fit(X, y) importances = clf.coef_[0] > **最佳實務**:先用 Filter 進行粗篩,再用 Wrapper/Embedded 做細調。 --- ## 4.6 主成分分析(PCA)與線性降維 ### 4.6.1 原理 PCA 透過特徵值分解將資料投影到「方差最大」的正交方向,形成新的「主成分」。 ### 4.6.2 使用場景 - **資料維度過高**(>50) - **視覺化**:將 3D+ 資料降至 2D 或 3D 觀察聚類 - **噪音抑制**:低方差主成分往往是噪音 ### 4.6.3 實作範例 python from sklearn.decomposition import PCA pca = PCA(n_components=0.95) # 取保留 95% 方差 X_pca = pca.fit_transform(X_scaled) print(f'降維後維度: {X_pca.shape[1]}') > **技巧**: > - 在 `PCA` 前一定要 **標準化**,因為主成分依賴於特徵尺度; > - `n_components` 可設定為數值或百分比。 --- ## 4.7 t‑SNE 與 UMAP(非線性降維) ### 4.7.1 t‑SNE - **用途**:高維資料可視化,保持局部結構; - **缺點**:計算量大、參數敏感、難以擴展。 python from sklearn.manifold import TSNE tsne = TSNE(n_components=2, perplexity=30, learning_rate=200) X_tsne = tsne.fit_transform(X_scaled) ### 4.7.2 UMAP - **相較於 t‑SNE**:速度快、保留全局結構、可直接用於聚類。 python import umap umap_2d = umap.UMAP(n_components=2, n_neighbors=15, min_dist=0.1) X_umap = umap_2d.fit_transform(X_scaled) > **實務建議**: > - **先做 PCA**(n_components≈50)再進行 t‑SNE/UMAP,減少計算量; > - 用於 **資料探索**、**聚類預處理** 或 **特徵投影**。 --- ## 4.8 綜合實務案例:金融風控模型的特徵工程流程 1. **資料結合**:從交易、客戶基本資料、信用報告合併; 2. **數值特徵處理**:填補缺失、標準化; 3. **類別特徵編碼**:信用卡類別使用 Target Encoding; 4. **特徵擴充**:計算「月均交易額 / 信用額」等衍生特徵; 5. **特徵選擇**:使用 `SelectKBest` + `XGBoost` 內建重要性; 6. **降維**:使用 UMAP 生成 10 维嵌入作為「信用行為指標」; 7. **模型訓練**:XGBoost / LightGBM; 8. **驗證**:使用 `f1` 作為評估指標,採用 `StratifiedKFold`; 9. **部署**:將模型封裝為 REST API,並監控特徵漂移。 > **關鍵成功因素**: > - **特徵與業務邏輯對齊**; > - **資料品質管理**(缺失值、異常檢測)是基礎; > - **持續迭代**:特徵重要性隨時間變化,需定期檢討。 --- ## 4.9 小結 1. **特徵工程是門「數學+藝術」**:需要統計、機器學習知識,亦需業務洞察。 2. **編碼方法多樣**,選擇需考慮特徵類別數、模型類型與可解釋性。 3. **特徵擴充** 可以提升模型表現,但要注意「維度災難」。 4. **特徵選擇與降維** 是降低計算成本與防止過擬合的重要工具。 5. **實務流程** 要重視資料品質、交叉驗證與可解釋性,才能把模型落地並持續維護。 > **一句話提醒**:一份優秀的特徵集,往往比複雜模型更能帶來商業價值。透過嚴謹的特徵設計與評估,才能在變化多端的資料環境中穩定發揮。 ---