返回目錄
A
數據科學實戰:從問題到洞見 - 第 4 章
第 4 章:資料探索與可視化 — 洞見的開端
發布於 2026-03-05 11:04
# 第 4 章:資料探索與可視化 — 洞見的開端
在前兩章我們已經把「問題定義」與「資料蒐集」的基石鋪設完成,現在要進一步問自己:
> **「這些資料藏著什麼故事?」**
這一段旅程的核心是 **探索性資料分析(EDA)**,它既是對資料品質的驗證,也是模型特徵選擇的起點。以下,我會用實際範例說明如何在 Python 與 Spark 環境下,透過可視化與統計量快速把握資料特性。
## 1. 為什麼要先做 EDA?
| 目的 | 具體做法 | 需要注意的點 |
|------|----------|---------------|
| 了解資料結構 | `df.dtypes`、`df.describe()` | 先確定每個欄位的資料型別,避免後續轉型錯誤 |
| 檢查缺失值 | `df.isnull().mean()` | 缺失比例高的欄位可能需要剔除或填補 |
| 探索分布 | `sns.histplot`、`plt.boxplot` | 觀察是否有偏態、離群點 |
| 變數關聯 | `corr()`、`heatmap` | 可能揭露可用於特徵工程的線性關係 |
| 資料品質金字塔 | **可測試** | 以統計指標檢驗資料完整性、準確性、一致性 |
EDA 是資料治理的 **前端**:如果資料本身就存在問題,後續所有模型都會被「泥濘」覆蓋。
## 2. Python‑centric EDA
> **小技巧**:用 `%%time` 或 `%%timeit` 監控腳本效能,避免「看不到時間」的陷阱。
python
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
# 假設有一個信用評分資料集
path = 'data/credit_score.csv'
df = pd.read_csv(path)
# 基本資訊
print(df.info())
print(df.describe().T)
# 缺失值分佈
missing = df.isnull().mean() * 100
print('缺失率(%)\n', missing.sort_values(ascending=False).head(10))
# 可視化:箱型圖檢查離群點
plt.figure(figsize=(12, 4))
for i, col in enumerate(['Age', 'Income', 'CreditScore']):
plt.subplot(1, 3, i+1)
sns.boxplot(x=df[col])
plt.title(col)
plt.tight_layout()
plt.show()
### 2.1 互動式視覺化
如果你在 Notebook 之外想要更動態的圖表,Plotly 是不可忽略的選擇:
python
import plotly.express as px
fig = px.histogram(df, x='Income', nbins=30, title='收入分布')
fig.show()
## 3. Spark‑powered EDA
在分散式環境下,資料規模會爆炸,單機版的 Pandas 無法滿足。Spark DataFrame 仍保留類似的 API,並可利用 SparkSQL 做 SQL 風格分析。
python
from pyspark.sql import SparkSession
spark = SparkSession.builder.appName('EDA').getOrCreate()
df_spark = spark.read.csv('data/credit_score.parquet', header=True, inferSchema=True)
# 基本統計
df_spark.describe().show()
# 缺失值
from pyspark.sql.functions import col, sum as _sum
missing_expr = [(_sum(col(c).isNull().cast('int')).alias(c)) for c in df_spark.columns]
missing_df = df_spark.select(*missing_expr)
missing_df.show()
> **提醒**:Spark 的 `describe()` 只會回傳 `count`, `mean`, `stddev`, `min`, `max`,若需要更深層次的分布統計,需要自己寫 UDF 或轉成 Pandas(但前提是資料量允許)。
## 4. 特徵工程的早期洞見
探索性資料分析不只是「看圖」與「算統計」,它也是 **特徵選擇** 的第一步。下面列出一些常見的特徵篩選方法:
| 方法 | 實際實現 |
|------|----------|
| 相關係數 | `df.corr()` 只保留相關性 > 0.7 |
| 互信息 | `mutual_info_classif`(sklearn) |
| L1 正則化 | `LogisticRegression(penalty='l1')` |
| 主成分分析 | `PCA` 可幫你觀察變異量 |
python
from sklearn.feature_selection import mutual_info_classif
X = df.drop(columns=['Target'])
y = df['Target']
mi = mutual_info_classif(X, y)
mi_series = pd.Series(mi, index=X.columns).sort_values(ascending=False)
print(mi_series.head(10))
## 5. 連結到資料治理
在完成 EDA 後,下一步是將洞見轉化為 **可追溯、可重複的流程**。這裡你會用到:
- **MLflow** 追蹤探索結果:把統計報告、圖表與模型參數寫入 MLflow 以便日後查詢。
- **Amundsen** 的資料線圖:將 EDA 產出的特徵標記在資料線圖中,讓後續使用者能即時了解其來源與轉換。
- **OPA**:若某些特徵對某些角色來說機密,直接在資料存取層設置規則,確保資料不被誤用。
> **實戰提示**:將 EDA 產生的 `df.describe()` 及 `corr()` 結果直接輸出成 `JSON`,並註冊到 MLflow 參數表,這樣可以在後續模型訓練時自動拉取相同的統計基線。
## 6. 小結
- **EDA 是資料治理的前置工作**:品質、完整性、可追溯性都需要在這一步確認。
- **Python 與 Spark** 雖然語法相似,但在效能、擴充性上有明顯差異;選擇哪個取決於資料規模與團隊熟悉度。
- **特徵洞見** 不是一成不變;隨著資料流更新與業務變化,需要定期重新進行 EDA。
- **可視化** 既是理解工具,也是溝通橋樑;保持圖表可重複產生、易於解讀。
> **挑戰**:在分散式環境下,繪圖往往被忽略,結果導致「看不見」的數據異常。建議將可視化納入 CI pipeline,若圖表偏差自動提醒開發者。
本章結束,接下來我們將進入 **模型構建** 的階段,將這些洞見轉化為可操作的預測邏輯。