聊天視窗

數據科學實戰:從問題到洞見 - 第 5 章

第5章 探索性資料分析(EDA)

發布於 2026-03-05 11:22

# 第5章 探索性資料分析(EDA) > **探索性資料分析(EDA)** 是在任何機器學習項目中不可或缺的階段。它幫助你快速了解資料特性、發現潛在問題、確定特徵關係,並為後續的特徵工程與模型選擇奠定基礎。以下內容將從統計摘要、分布視覺化、相關性矩陣、群聚洞察四個面向,逐步引導你完成完整且可重複的 EDA 流程。 --- ## 5.1 統計摘要 統計摘要提供了對數值特徵的一般性描述,通常包含**均值、標準差、最小值、最大值、四分位數**等指標。對於類別特徵,則以**頻次表**呈現。 | 量化特徵 | 值 | 描述 | 例子 | |---------|-----|------|------| | Min | 0 | 最小值 | 年齡 0 歲 | | 25th Percentile | 18 | 第一四分位 | 年齡 18 歲 | | Median | 35 | 中位數 | 35 歲 | | 75th Percentile | 50 | 第三四分位 | 50 歲 | | Max | 80 | 最大值 | 80 歲 | | Mean | 34.2 | 平均值 | 34.2 歲 | | Std | 9.8 | 標準差 | 9.8 歲 | ### 實作範例 python import pandas as pd import matplotlib.pyplot as plt # 讀取資料 url = 'https://raw.githubusercontent.com/mwaskom/seaborn-data/master/titanic.csv' df = pd.read_csv(url) # 選擇數值列 numeric_cols = df.select_dtypes(include=['number']).columns # 計算摘要統計 summary = df[numeric_cols].describe().T print(summary[['count', 'mean', 'std', 'min', '25%', '50%', '75%', 'max']]) > **實戰提示**:將 `summary` 輸出成 JSON 並註冊到 MLflow Parameters,方便模型訓練時自動拉取統計基線。 ## 5.2 分布視覺化 視覺化是 EDA 的核心工具,能快速揭示分布偏斜、離群值、雙峰等特徵。 ### 1. 直方圖與 KDE python import seaborn as sns plt.figure(figsize=(10, 4)) sns.histplot(df['age'], bins=20, kde=True, color='steelblue') plt.title('Age Distribution') plt.xlabel('Age') plt.ylabel('Count') plt.tight_layout() plt.show() ### 2. 箱型圖(Box Plot) python plt.figure(figsize=(8, 5)) sns.boxplot(x='sex', y='age', data=df, palette='Set2') plt.title('Age by Sex') plt.tight_layout() plt.show() ### 3. 熱度圖(Heatmap)顯示缺失值 python plt.figure(figsize=(12, 6)) sns.heatmap(df.isnull(), cbar=False, yticklabels=False, cmap='viridis') plt.title('Missing Value Heatmap') plt.show() > **最佳實務**: > - **單一變數視覺化**:先查看直方圖 + KDE,然後確認箱型圖。若發現離群值,考慮是否需要處理。 > - **缺失值可視化**:使用熱度圖或 `missingno` 直觀展示缺失分佈,幫助決策缺失處理方式。 > - **可重複性**:將視覺化腳本打包成函式,並在 CI Pipeline 中執行。若圖形與前一次結果差異超過閾值,自動通知開發者。 ## 5.3 相關性矩陣 相關性矩陣揭示特徵之間的線性關係。常用的係數有**皮爾森(Pearson)**、**斯皮爾曼(Spearman)**、**肯德爾(Kendall)**。 python corr_matrix = df[numeric_cols].corr(method='pearson') plt.figure(figsize=(10, 8)) sns.heatmap(corr_matrix, annot=True, fmt='.2f', cmap='coolwarm', vmin=-1, vmax=1) plt.title('Pearson Correlation Matrix') plt.tight_layout() plt.show() ### 重要觀察點 | 觀察 | 意義 | 需注意事項 | |------|------|------------| | 高相關 | 可能存在多重共線性 | 影響模型解釋性,可能需要刪除或合併特徵 | | 負相關 | 反向關係 | 不一定是錯誤,但需確認業務邏輯 | | 低相關 | 可被視為獨立特徵 | 仍可能在非線性模型中貢獻大 | > **實戰提示**:若使用 **非線性模型**(如 XGBoost、CatBoost),相關性矩陣的價值較低,但仍可用於初步過濾無關特徵。 ## 5.4 群聚洞察(Cluster Analysis) 在沒有明確目標變數時,**聚類**可以揭示資料內在結構,協助資料切分或發現異常。 ### 1. K‑Means 聚類示例 python from sklearn.preprocessing import StandardScaler from sklearn.cluster import KMeans # 選取關鍵特徵 features = df[['age', 'fare']].dropna() # 標準化 scaler = StandardScaler() scaled = scaler.fit_transform(features) # 估算最佳 K 值(Elbow Method) inertia = [] for k in range(1, 11): kmeans = KMeans(n_clusters=k, random_state=42) kmeans.fit(scaled) inertia.append(kmeans.inertia_) plt.figure(figsize=(8,4)) plt.plot(range(1, 11), inertia, marker='o') plt.xlabel('Number of clusters (k)') plt.ylabel('Inertia') plt.title('Elbow Method for K‑Means') plt.show() ### 2. 以最佳 k 進行聚類並可視化 python k_opt = 4 kmeans = KMeans(n_clusters=k_opt, random_state=42) cluster_labels = kmeans.fit_predict(scaled) plt.figure(figsize=(8,5)) sns.scatterplot(x=features['age'], y=features['fare'], hue=cluster_labels, palette='tab10') plt.title(f'K‑Means Clusters (k={k_opt})') plt.xlabel('Age') plt.ylabel('Fare') plt.legend(title='Cluster') plt.show() ### 3. 發現異常(Outlier) python # 距離平方(Sum of Squared Distances) dist_sq = kmeans.transform(scaled) ** 2 # 取最近聚類距離的最大值 threshold = dist_sq.max(axis=1).mean() + 3 * dist_sq.max(axis=1).std() outliers = np.where(dist_sq.max(axis=1) > threshold)[0] print('Potential outliers indices:', outliers) > **洞見**:聚類可以協助: > - **資料切分**:針對不同群聚採取不同特徵工程或模型。 > - **異常偵測**:遠離中心點的樣本可能為資料錯誤或業務異常。 > - **特徵選擇**:聚類結果可作為新的「群聚標籤」特徵輸入模型。 ## 5.5 實務建議與重複執行 | 步驟 | 工具 | 重點 | 典型陷阱 | |------|------|------|----------| | 1. 資料載入 | Pandas / Spark | 確認檔案編碼、缺失值 | 未處理的 NaN 會導致 `describe()` 異常 | | 2. 統計摘要 | Pandas | 計算全量摘要 | 不同資料型態(int vs float)造成誤差 | | 3. 視覺化 | Matplotlib / Seaborn / Plotly | 交互式儀表板 | 視覺化太複雜,難以快速洞察 | | 4. 相關性 | Scikit‑learn / Pandas | 觀察高相關 | 多重共線性忽略,影響模型解釋 | | 5. 聚類 | Scikit‑learn / HDBSCAN | 觀察群聚結構 | 未標準化會導致聚類偏差 | | 6. 迭代 | CI/CD / Jupyter Notebook | 確保可重複 | 版本不一致,導致結果不一致 | ### 重複性與追蹤 1. **腳本化**:將 EDA 代碼寫成 Python 模組,使用 `pytest` 或 `unittest` 進行單元測試。 2. **版本管理**:使用 Git 提交腳本與資料描述文件,保持歷史紀錄。 3. **結果儲存**:將圖表、摘要統計與相關矩陣輸出為 JSON / CSV,並註冊至 MLflow,確保每次實驗都有可追溯的基線。 4. **CI Pipeline**:在 GitHub Actions / GitLab CI 中執行 EDA 腳本,若結果偏差超過 5% 自動觸發通知。 ## 5.6 小結 - **EDA 是資料治理的前置工作**:品質、完整性、可追溯性都需要在此確認。 - **工具選擇**:Python 與 Spark 在語法上相似,但效能與擴充性不同,需依據資料規模與團隊熟悉度選擇。 - **特徵洞見**:不是一成不變;隨著資料流更新與業務變化,需要定期重新進行 EDA。 - **可視化**:既是理解工具,也是溝通橋樑;保持圖表可重複產生、易於解讀。 - **CI 中的可視化**:建議將可視化納入 CI pipeline,若圖表偏差自動提醒開發者。 > **挑戰**:在分散式環境下,繪圖往往被忽略,結果導致「看不見」的數據異常。建議將可視化納入 CI pipeline,若圖表偏差自動提醒開發者。 --- **接下來**:我們將進入 **機器學習與模型建構** 的階段,將這些洞見轉化為可操作的預測邏輯。