返回目錄
A
金融資料科學:從數據到決策的完整流程 - 第 3 章
第 3 章:資料清理與前處理
發布於 2026-03-07 11:47
# 第 3 章:資料清理與前處理
在金融資料科學的實務流程中,資料清理(Data Cleaning)與前處理(Feature Engineering)是連接原始資料與模型輸入的關鍵橋樑。缺失值、重複紀錄、異常數值以及資料類型不一致等問題,若不妥善處理,往往會直接導致模型性能急劇下降,甚至產生誤導性的投資決策。
以下以 **台股日成交資料** 為例,逐步拆解常見的清理與前處理步驟,並提供完整的 Python 程式碼範例與 Airflow 任務示範。
---
## 3.1 欄位缺失與重複資料處理
| 步驟 | 目的 | 常見做法 |
|------|------|----------|
| `detect_missing` | 檢測缺失比例 | `df.isna().sum()` |
| `handle_missing` | 逐欄決策填補 | `fillna`、`interpolate`、`dropna` |
| `detect_duplicates` | 发现重复记录 | `df.duplicated()` |
| `remove_duplicates` | 只保留唯一值 | `df.drop_duplicates()` |
### 程式碼範例
```python
import pandas as pd
def clean_basic(df: pd.DataFrame) -> pd.DataFrame:
"""處理缺失值與重複紀錄。"""
# 1. 欄位缺失檢測
missing = df.isna().sum()
print('Missing values per column:\n', missing)
# 2. 欄位缺失處理(根據業務決策)
# 以成交量為例,若缺失小於 5% 可直接 drop
if missing['Volume'] / len(df) < 0.05:
df = df.dropna(subset=['Volume'])
else:
df['Volume'] = df['Volume'].interpolate(method='linear')
# 3. 重複紀錄處理
dup_count = df.duplicated().sum()
print(f'Duplicate rows detected: {dup_count}')
df = df.drop_duplicates()
return df
```
> **實務建議**:缺失值的處理必須配合業務知識。若缺失屬於極端情況(如公司停牌),直接 drop 可能更安全;若缺失是隨機機率,則使用插補或預測模型補齊。
---
## 3.2 日期時間轉換與時區校正
金融市場資料往往只提供「日期」欄位,而實際分析需要完整的時間戳(timestamp)。若不統一時區,跨市場比較或高頻交易分析將出錯。
```python
# 假設 df['Date'] 為 yyyy-mm-dd
import pytz
from datetime import datetime
def normalize_datetime(df: pd.DataFrame) -> pd.DataFrame:
df['Datetime'] = pd.to_datetime(df['Date'])
# 台灣時區:Asia/Taipei
tz = pytz.timezone('Asia/Taipei')
df['Datetime'] = df['Datetime'].dt.tz_localize(tz)
return df
```
---
## 3.3 數值與類別變數編碼
| 類型 | 編碼方式 | 典型範例 |
|------|----------|----------|
| 數值 | 標準化/正規化 | `StandardScaler`, `MinMaxScaler` |
| 類別 | One-Hot, Target Encoding | `pd.get_dummies`, `category_encoders` |
### 代碼範例
```python
from sklearn.preprocessing import StandardScaler
import category_encoders as ce
def encode_features(df: pd.DataFrame) -> pd.DataFrame:
# 數值欄位標準化
num_cols = ['Close', 'Open', 'High', 'Low']
scaler = StandardScaler()
df[num_cols] = scaler.fit_transform(df[num_cols])
# 類別欄位 One-Hot
cat_cols = ['Market']
df = pd.get_dummies(df, columns=cat_cols, drop_first=True)
return df
```
> **實務建議**:若模型支援稀疏矩陣(如 Logistic Regression),可直接使用 One-Hot;若資料量極大,考慮使用 Target Encoding 或 Embedding 以降低維度。
---
## 3.4 異常值與離群值檢測
金融資料的異常值(Outlier)往往是重要訊號,但若不加控制,會干擾模型學習。常見方法有
* IQR(四分位距)檢測
* Z-Score
* 盒鬚圖(Boxplot)視覺化
* DBSCAN、Isolation Forest
### 範例:IQR
```python
def remove_outliers(df: pd.DataFrame, column: str, factor: float = 1.5) -> pd.DataFrame:
Q1 = df[column].quantile(0.25)
Q3 = df[column].quantile(0.75)
IQR = Q3 - Q1
lower = Q1 - factor * IQR
upper = Q3 + factor * IQR
mask = (df[column] >= lower) & (df[column] <= upper)
print(f'Removed {mask.shape[0] - mask.sum()} outliers from {column}')
return df[mask]
```
---
## 3.5 時間序列特徵創造
在金融領域,時間序列特徵極為重要:移動平均、布林帶、RSI、MACD 等技術指標可直接用於模型。
```python
import ta # Technical Analysis Library
def add_time_series_features(df: pd.DataFrame) -> pd.DataFrame:
df['MA_20'] = ta.trend.sma_indicator(df['Close'], window=20)
df['MA_50'] = ta.trend.sma_indicator(df['Close'], window=50)
df['RSI_14'] = ta.momentum.rsi(df['Close'], window=14)
df['MACD'] = ta.trend.macd_diff(df['Close'])
return df
```
> **實務建議**:避免使用未來資訊進行滾動計算,確保「前視窗」的資料窗口僅包含過去資料。
---
## 3.6 完整 ETL 與 Airflow 工作流範例
```python
# dag.py
from airflow import DAG
from airflow.operators.python import PythonOperator
from datetime import datetime
# 依賴自前面章節的函式
from data_cleaning import clean_basic, normalize_datetime, encode_features, remove_outliers, add_time_series_features
with DAG('twse_daily_clean', start_date=datetime(2023, 1, 1), schedule_interval='@daily', catchup=False) as dag:
def fetch_and_clean(**context):
df = context['ti'].xcom_pull(task_ids='fetch_data')
df = clean_basic(df)
df = normalize_datetime(df)
df = encode_features(df)
df = remove_outliers(df, 'Close')
df = add_time_series_features(df)
context['ti'].xcom_push(key='cleaned_df', value=df)
clean_task = PythonOperator(
task_id='clean_data',
python_callable=fetch_and_clean,
provide_context=True
)
# 依賴的 fetch_data 任務(已在前章實作)
fetch_task >> clean_task
```
---
## 3.7 資料品質指標
* **完整度(Completeness)**:缺失值比例 < 5%
* **一致性(Consistency)**:資料類型、格式統一
* **準確性(Accuracy)**:數值範圍合理、無極端離群
* **時效性(Timeliness)**:資料延遲 < 1 天
定期生成「資料品質報告」並存於資料倉庫,方便後續模型監控與回溯。
---
## 小結
資料清理與前處理雖然流程繁瑣,但卻是模型成功的關鍵基石。本文以台股日成交資料為例,從缺失值、重複、日期、編碼、異常、特徵到完整的 Airflow 工作流,展示了從資料原始形態到可供模型使用的完整轉化過程。未來在第 4 章,我們將進一步探討 **統計建模** 與 **機器學習** 的實務實作,將前處理好的特徵轉化為投資決策的數學模型。