返回目錄
A
資料科學實務與方法:從理論到應用 - 第 3 章
第 3 章 資料前處理與特徵工程
發布於 2026-03-04 02:39
# 第 3 章 資料前處理與特徵工程
資料科學的「資料前處理」常被誤解為「雜事」。實際上,它是模型性能的基石,若處理不當,即使再先進的演算法也會失靈。這一章將從實務出發,拆解前處理與特徵工程的關鍵步驟,並以信用卡詐騙偵測為例,展示如何將理論落地。
## 3.1 資料清洗:把亂數剃掉
> **「清潔」的資料就像乾淨的水,沒有雜質才能流通。**
### 3.1.1 資料缺失檢測
python
import pandas as pd
df = pd.read_csv('credit_card_fraud.csv')
print(df.isnull().mean()) # 每欄缺失比例
- **規則性缺失**:若缺失值隨時間分布,可視化時使用熱力圖。
- **隨機缺失**:可採用均值/中位數/眾數填補。
- **系統性缺失**:若缺失與某個類別高度相關,建議建模時加上缺失指標。
### 3.1.2 重複值處理
python
# 只保留第一筆重複
unique_df = df.drop_duplicates(subset=['TransactionID'], keep='first')
- 大多數情況下,重複代表交易被重複記錄,須刪除或合併。
- 若重複出現在不同時間戳,可能代表異步交易,需進一步調查。
## 3.2 資料類型轉換:把字串變成數字
在機器學習管線中,非數值型資料必須轉換為模型可接受的形式。
- **類別型資料**:`pd.get_dummies()` 或 `LabelEncoder`。
- **日期時間型**:分解為年、月、日、星期、時間段。
- **文本型**:TF‑IDF、Word2Vec 或 BERT 嵌入。
python
# 日期時間拆解示例
unique_df['TransactionDate'] = pd.to_datetime(unique_df['TransactionDate'])
unique_df['Year'] = unique_df['TransactionDate'].dt.year
unique_df['Month'] = unique_df['TransactionDate'].dt.month
unique_df['Day'] = unique_df['TransactionDate'].dt.day
unique_df['Weekday'] = unique_df['TransactionDate'].dt.weekday
## 3.3 欠缺值處理策略
> **「填補」不是「填坑」**。填補要根據資料分布與業務邏輯決定。
| 欠缺類型 | 常用方法 | 適用情境 |
|---|---|---|
| 連續變數 | 均值 / 中位數 | 變數分布對稱 |
| 連續變數 | KNN/多元插補 | 資料不對稱或缺失模式複雜 |
| 類別變數 | 最頻類別 | 稀疏類別 |
| 時間序列 | 前向填補 / 後向填補 | 有序時間數據 |
> **實務提醒**:在測試集上絕不能使用訓練集統計量,避免數據泄露。
## 3.4 標準化與正規化
模型對特徵尺度敏感,特別是距離度量或正則化項。
- **標準化(StandardScaler)**:`(x - μ)/σ`
- **正規化(MinMaxScaler)**:`(x - min)/(max - min)`
- **Log/Box‑Cox**:處理偏態分布。
python
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
scaled_features = scaler.fit_transform(df[['TransactionAmount', 'AccountBalance']])
## 3.5 特徵選擇與降維
### 3.5.1 相關性矩陣
python
import seaborn as sns
corr = df.corr()
sns.heatmap(corr, cmap='coolwarm')
- 排除高度共線的特徵,避免模型過度擬合。
### 3.5.2 重要性評估
- **樹模型**(XGBoost、RandomForest):輸出特徵重要性。
- **正則化**(L1):自動稀疏化。
- **PCA / tSNE**:資料可視化與降維。
python
from sklearn.decomposition import PCA
pca = PCA(n_components=0.95) # 保留 95% 方差
pca_features = pca.fit_transform(scaled_features)
## 3.6 實戰案例:信用卡詐騙偵測
### 3.6.1 資料概覽
| 欄位 | 類型 | 代表意義 |
|---|---|---|
| TransactionID | 數字 | 交易編號 |
| TransactionAmount | 數字 | 交易金額 |
| TransactionDate | 時間 | 交易時間 |
| MerchantID | 數字 | 商戶編號 |
| CardHolderID | 數字 | 卡持有人 |
| IsFraud | 0/1 | 詐騙標籤 |
### 3.6.2 前處理流程
1. **缺失值**:TransactionAmount 2% 欠缺,用中位數填補。
2. **重複值**:TransactionID 重複 0.1%,剔除。
3. **類別編碼**:MerchantID、CardHolderID 使用 `TargetEncoder`(因為數量龐大)。
4. **日期拆解**:提取星期、月份、交易時段。
5. **標準化**:對 TransactionAmount 進行 Log 轉換後標準化。
6. **特徵擴充**:計算每位持卡人每月交易次數與平均金額,作為新特徵。
### 3.6.3 重要性示例
python
import xgboost as xgb
model = xgb.XGBClassifier()
model.fit(X_train, y_train)
importances = model.feature_importances_
feat_importance = pd.Series(importances, index=X_train.columns).sort_values(ascending=False)
print(feat_importance.head(10))
> **結果**:TransactionAmount、CardHolderMonthlyAvg、MerchantRiskScore 為最高權重,表明金額與商戶風險是決定因素。
## 3.7 小結
- **前處理**不是「花時間」的瑣事,而是**模型成功的基礎**。
- **選擇合適的策略**(填補、編碼、縮放)需結合資料特性與業務目標。
- **特徵工程**是對業務知識的數據化表達,良好的特徵能大幅提升模型效能。
> **練習題**:使用 Kaggle 上的「信用卡詐騙」資料集,嘗試自行設計至少 5 個新特徵,並測試其對 F1‑score 的影響。