返回目錄
A
數據驅動決策:從原始資料到洞察的全流程 - 第 5 章
5. 特徵工程(Feature Engineering)
發布於 2026-02-22 14:26
# 5. 特徵工程(Feature Engineering)
> **「特徵」是模型的「血液」**:在資料科學裡,資料本身是脈搏,特徵是血管。若血管不夠靈活,血液無法順暢流動,模型就難以發揮潛能。
## 5.1 為什麼特徵工程如此重要
在第4章「探索性資料分析(EDA)」中,我們已經知道了資料的分布、缺失情形、類別比例等基本情況。這些洞見是特徵工程的地圖:
- **缺失值** 可能需要填補或創造「缺失指標」
- **類別數量** 若過多,需考慮編碼方式或降維
- **時間序列** 可拆解為「年、月、日」或「工作日」等
- **離群值** 可轉換為「離群指標」或做對數變換
把這些觀察轉化為具體特徵,能直接提升模型解釋力與預測精度。
## 5.2 典型特徵工程流程
> **步驟 1️⃣:資料整合**
> - 合併來源表
> - 轉換資料型別
> **步驟 2️⃣:缺失值處理**
> - 用統計量填補(均值、中位數、眾數)
> - 建立「是否缺失」指標
> **步驟 3️⃣:類別編碼**
> - **Label Encoding**:對有序類別
> - **One‑Hot Encoding**:對無序類別,使用 `pd.get_dummies` 或 `sklearn.preprocessing.OneHotEncoder`
> - **Target Encoding**:對高頻類別,利用目標變量資訊
> **步驟 4️⃣:數值變換**
> - **標準化**(StandardScaler)
> - **正規化**(MinMaxScaler)
> - **對數/平方根**:處理偏態分布
> **步驟 5️⃣:衍生特徵**
> - 日期拆分:年、月、日、工作日、季節
> - 交互特徵:`Feature_A * Feature_B`
> - 多項式特徵:`PolynomialFeatures(degree=2)`
> - 文本特徵:TF‑IDF、word2vec、BERT 向量
> **步驟 6️⃣:特徵篩選**
> - 相關係數閾值(|corr|>0.95 刪除)
> - 單變量檢定(ANOVA、卡方)
> - 模型內部重要性(RandomForest、XGBoost)
> - 主成分分析(PCA)
> **步驟 7️⃣:特徵組合 & 優化**
> - `featuretools` 的 Deep Feature Synthesis
> - 自動特徵生成(AutoFeat, H2O AutoML)
> **步驟 8️⃣:版本管理**
> - 使用 `dvc` 或 `mlflow` 保存特徵表的版本
## 5.3 案例:線上零售交易預測
以下示範如何從 EDA 到特徵工程,最後輸出供模型訓練的特徵表。
python
import pandas as pd
import numpy as np
from sklearn.preprocessing import OneHotEncoder, StandardScaler
from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline
# 讀取原始資料
df = pd.read_csv('online_sales_raw.csv')
# 1️⃣ 日期特徵拆分
df['order_date'] = pd.to_datetime(df['order_date'])
for col in ['year', 'month', 'day', 'weekday']:
df[col] = df['order_date'].dt.__getattribute__(col)
# 2️⃣ 缺失處理
for col in ['payment_method']:
df[col].fillna('Unknown', inplace=True)
# 3️⃣ 類別編碼
cat_cols = ['payment_method', 'product_category']
num_cols = ['order_amount', 'customer_age']
preprocessor = ColumnTransformer(
transformers=[
('cat', OneHotEncoder(handle_unknown='ignore'), cat_cols),
('num', StandardScaler(), num_cols)
])
X = df.drop(columns=['order_id', 'order_date', 'label'])
y = df['label'] # 目標變數:是否完成付款
X_preprocessed = preprocessor.fit_transform(X)
# 4️⃣ 儲存特徵表
X_processed = pd.DataFrame(X_preprocessed.toarray(),
columns=preprocessor.get_feature_names_out())
X_processed.to_csv('online_sales_features.csv', index=False)
> **注意**:在實務上,建議使用 `Pipeline` 將特徵工程流程封裝,確保測試集與訓練集處理一致。
## 5.4 常見陷阱與對策
| 陷阱 | 原因 | 對策 |
|------|------|------|
| **漏擴編碼** | 只在訓練集生成類別編碼,測試集含未知類別 | `OneHotEncoder(handle_unknown='ignore')` 或 `sklearn.preprocessing.OrdinalEncoder` |
| **數值尺度不一致** | 影響梯度下降 | 使用標準化 / 正規化 |
| **高維稀疏矩陣** | 計算成本高、模型過擬合 | 檢查類別頻率,採用 `drop='first'` 或 `freq_weight` |
| **缺失指標誤用** | 直接使用缺失值作為特徵 | 檢查缺失與目標變數關聯,避免「缺失指標漂移」 |
| **特徵衍生過度** | 產生大量冗餘特徵 | 交叉驗證特徵重要性,使用 L1 正則化或模型重要性 |
## 5.5 數據治理與倫理
- **隱私保護**:在衍生個人特徵時,遵守 GDPR、個資法等規範。
- **公平性檢查**:特徵工程不應強化性別、族群偏見,使用 `fairlearn` 進行評估。
- **可解釋性**:保持「特徵可追溯」:每一特徵都要能回溯到原始資料,方便審計。
## 5.6 小結
特徵工程是資料科學的「翻譯工作」——把原始資料的語言,轉換成模型可理解的「符號」。好的特徵能讓模型快速收斂、提升表現;糟糕的特徵則可能讓即使最先進的模型也無法發揮。從 EDA 洞見出發,結合實務工具與規範流程,你已準備好在下個章節「機器學習模型」中,將這些特徵投入模型,邁向更高準確度與更可信的決策。