返回目錄
A
數據驅動決策:實務分析師的數據科學指南 - 第 4 章
第四章:特徵工程與自動化流水線的實戰
發布於 2026-03-02 19:17
# 第四章:特徵工程與自動化流水線的實戰
> **墨羽行**:在上一章,我們把資料從「原始」變成了「乾淨」。接下來,我們要把這個乾淨的資料變成能直接喂給模型的「特徵」——這是數據科學的核心,也是決策支援的關鍵。
## 1. 特徵工程:把資訊轉化成模型可解讀的語言
### 1.1 為什麼特徵工程重要?
- **資料品質的延伸**:即使資料已經清洗,還可能缺乏能讓模型學習的訊息。
- **降低維度、提升效能**:合理的特徵選擇能減少模型訓練時間,降低 overfitting。
- **解釋性與洞察**:特徵工程往往讓模型結果更易解釋,為業務決策提供可操作的洞察。
### 1.2 典型的特徵轉換技巧
| 轉換類型 | 例子 | 實務工具 |
|-----------|------|-----------|
| **數值化** | 標籤編碼、標準化、Box-Cox | `StandardScaler`, `PowerTransformer` |
| **時間序列** | 滑動窗口、滾動統計、週期性分解 | `Rolling`, `Expanding`, `SeasonalDecompose` |
| **文本** | TF‑IDF、word2vec、Doc2Vec | `TfidfVectorizer`, `gensim` |
| **圖形** | 邊特徵、鄰居聚合 | NetworkX, StellarGraph |
| **衍生特徵** | 交互項、非線性項、分箱 | `PolynomialFeatures`, `KBinsDiscretizer` |
> **案例:電商推薦**
>
> 我們有一筆訂單資料,欄位包括「客戶 ID」、「商品 ID」、「訂購時間」、「價格」。
>
> - **時間特徵**:將訂購時間拆分為「年、月、日、星期、時間段」;計算「最近一次購買距離現在的天數」。
> - **衍生特徵**:客戶總購買額、平均單價、購買頻率。
> - **交互特徵**:價格 × 商品類別(捕捉高價商品的偏好)。
>
> 這些特徵在模型中往往比原始欄位能帶來更高的預測準確度。
### 1.3 自動化特徵生成:Featuretools
```python
import featuretools as ft
# 建立實體集
es = ft.EntitySet(id='ecommerce')
# 加入客戶實體
es = es.entity_from_dataframe(
entity_id='customers',
dataframe=customers_df,
index='customer_id'
)
# 加入訂單實體
es = es.entity_from_dataframe(
entity_id='orders',
dataframe=orders_df,
index='order_id',
time_index='order_time'
)
# 設定關聯
es = es.add_relationship(
ft.Relationship(
es['customers']['customer_id'],
es['orders']['customer_id']
)
)
# 自動特徵生成
feature_matrix, feature_defs = ft.dfs(
entityset=es,
target_entity='customers',
max_depth=2
)
```
> **注意**:Featuretools 生成的特徵可能非常豐富,但也容易導致資料洩漏。務必在「訓練集」內部生成特徵,再用於「驗證集」和「測試集」。
## 2. 版本控制:讓特徵工程可重現
### 2.1 Git + Data Version Control (DVC)
- **Git**:儲存程式碼、Notebook、文檔。
- **DVC**:追蹤大型資料檔案、特徵矩陣、模型權重。
```bash
# 初始化 DVC
$ dvc init
# 添加特徵矩陣
$ dvc add features/feature_matrix.csv
# 推送到遠端儲存
$ dvc push
```
> **實務提醒**:將「資料來源」、`feature_engineering.py`、`dvc.yaml` 等放入同一 Git branch,確保每次模型重訓都能回溯到原始特徵。
### 2.2 MLflow Artifact Store
- 將特徵矩陣、模型、實驗參數上傳到 MLflow,方便後續可追溯。
- 版本號與 hash 一致,確保「跑一次模型」與「跑兩週後模型」結果可比對。
```python
import mlflow
with mlflow.start_run():
mlflow.log_artifacts('features/')
mlflow.sklearn.log_model(model, 'model')
```
## 3. 測試:確保特徵不帶入「錯誤訊息」
### 3.1 Great Expectations:資料品質自動驗證
```python
from great_expectations.dataset import PandasDataset
df = PandasDataset(features_df)
df.expect_column_values_to_not_be_null('customer_id')
df.expect_column_values_to_be_in_set(
'category',
['electronics', 'fashion', 'home', 'sports']
)
```
- **優點**:將資料驗證寫成代碼,能在 CI pipeline 自動執行。
- **缺點**:需要維護期待檔(expectation suite),不易隨資料變化自動調整。
### 3.2 單元測試與集成測試
```python
import pytest
from feature_engineering import generate_features
def test_generate_features_output_shape():
df = load_raw_data()
features = generate_features(df)
assert features.shape[1] == expected_feature_count
```
> **建議**:把「特徵生成腳本」打包成函式庫,使用 pytest 自動化驗證,避免「一次改動,另一個模組莫名失效」。
## 4. 自動化:從資料抓取到特徵產生的全流程
### 4.1 Airflow:排程與監控
```python
from airflow import DAG
from airflow.operators.python import PythonOperator
from datetime import datetime
with DAG('feature_pipeline', start_date=datetime(2023,1,1), schedule_interval='@daily') as dag:
t1 = PythonOperator(
task_id='extract_data',
python_callable=extract_data
)
t2 = PythonOperator(
task_id='clean_data',
python_callable=clean_data
)
t3 = PythonOperator(
task_id='generate_features',
python_callable=generate_features
)
t1 >> t2 >> t3
```
> **關鍵**:把所有腳本都封裝成獨立的 Python 模組,Airflow 只負責排程與監控。
### 4.2 Prefect:更輕量級且易於開發
```python
import prefect
from prefect import task, Flow
@task
def extract():
pass
@task
def clean():
pass
@task
def feature():
pass
with Flow('feature_flow') as flow:
data = extract()
cleaned = clean(data)
feat = feature(cleaned)
flow.run()
```
- Prefect 的 Flow 可以在 Jupyter 直接執行,適合開發階段快速迭代。
### 4.3 Dagster:資料驅動型工作流
Dagster 的核心概念是 **Solid**(單元)和 **Pipeline**(流程)。它允許將資料型別明確化,減少「跑不通」的情況。
```python
from dagster import solid, pipeline, execute_pipeline
@solid
def extract(context):
return load_from_db()
@solid
def transform(context, raw):
return clean(raw)
@solid
def featurize(context, cleaned):
return generate_features(cleaned)
@pipeline
def feature_pipeline():
raw = extract()
cleaned = transform(raw)
features = featurize(cleaned)
if __name__ == '__main__':
result = execute_pipeline(feature_pipeline)
```
> **建議**:若團隊規模大、流程複雜,Dagster 能幫你管理依賴與資料流。若需求單純,Airflow 或 Prefect 足夠。
## 5. 小結:把特徵工程做成可重複、可追蹤的流水線
1. **特徵工程** 不是一次性腳本,而是持續改進的過程。使用 `Featuretools`、`scikit-learn` Pipeline 能快速迭代。
2. **版本控制** 需要將程式碼、特徵矩陣、模型全都追蹤。Git + DVC + MLflow 是三位一體的最佳做法。
3. **測試** 用 Great Expectations 檢查資料品質,用 pytest 檢查函式輸出,確保「資料不變」的前提下「邏輯不變」。
4. **自動化** 選擇適合團隊的工具:Airflow 用於排程、Prefect 用於開發快速迭代、Dagster 用於大型、複雜流程。
5. **監控**:在自動化流程中嵌入資料品質報告(缺失率、異常點),確保每一次產出的特徵都符合標準。
> **結語**:特徵工程是「把資料變成知識」的橋樑。把它做成可自動化、可測試、可追蹤的流水線,才能讓決策者真正依賴數據做出科學判斷。下一章,我們將聚焦於**統計建模與機器學習**,探討如何把這些特徵轉化為可執行的預測模型。