返回目錄
A
決策者的資料科學:分析基礎與實務應用 - 第 2 章
第2章 資料收集與清洗:從原始資料到乾淨數據
發布於 2026-03-06 02:06
# 第2章 資料收集與清洗:從原始資料到乾淨數據
> **說明**:在任何資料科學專案的開端,資料品質都是決定結果成敗的關鍵。資料不完整、格式不一致、隱藏的偏差,都是決策者需要先清除的障礙。此章將從資料來源說起,帶領你踏上「資料洗滌」之路,並以實務範例說明每一步的核心要點。
---
## 2.1 資料來源:內部 vs 外部
| 類型 | 典型來源 | 優缺點 |
|------|-----------|--------|
| 內部資料 | ERP、CRM、財務系統、網路行銷平台 | *優點*:權限可控、更新頻率高; *缺點*:維度有限、格式不統一 |
| 外部資料 | 開放資料、政府統計、第三方 API、Web 爬蟲 | *優點*:視角多元、可填補缺口; *缺點*:授權成本、品質難以保證 |
> **決策提示**:在設計資料需求前,先列舉所有潛在來源,並評估其可靠性與可得性。決策者可透過「資料可用性矩陣」將來源分類。
## 2.2 設計資料需求
1. **目標明確**:先確定分析目標(例如:預測客戶流失、提升庫存周轉率)。
2. **關鍵指標**:列出需要的 KPI(如:客戶黏著度、毛利率)。
3. **資料需求文件(Data Requirements Document, DRD)**:
* 來源、頻率、格式、欄位定義
* 資料清洗規則、缺失值處理
* 合規需求(GDPR、個資法)
> **常見陷阱**:需求模糊導致資料收集時「找不到」必要欄位。先用 5‑W‑H(為何、誰、何時、何地、何種)確認需求。
## 2.3 資料收集流程
| 步驟 | 技術 | 典型程式碼 |
|------|------|------------|
| 1. 連接資料庫 | SQL | `pd.read_sql("SELECT * FROM orders", con=conn)` |
| 2. 讀取 API | REST | `response = requests.get(url, headers=hdrs); df = pd.DataFrame(response.json())` |
| 3. 爬蟲 | BeautifulSoup / Scrapy | `soup = BeautifulSoup(html, 'html.parser'); table = pd.read_html(str(soup), header=0)[0]` |
> **實作要點**:在連線前先做「資料安全審核」與「連線速率限制」設定,避免因大流量造成系統阻塞。
## 2.4 資料品質問題
- **缺失值**:空值、`NaN`、`NULL`
- **重複值**:同一筆資料多次出現
- **錯誤格式**:日期格式不統一、貨幣單位混用
- **異常值**:極端數值、邏輯錯誤(如:負價格)
> **風險說明**:如果不處理缺失值,模型可能傾向於「訓練時可見」的樣本,導致偏差;重複值會引發統計誤差,甚至讓決策者錯估市場規模。
## 2.5 資料清洗技巧
| 目標 | 方法 | 例子 |
|------|------|------|
| 缺失值處理 | - 刪除
- 代入(均值/中位數/多重插補)
- 前向/後向填充 | `df.dropna()` / `df.fillna(df.mean())` |
| 重複值 | `df.drop_duplicates()` | 取消重複訂單號 |
| 格式統一 | `pd.to_datetime()` / `astype()` | 日期統一為 `YYYY-MM-DD` |
| 異常值檢測 | IQR、Z‑score、視覺化 | `df[(df['price'] > 3*iqr) | (df['price'] < -3*iqr)]` |
> **最佳實踐**:先將缺失值的原因記錄於 *data lineage*,避免在後續分析中忽略其重要性。
## 2.6 Feature Engineering 基礎
1. **欄位轉換**:log、平方根、標準化(`StandardScaler`)
2. **分箱**:將連續變量拆分為離散等級
3. **衍生特徵**:交互項、日期時間拆解(年、月、週)
4. **編碼**:One‑Hot、Target Encoding
> **案例**:將「訂單日期」拆解為「年」與「季節」兩欄,提升銷售預測模型對季節性波動的辨識度。
## 2.7 工具實務
### Pandas 範例
```python
import pandas as pd
from sqlalchemy import create_engine
# 1. 連接資料庫
engine = create_engine('postgresql://user:pwd@host:5432/db')
query = "SELECT order_id, order_date, amount FROM orders WHERE order_date >= '2023-01-01'"
df = pd.read_sql(query, engine)
# 2. 資料清洗
# 日期格式統一
df['order_date'] = pd.to_datetime(df['order_date'])
# 缺失值填充
df['amount'] = df['amount'].fillna(df['amount'].median())
# 去重
df = df.drop_duplicates(subset='order_id')
# 3. Feature Engineering
# 標準化
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
df['amount_z'] = scaler.fit_transform(df[['amount']])
print(df.head())
```
### SQL 範例
```sql
-- 取得過去 90 天內的訂單
SELECT order_id, order_date, amount
FROM orders
WHERE order_date >= CURRENT_DATE - INTERVAL '90 days';
```
### API 範例(Python)
```python
import requests, pandas as pd
url = "https://api.example.com/v1/sales"
headers = {"Authorization": "Bearer YOUR_TOKEN"}
resp = requests.get(url, headers=headers)
data = resp.json()
df = pd.DataFrame(data['records'])
```
## 2.8 常見陷阱 & 實作要點
| 陷阱 | 影響 | 解決方案 |
|------|------|----------|
| **資料遺失** | 偏差、模型過擬合 | 追蹤缺失原因、做「資料遺失分層」處理 |
| **版本控制失敗** | 同一資料被不同團隊使用,導致不一致 | 建立資料湖版本化策略(Delta Lake、Parquet) |
| **偏見傳遞** | 社會偏見嵌入資料,決策偏離公平 | 檢查欄位敏感度、做公平性審核 |
| **性能瓶頸** | 大量資料處理耗時 | 先做「資料抽樣」、使用 Dask 或 Spark |
> **實作要點**:每次清洗後,記錄「資料摘要」與「清洗筆記」,方便後續追蹤與重現。
## 2.9 小結
1. **資料品質是關鍵**:即使再先進的模型,也無法彌補資料錯誤。
2. **系統化流程**:從需求、來源、收集、清洗到 Feature Engineering,形成可重複的工作流。
3. **工具運用**:熟練 Pandas、SQL、API 呼叫,能大幅降低前置工作量。
4. **持續監控**:建立資料監測機制,確保資料健康。
---
## 實務案例:某零售商營收分析資料清洗
- **背景**:一家線上零售商希望通過訂單資料預測月營收。
- **資料**:從 2022‑01 到 2023‑06 的訂單資料(約 200,000 筆)。
- **清洗流程**:
1. 連結 PostgreSQL,抓取 `orders`、`customers`、`products`。
2. 合併資料,填補缺失客戶資訊(使用社群媒體 API 取得聯絡方式)。
3. 針對 `amount` 欄位做 IQR 檢測,將超過 99% 分位數的訂單視為異常,並以 `mean + 3σ` 重新估算。
4. 將日期拆解為「年-月-日」與「週次」,建立時間特徵。
5. 生成「訂單量」與「客戶回訪次數」等衍生特徵。
- **結果**:資料清洗後的可視化呈現,顯示 5% 缺失值已被有效處理,且異常值剔除後營收趨勢更平滑。
---
## 附錄:常用函式庫與工具
- **Python**:pandas, numpy, scikit‑learn, matplotlib, seaborn, requests
- **SQL**:PostgreSQL, MySQL, SQLite
- **大數據**:Dask, PySpark
- **資料湖**:Delta Lake, Apache Iceberg
- **版本化**:Git, DVC
> **下一章預告**:資料探索分析(EDA)— 透過視覺化與統計檢驗揭示數據內在結構,為模型選擇鋪路。