返回目錄
A
從資料到決策:系統化資料科學實踐手冊 - 第 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. **實務流程** 要重視資料品質、交叉驗證與可解釋性,才能把模型落地並持續維護。
> **一句話提醒**:一份優秀的特徵集,往往比複雜模型更能帶來商業價值。透過嚴謹的特徵設計與評估,才能在變化多端的資料環境中穩定發揮。
---