聊天視窗

資料科學實戰:從數據到洞察 - 第 2 章

第2章 數據採集與清洗

發布於 2026-02-27 04:39

# 第2章 數據採集與清洗 資料科學的核心在於 **「資料」**。即使有最先進的演算法,如果輸入的資料品質欠佳,模型輸出的洞察也可能是誤導性的。此章節將帶領讀者從資料來源、採集技術,到清洗與品質保證的完整流程,為後續的 EDA、特徵工程與模型建置奠定堅實基礎。 --- ## 2.1 資料來源分類 | 類型 | 特徵 | 典型例子 | |------|------|----------| | 結構化資料 | 固定 schema、表格化 | 資料庫表、CSV、Excel | | 半結構化資料 | 標籤或層級化 | JSON、XML、Parquet | | 非結構化資料 | 無明確 schema | 文字、影像、音訊、影片 | | 流資料 | 持續、即時更新 | Kafka、Apache Flink、IoT sensor | > **實務觀察**:金融交易記錄多為結構化資料;社群媒體貼文則屬於非結構化;即時風險監控常用流資料。 ## 2.2 資料採集工具與技術 | 技術 | 主要用途 | 常用語言/框架 | |------|----------|----------------| | API | 結構化資料的遠端調用 | `requests`, `httpx`, `aiohttp` | | Web Scraping | 抓取網頁資料 | `BeautifulSoup`, `Scrapy`, `Selenium` | | ETL / ELT | 批次資料整合 | `Airflow`, `dbt`, `Luigi` | | 流式平台 | 實時資料流 | `Kafka`, `Apache Pulsar`, `Azure Event Hubs` | | 雲端儲存 | 大量原始資料 | AWS S3, GCP Cloud Storage, Azure Blob Storage | > **小技巧**:對於需要高頻更新的金融行情,建議使用 WebSocket 取代 HTTP GET,能減少延遲與頻寬。 ## 2.3 資料品質概念 1. **完整性 (Completeness)** – 資料是否遺漏關鍵欄位或紀錄。 2. **準確性 (Accuracy)** – 資料是否與真實情況相符。 3. **一致性 (Consistency)** – 多個資料來源在同一實體上是否相符。 4. **時效性 (Timeliness)** – 資料更新的延遲是否可接受。 5. **唯一性 (Uniqueness)** – 同一實體是否存在重複紀錄。 > **實務提醒**:在金融風控中,信用分數若缺失或不一致,模型可能高估或低估風險,導致損失。 ## 2.4 常見資料清洗任務 | 任務 | 目的 | Python 範例 | |------|------|------------| | 缺失值處理 | 填補或移除不完整資料 | `df.dropna()`, `df.fillna(0)` | | 異常值偵測 | 移除離群或錯誤輸入 | `np.where(df['col'] > threshold, np.nan, df['col'])` | | 重複資料移除 | 避免多重計算 | `df.drop_duplicates()` | | 格式統一 | 文字統一大小寫、日期格式 | `df['date'] = pd.to_datetime(df['date'])` | | 資料型別轉換 | 確保型別一致 | `df['amount'] = df['amount'].astype(float)` | ### 範例:缺失值與異常值處理 ```python import pandas as pd import numpy as np # 讀取原始資料 raw = pd.read_csv('transaction_raw.csv') # 缺失值填補 raw['amount'].fillna(raw['amount'].median(), inplace=True) # 異常值檢測(假設 1% 的離群上限) q1, q3 = raw['amount'].quantile([0.25, 0.75]) iqr = q3 - q1 lower, upper = q1 - 1.5*iqr, q3 + 1.5*iqr raw.loc[(raw['amount'] < lower) | (raw['amount'] > upper), 'amount'] = np.nan # 再次填補異常值 raw['amount'].fillna(raw['amount'].mean(), inplace=True) raw.to_csv('transaction_clean.csv', index=False) ``` ## 2.5 清洗工具與技巧 | 工具 | 特色 | 何時使用 | |------|------|----------| | Pandas | 適合單機中小規模資料 | < 10 億筆、記憶體 < 16GB | | PySpark | 水平擴展、分散式處理 | > 10 億筆、需要分佈式計算 | | SQL (PostgreSQL, BigQuery) | 直接在資料庫中清洗 | 資料已存於 RDBMS | | OpenRefine | 直覺式資料探索 | 清洗表格、發現重複、標準化 | | Data Wrangler | 交互式轉換 | 需求快速原型、視覺化轉換 | ### 使用 Spark 進行大規模資料清洗 ```python from pyspark.sql import SparkSession from pyspark.sql.functions import col, mean, expr spark = SparkSession.builder.appName('cleaning').getOrCreate() raw = spark.read.csv('s3://bucket/transaction_raw.csv', header=True, inferSchema=True) # 缺失值填補 clean = raw.na.fill({'amount': raw.selectExpr('percentile_approx(amount, 0.5)').first()[0]}) # 異常值篩選(以 3 倍 IQR 為界) stats = clean.selectExpr('percentile_approx(amount, 0.25) as q1', 'percentile_approx(amount, 0.75) as q3').first() q1, q3 = stats.q1, stats.q3 iqr = q3 - q1 lower, upper = q1 - 3*iqr, q3 + 3*iqr clean = clean.where((col('amount') >= lower) & (col('amount') <= upper)) clean.write.mode('overwrite').csv('s3://bucket/transaction_clean.csv') ``` ## 2.6 資料清洗流程設計 ``` ┌─────────────────────┐ │ 1️⃣ 需求分析 │ ├─────────────────────┤ │ 2️⃣ 資料來源確認 │ ├─────────────────────┤ │ 3️⃣ 取得資料(API / Scrape / ETL)│ ├─────────────────────┤ │ 4️⃣ 初步檢查(EDA) │ ├─────────────────────┤ │ 5️⃣ 清洗規則定義 │ ├─────────────────────┤ │ 6️⃣ 資料轉換 (ETL/ELT) │ ├─────────────────────┤ │ 7️⃣ 儲存與檢核 │ └─────────────────────┘ ``` > **最佳實踐**: > - **版本化**:每一次清洗都產生新的「clean」檔案,使用 Git 或 DVC 追蹤。 > - **自動化**:Airflow DAG 或 Prefect Flow 讓流程可重複執行,減少人為錯誤。 > - **日誌紀錄**:記錄每一步的行為(填補、移除、型別轉換),方便審計。 ## 2.7 資料治理與合規 | 法規 | 主要要求 | 影響範疇 | |------|----------|----------| | GDPR (EU) | 隱私權保護、資料主體權益 | 敏感資料需匿名化或加密 | | 個人資料保護法(台灣) | 個人資料蒐集、利用、保留 | 標籤化、加密、刪除 | | PCI‑DSS | 信用卡資料安全 | 加密傳輸、最小權限存取 | ### 匿名化技巧 ```python # 進行哈希匿名化 raw['user_id'] = raw['user_id'].apply(lambda x: hash(x)) # 或使用 Faker 的 anonymizer from faker import Faker fake = Faker() raw['ssn'] = raw['ssn'].apply(lambda _: fake.ssn()) ``` > **關鍵提醒**:資料治理不只是清洗,更包含 *權限、版本、審計*。在金融機構,所有資料處理步驟必須可追蹤,避免合規風險。 ## 2.8 案例實務:金融交易數據清洗 ### 原始資料片段 ``` date,user_id,amount,card_type,status 2023‑01‑01,123456,1000,visa,approved 2023‑01‑02,123456,,visa,declined 2023‑01‑02,123456,5000,visa,approved 2023‑01‑02,123456,5000,visa,approved # 重複 ``` ### 清洗流程 1. **缺失值**:`amount` 填補為中位數。 2. **異常值**:設定 `amount > 3000` 為離群,填補為 `NaN` 後再取均值。 3. **重複**:`drop_duplicates(subset=['date','user_id','card_type'])`。 4. **型別轉換**:將 `date` 轉為 `datetime`。 ### 成效 | 變數 | 清洗前 | 清洗後 | |------|--------|--------| | 欄位數 | 5 | 5 | | 缺失值數 | 1 | 0 | | 重複紀錄 | 1 | 0 | | 離群數 | 1 | 0 | > **學習點**:此簡易流程已使資料符合「完整性」與「一致性」兩項品質指標,進一步提升 EDA 及模型效能。 ## 2.9 小結 - **資料採集**:不同類型的資料需要不同的技術棧,選擇合適的工具能節省時間與成本。 - **資料清洗**:缺失值、異常值、重複資料等問題是常見的品質障礙,透過 Pandas、Spark 或 SQL 等工具可有效處理。 - **資料治理**:合規與治理是不可忽略的環節,尤其在金融、醫療等高風險領域。 - **實務案例**:金融交易數據的清洗流程示範了理論到實作的轉換,並說明了品質提升對模型效果的正向影響。 > **下一步**:第3章將以已清洗的資料為基礎,進行 **探索性資料分析 (EDA)**,發掘資料中的模式、分布與潛在關聯,進一步為特徵工程與模型選型提供洞察。