聊天視窗

數據驅動決策:實務分析師的數據科學指南 - 第 3 章

第三章:資料清理與預處理

發布於 2026-03-02 19:11

# 第三章:資料清理與預處理 > 在任何數據科學專案中,資料清理(Data Cleaning)與預處理(Data Pre‑processing)是決定模型效能與決策可靠性的關鍵環節。這一章將系統說明缺失值處理、異常檢測以及特徵工程的基礎概念、方法與實務技巧,並提供可直接落地的程式碼範例。 --- ## 1. 缺失值處理 ### 1.1 為何缺失值重要 | 缺失類型 | 典型來源 | 可能影響 | |----------|----------|----------| | **整體缺失**(Missing Completely at Random, MCAR) | 隨機刪除、系統失效 | 估計偏差可忽略 | | **條件缺失**(Missing at Random, MAR) | 問卷非回覆、傳感器失靈 | 需依其他變數補估 | | **非隨機缺失**(Missing Not at Random, MNAR) | 敏感數據不報、商業機密 | 需要特別建模 | > **小提示**:在實務中,先用資料探勘工具(如 Pandas Profiling、Sweetviz)快速可視化缺失結構,幫助決策。 ### 1.2 補值策略 | 方式 | 適用情況 | Python 範例 | |------|----------|-------------| | **刪除**(Drop) | 變數缺失比例極低 (<5%) | `df.dropna(subset=['col'])` | | **均值/中位數/眾數** | 連續數據、單一列缺失 | `df['col'].fillna(df['col'].median(), inplace=True)` | | **前向/後向填充** | 時間序列、缺失連續段 | `df['col'].fillna(method='ffill')` | | **插值**(Interpolation) | 時間序列、平滑需求 | `df['col'].interpolate(method='time')` | | **KNN 補值** | 多維度關聯 | `from sklearn.impute import KNNImputer imp = KNNImputer(n_neighbors=5) df_imp = imp.fit_transform(df)` | | **多重插補 (MICE)** | 複雜缺失模式 | `from sklearn.experimental import enable_iterative_imputer from sklearn.impute import IterativeImputer imp = IterativeImputer() df_imp = imp.fit_transform(df)` | > **實務提示**:若資料量大且缺失分佈複雜,建議先做 **特徵分群**,在各群內使用 KNN 或 MICE 進行補值,避免跨群不合理的補值。 ### 1.3 補值流程建議 1. **資料檢測**:用 `df.isnull().sum()` 或 `df.isnull().mean()` 查看缺失比例。 2. **分類缺失類型**:根據業務背景判斷 MCAR/MAR/MNAR。 3. **選擇方法**:依缺失比例、資料類型、業務影響決定。 4. **實施補值**:寫成函式或使用 `Pipeline`,保持可重用。 5. **驗證**:補值後再次統計,確保缺失被處理且數值分佈未被扭曲。 --- ## 2. 異常檢測 ### 2.1 異常定義 > **異常(Outlier)**:在統計分布或機器學習模型中,與大多數樣本顯著不同的觀測值。異常既可能是測量錯誤,也可能是新現象(如詐騙、產品缺陷)。 ### 2.2 檢測方法 | 方法 | 優點 | 局限 | 典型工具 | |------|------|------|----------| | **統計門檻**(IQR, Z‑score) | 簡單、直觀 | 受分佈影響、無法處理多變量 | `scipy.stats`, `numpy` | | **聚類基礎**(DBSCAN) | 可發現任意形狀群 | 參數敏感、計算成本 | `scikit‑learn` | | **Isolation Forest** | 針對高維資料設計 | 需要較多樣本 | `scikit‑learn` | | **局部離群因子(LOF)** | 考慮鄰域密度 | 參數敏感、計算量大 | `scikit‑learn` | | **貝葉斯方法**(Gaussian Mixture) | 可估計多峰分佈 | 需要假設分佈 | `scikit‑learn` | ### 2.3 範例:使用 Isolation Forest python import pandas as pd from sklearn.ensemble import IsolationForest # 假設 df 為數值型資料 model = IsolationForest(contamination=0.05, random_state=42) # 建模 outlier_labels = model.fit_predict(df) # -1 表示異常,1 表示正常 df['outlier'] = outlier_labels # 篩選異常 outliers = df[df['outlier'] == -1] print(f"偵測到 {len(outliers)} 個異常樣本") ### 2.4 實務操作 1. **視覺化先行**:利用箱型圖、散點圖確認異常模式。 2. **多層檢測**:先用統計門檻做粗篩,再用機器學習做細緻辨識。 3. **業務驗證**:將偵測結果交由領域專家審核,確認異常是否真實缺陷。 4. **處理決策**:異常可選擇刪除、修正、或保留並加權處理。 --- ## 3. 特徵工程基礎 ### 3.1 為何特徵工程重要 > 特徵是模型學習的語言,優質的特徵能顯著提升模型準確度、縮短收斂時間,並降低過擬合風險。 ### 3.2 主要技術 | 技術 | 目的 | 範例 | |------|------|------| | **標準化 / 正規化**(StandardScaler, MinMaxScaler) | 消除量級差異 | `StandardScaler()` | | **類別編碼**(One-Hot, Ordinal, Target Encoding) | 讓模型處理非數值類別 | `pd.get_dummies()` | | **交互特徵**(PolynomialFeatures) | 捕捉變數之間非線性關係 | `PolynomialFeatures(degree=2)` | | **降維**(PCA, t-SNE, UMAP) | 減少維度、去除噪聲 | `PCA(n_components=5)` | | **時間特徵擷取**(Year, Month, Day, DayOfWeek, IsWeekend) | 捕捉季節性 | `df['month'] = df['date'].dt.month` | | **文字向量化**(TF‑IDF, Word2Vec, Sentence‑BERT) | 將文本轉為數值 | `TfidfVectorizer()` | | **缺失值特徵** | 讓模型利用缺失資訊 | `df['col_missing'] = df['col'].isnull().astype(int)` | ### 3.3 實戰範例:處理顧客資料集 python import pandas as pd from sklearn.preprocessing import StandardScaler, OneHotEncoder from sklearn.compose import ColumnTransformer from sklearn.pipeline import Pipeline # 假設 df 內含 numeric, categorical, datetime 欄位 numeric_features = ['age', 'income', 'score'] categorical_features = ['gender', 'region'] datetime_features = ['signup_date'] # 1. 處理 datetime def datetime_transformer(df): df['signup_month'] = df['signup_date'].dt.month df['signup_weekday'] = df['signup_date'].dt.weekday return df.drop(columns=['signup_date']) # 2. 建立 ColumnTransformer preprocess = ColumnTransformer( transformers=[ ('num', StandardScaler(), numeric_features), ('cat', OneHotEncoder(handle_unknown='ignore'), categorical_features), ], remainder='passthrough' ) # 3. 組合 Pipeline pipe = Pipeline( steps=[ ('datetime', FunctionTransformer(datetime_transformer)), ('preprocess', preprocess), ] ) X_processed = pipe.fit_transform(df) print(X_processed.shape) > **提示**:在大型資料集中,建議將 Pipeline 轉存為 `pickle` 或 `joblib`,確保版本一致與重現性。 ### 3.4 特徵選擇與評估 | 方法 | 說明 | |------|------| | **基於模型的重要性**(RandomForest, XGBoost) | 直接回傳 feature importance | | **L1 正則化(Lasso)** | 把係數稀疏化,隱式選擇特徵 | | **Recursive Feature Elimination (RFE)** | 迭代移除不重要特徵 | | **資訊增益 / 卡方檢定** | 評估類別特徵與目標的相關度 | > 透過交叉驗證與目標評估(如 AUC、RMSE)確認特徵選擇的實際效益。 --- ## 4. 綜合工作流與最佳實踐 | 步驟 | 目標 | 工具 / 版型 | |------|------|--------------| | **資料探勘** | 確認數據質量、缺失、異常 | `pandas_profiling`, `sweetviz`, `dataprep` | | **清理 & 補值** | 去除雜訊、填補缺失 | `pandas`, `scikit‑learn`, `PySpark` | | **特徵工程** | 創造、轉換特徵 | `Pipeline`, `Featuretools`, `scikit‑feature` | | **版本控制** | 保持 reproducibility | Git, DVC, MLflow Artifact Store | | **測試** | 確保流程正確性 | `Great Expectations`, `pytest` | | **自動化** | 週期性運行 | Airflow, Prefect, Dagster | > **結語**:資料清理與預處理不僅是「把資料搞乾淨」的工作,更是一場持續的品質管理與探索性實驗。建議把清理流程視為「資料治理 pipeline」的一部分,持續監控資料品質,並以可重複、可測試的方式交付給後續建模團隊。 --- > **實務提醒**:在高頻更新的商業資料(如交易日誌、網站日志)中,盡量使用**增量清理**(只處理新到資料),並在資料管道中加入**資料品質監控**(例如每日自動報告缺失比例、異常數量),確保資料湖或資料倉庫的即時性與可靠性。