聊天視窗

數據科學實務:從數據蒐集到模型部署的完整流程 - 第 4 章

第 4 章 探索性資料分析(EDA)與特徵工程

發布於 2026-02-22 18:46

# 第 4 章 探索性資料分析(EDA)與特徵工程 ## 4.1 為什麼 EDA 重要 - **數據品質檢驗**:在進行建模之前,先確保資料沒有遺漏值、重複、格式錯誤等問題。若不先處理,模型往往會被噪音擾亂。 - **洞察發現**:EDA 讓你快速把握資料的分佈、相關性、潛在異常,這些洞察常能驅動特徵設計。 - **特徵工程方向**:透過統計檢驗和可視化,你可以判斷哪些變數值得進一步轉換、合併或刪除。 ## 4.2 基礎工具與環境 | 主要工具 | 作用 | |---|---| | Pandas | 資料處理、缺失值填補、分組統計 | | NumPy | 數值運算、向量化操作 | | Matplotlib | 低階可視化、圖形調整 | | Seaborn | 高階統計可視化、預設美化 | | Scikit‑learn | 內建資料前處理工具、特徵選擇 | 安裝建議: bash pip install pandas numpy matplotlib seaborn scikit-learn ## 4.3 資料清理實務 ### 4.3.1 讀取資料 python import pandas as pd df = pd.read_csv('data/titanic.csv') print(df.head()) ### 4.3.2 處理遺漏值 | 方法 | 適用情境 | |---|---| | `dropna()` | 數據量大,遺漏值比例極低 | | `fillna()` | 需要保留行,常用均值/中位數/眾數 | | `IterativeImputer` | 多變數缺失,需考慮互相影響 | 範例:用中位數填補 `Age` 欄位 python median_age = df['Age'].median() df['Age'].fillna(median_age, inplace=True) ### 4.3.3 去除重複 python df.drop_duplicates(inplace=True) ### 4.3.4 轉換資料型別 python df['Cabin'] = df['Cabin'].astype('category') ## 4.4 資料可視化與統計檢驗 ### 4.4.1 分佈視覺化 python import seaborn as sns import matplotlib.pyplot as plt plt.figure(figsize=(8,4)) sns.histplot(df['Age'], bins=30, kde=True) plt.title('Age Distribution') plt.xlabel('Age') plt.ylabel('Count') plt.show() ### 4.4.2 相關性矩陣 python corr = df.corr() plt.figure(figsize=(10,8)) sns.heatmap(corr, annot=True, cmap='coolwarm', fmt='.2f') plt.title('Correlation Matrix') plt.show() ### 4.4.3 盒鬍鬚圖檢測離群值 python plt.figure(figsize=(6,4)) sns.boxplot(x=df['Fare']) plt.title('Fare Boxplot') plt.show() ### 4.4.4 統計檢驗範例 | 測試 | 目的 | 何時使用 | |---|---|---| | t‑test | 比較兩組均值差異是否顯著 | 兩個獨立樣本 | | ANOVA | 多組均值差異 | >2 群組 | | Chi‑square | 分類變數獨立性 | 交叉表 | 範例:獨立樣本 t‑test python from scipy import stats male = df[df['Sex']=='male']['Fare'] female = df[df['Sex']=='female']['Fare'] t_stat, p_val = stats.ttest_ind(male, female) print(f't‑stat={t_stat:.3f}, p={p_val:.3f}') ## 4.5 特徵工程概念 ### 4.5.1 特徵選擇 | 方法 | 優點 | 缺點 | |---|---|---| | Filter(相關係數) | 簡單快速 | 只考慮單變數 | | Wrapper(Recursive Feature Elimination, RFE) | 考慮模型交互 | 計算成本高 | | Embedded(L1 正則化、Tree‑based importance) | 同時進行模型訓練 | 依賴模型類型 | 範例:使用 `SelectKBest` + `f_regression` python from sklearn.feature_selection import SelectKBest, f_regression X = df.drop(columns=['Survived']) y = df['Survived'] selector = SelectKBest(score_func=f_regression, k=5) X_new = selector.fit_transform(X, y) print('Selected feature mask:', selector.get_support()) ### 4.5.2 編碼技巧 | 類型 | 方法 | |---|---| | Binary (True/False) | `df['Sex'].map({'male':0,'female':1})` | | Label | `LabelEncoder()` | 只適合有順序的類別 | | One‑Hot | `pd.get_dummies()` | 可能造成維度爆炸 | | Target / Mean Encoding | 把類別轉成目標均值 | 需要避免資訊洩漏 | | Frequency Encoding | 轉成類別出現頻率 | 只適合高 cardinality | 範例:One‑Hot + Frequency python # One‑Hot sex_ohe = pd.get_dummies(df['Sex'], prefix='Sex', drop_first=True) # Frequency Encoding freq = df.groupby('Embarked')['Survived'].mean() df['Embarked_freq'] = df['Embarked'].map(freq) ### 4.5.3 特徵縮放 | 方法 | 適用範例 | |---|---| | StandardScaler | 需要正態分佈假設 | 樹模型不必須 | | MinMaxScaler | 範圍壓縮到 0‑1 | 異常值影響大 | | RobustScaler | 對離群值不敏感 | 中位數基準 | 範例:使用 `RobustScaler` python from sklearn.preprocessing import RobustScaler scaler = RobustScaler() df['Age_scaled'] = scaler.fit_transform(df[['Age']]) ## 4.6 高階特徵 ### 4.6.1 交互特徵 python # 舉例:Age 與 Fare 交互 X['Age_Fare'] = df['Age'] * df['Fare'] ### 4.6.2 時間序列特徵(若有時間戳) | 生成特徵 | 例子 | |---|---| | 年月日 | `datetime.dt.year` | | 時間 | `datetime.dt.hour` | | 工作日/週末 | `datetime.dt.weekday` | ### 4.6.3 多元尺度轉換 | 轉換 | 目的 | |---|---| | Log | 把右偏分佈變成近似正態 | `Fare`, `TotalCharges` | | Box‑Cox | 提升正態性,同時可處理 0 或負值 | `salary` | | PowerTransformer(Yeo‑Johnson) | 處理非正態分佈 | 範例:Log 轉換 python import numpy as np df['Fare_log'] = np.log1p(df['Fare']) ## 4.7 維度縮減 - **PCA**:保持方差比例,適用於連續特徵。 - **t‑SNE / UMAP**:可視化高維資料,發現群聚結構。 範例:PCA python from sklearn.decomposition import PCA pca = PCA(n_components=2) principal = pca.fit_transform(df.select_dtypes(include='number')) print('Explained variance ratio:', pca.explained_variance_ratio_) ## 4.8 EDA 與特徵工程最佳實踐 1. **資料版本控制**:使用 `DVC` 或 Git‑LFS 追蹤原始資料。 2. **自動化 EDA**:寫腳本或 notebook 產生報表,使用 `pandas‑profiling` 或 `sweetviz`。 3. **記錄決策**:在 Jupyter notebook 或 Google Sheet 中記錄為什麼採用某種缺失值填補或編碼方式。 4. **避免資料洩漏**:在填補缺失值或編碼前,先在訓練集與測試集分開處理,或使用 `Pipeline`。 5. **特徵重要性評估**:結合模型(如 RandomForest)或 SHAP 進行解釋,幫助挑選關鍵特徵。 ## 4.9 小結 - EDA 讓資料品質、分佈、相關性等層面可視化,成為特徵工程的基礎。 - 清理流程應包括缺失值處理、重複移除、型別轉換與資料型態統一。 - 可視化工具(hist、heatmap、boxplot、scatter)與統計檢驗(t‑test、ANOVA、Chi‑square)能快速發現結構性問題。 - 特徵工程涵蓋特徵選擇、編碼、縮放、交互與降維,這些技巧將直接影響模型效能與可解釋性。 - 建議將 EDA 步驟寫成腳本或 Jupyter notebook,並加入單元測試與 CI/CD 以保持重現性。 > **實作練習**:以 Titanic 數據為例,完成上述所有 EDA 步驟並將特徵輸出為 `train_X.csv` 與 `train_y.csv`,供後續建模使用。