返回目錄
A
資料科學實務:從數據洞察到決策行動 - 第 3 章
第三章:資料清理與前處理
發布於 2026-03-05 13:07
# 第三章:資料清理與前處理
資料科學的核心在於「資料能否被信賴」——沒有乾淨、結構化、可衡量的資料,模型永遠是盲目的。本章將從缺失值處理、異常偵測、特徵工程、標準化技巧四大面向,帶領讀者學習如何將雜亂無章的原始資料轉化為可直接輸入模型的乾淨資料。
## 3.1 缺失值處理
### 3.1.1 缺失值的來源與影響
| 來源 | 典型案例 | 影響 |
|------|----------|------|
| 資料錄入錯誤 | 鑑別欄位輸入空白 | 減少樣本數、偏差 |
| 系統同步遺漏 | API 回傳部分字段 | 資料不完整 |
| 隨機取樣 | 調查問卷非答 | 造成資料不平衡 |
缺失值若不處理,常見影響包括:
- **模型訓練失效**:大多數 ML 演算法無法直接處理 NaN。
- **統計偏差**:隨機缺失 vs 非隨機缺失會引入偏誤。
- **決策錯誤**:決策層根據不完整資料作業,導致策略失誤。
### 3.1.2 處理策略
| 策略 | 適用情境 | 優缺點 |
|------|----------|--------|
| **刪除** | 缺失比例低且隨機 | 簡單;可能損失重要樣本 |
| **填補(統計)** | 數值欄位、缺失少量 | 低成本;可能縮小變異 |
| **填補(前向/後向)** | 時序資料 | 保留趨勢;忽略季節性 |
| **插值** | 時序連續資料 | 連續平滑;假設線性 |
| **預測填補** | 重要欄位、缺失高 | 高準確度;計算量大 |
#### 例子:Python 版缺失值填補
python
import pandas as pd
from sklearn.impute import SimpleImputer
# 讀取資料
train = pd.read_csv('train.csv')
# 1. 數值欄位填補
num_cols = ['age', 'income']
imp_mean = SimpleImputer(strategy='mean')
train[num_cols] = imp_mean.fit_transform(train[num_cols])
# 2. 類別欄位填補
cat_cols = ['gender', 'region']
imp_mode = SimpleImputer(strategy='most_frequent')
train[cat_cols] = imp_mode.fit_transform(train[cat_cols])
> **實務提示**:在填補前先做缺失率分析,若某欄位缺失率>50%,通常不宜保留。
## 3.2 異常偵測
### 3.2.1 異常定義
- **統計異常**:遠離中心統計量的數值。
- **空間異常**:在資料空間中孤立的點。
- **時序異常**:時間序列中突變或跳躍。
### 3.2.2 常用方法
| 方法 | 概念 | 典型應用 |
|------|------|----------|
| **Z-score** | 標準化後遠離均值的點 | 金融風險、工廠異常 |
| **IQR(Tukey)** | 1.5×IQR 外的點 | 零售數據異常 |
| **DBSCAN** | 基於密度的聚類 | 空間點雜訊 |
| **Isolation Forest** | 隨機樹切割原理 | 大規模異常檢測 |
| **LOF (Local Outlier Factor)** | 局部密度差異 | 異常資料點 |
#### 例子:使用 Isolation Forest
python
from sklearn.ensemble import IsolationForest
X = train[['age', 'income', 'purchase_amount']]
iso = IsolationForest(contamination=0.01, random_state=42)
train['anomaly'] = iso.fit_predict(X)
# -1 表示異常,1 表示正常
### 3.2.3 異常處理
- **剔除**:若異常數量少,直接刪除。
- **修正**:用鄰近點或平均值替換。
- **標記**:將異常標籤加入特徵,讓模型學習。
## 3.3 特徵工程
### 3.3.1 特徵創建
| 類型 | 例子 |
|------|------|
| **組合特徵** | `total_spend = purchase_amount * quantity` |
| **時間特徵** | `hour_of_day`, `day_of_week` |
| **文本特徵** | `tf-idf` 於評論文字 |
| **相對特徵** | `spend_rank = pd.rank(method='first')` |
### 3.3.2 類別編碼
| 編碼方式 | 典型情境 |
|----------|----------|
| **One-Hot** | 無序類別、模型不敏感 |
| **Target Encoding** | 類別與目標有強相關 |
| **Ordinal** | 自然序列(如教育程度) |
| **Frequency** | 低頻類別合併 |
#### 例子:ColumnTransformer 與 OneHotEncoding
python
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import OneHotEncoder
cat_cols = ['gender', 'region']
num_cols = ['age', 'income']
preprocess = ColumnTransformer(
transformers=[
('cat', OneHotEncoder(handle_unknown='ignore'), cat_cols),
('num', 'passthrough', num_cols)
]
)
X_pre = preprocess.fit_transform(train)
### 3.3.3 特徵選擇
| 方法 | 優缺點 |
|------|--------|
| **Filter** | 快速;不考慮模型 | 過度簡化 |
| **Wrapper** | 考慮模型;計算量大 | 過擬合風險 |
| **Embedded** | 與模型結合 | 需選擇合適模型 |
> **最佳實踐**:先使用 Filter 進行粗篩,然後再進行 Wrapper 或 Embedded 精選。
## 3.4 標準化與正規化技巧
| 技術 | 何時使用 | 典型工具 |
|------|----------|----------|
| **Min-Max Scaling** | 需要 0-1 範圍 | `MinMaxScaler` |
| **Standard Scaling** | 正態分布、機器學習模型 | `StandardScaler` |
| **Robust Scaling** | 離群值多 | `RobustScaler` |
| **Log / Box-Cox** | 右偏分布 | `np.log1p`, `scipy.stats.boxcox` |
#### 例子:RobustScaler + Log 轉換
python
from sklearn.preprocessing import RobustScaler
X = train[['purchase_amount']]
X_log = np.log1p(X)
scaler = RobustScaler()
X_scaled = scaler.fit_transform(X_log)
## 3.5 Pipeline 與可重複性
### 3.5.1 sklearn Pipeline
python
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.compose import ColumnTransformer
from sklearn.ensemble import RandomForestRegressor
pipeline = Pipeline([
('preprocess', preprocess),
('model', RandomForestRegressor(n_estimators=200, random_state=42))
])
pipeline.fit(X_train, y_train)
### 3.5.2 版本控制與實驗管理
- **MLflow**:追蹤實驗、模型、參數。
- **DVC**:資料版本控制,確保可重複。
## 3.6 資料治理與品質檢核
| 檢核指標 | 目標 | 工具 |
|----------|------|------|
| **完整度** | 100% | Great Expectations、DataProfiler |
| **一致性** | 同一欄位類型、範圍 | Data Quality Dashboard |
| **準確度** | 與真實值對照 | 監控腳本、單元測試 |
| **時效性** | 低延遲 | Data Pipeline 監控 |
### 例子:Great Expectations
python
import great_expectations as ge
ge_data = ge.from_pandas(train)
ge_data.expect_column_values_to_not_be_null('age')
ge_data.expect_column_mean_to_be_between('income', 30000, 100000)
results = ge_data.validate()
print(results)
## 3.7 實務案例:零售商客戶資料清理
| 步驟 | 目標 | 具體操作 |
|------|------|----------|
| 1. 資料抓取 | 取回 CRM、POS、網站行為 | ETL 或 API 連接 |
| 2. 缺失處理 | 保障客戶資料完整 | `SimpleImputer` + 前向填補 |
| 3. 異常偵測 | 排除誤差訂單 | `IsolationForest` |
| 4. 特徵工程 | 製造客戶活躍度指標 | `purchase_freq`, `recency` |
| 5. 編碼與標準化 | 準備模型 | One-Hot + StandardScaler |
| 6. Pipeline 測試 | 確保流程可重複 | `Pipeline` + MLflow |
> **結果**:資料完整度從 85% 提升至 99%,異常比例下降 60%,模型準確度提升 8%。
## 小結
資料清理與前處理是資料科學管線中最具挑戰與價值的階段。透過系統化的方法:先了解資料本身的缺失與異常,再運用適合的統計與機器學習工具進行處理;接著,結合特徵工程與標準化技巧,將原始資料轉化為「模型可食用」的特徵;最後,將整個流程打包成 Pipeline,並以資料治理工具確保可追溯、可重複。正是這一系列的「乾淨」工作,才能為後續模型、洞察與決策提供堅實基礎。