返回目錄
A
金融數據科學:從基礎到量化交易 - 第 3 章
第三章 探索性資料分析 (EDA)
發布於 2026-03-04 07:43
# 第三章 探索性資料分析 (EDA)
> **目的**:在資料前處理完成後,透過統計摘要、視覺化與相關性分析快速洞察市場結構、潛在趨勢與異常。探索性資料分析不僅能揭示資料內在模式,也為後續建模與風險評估奠定基礎。
## 3.1 EDA 的流程與思維
| 步驟 | 目的 | 主要輸出 |
|------|------|----------|
| 3.1.1 資料概覽 | 了解資料量、欄位類型、缺失比例 | 資料型別表、缺失率圖 |
| 3.1.2 基本統計摘要 | 描述性統計量(均值、偏度、峰度) | DataFrame、Summary Table |
| 3.1.3 分佈視覺化 | 檢測正態性、離群值 | 折線圖、箱形圖、QQ圖 |
| 3.1.4 相關性分析 | 發現變數間關聯、共線性 | 熱力圖、散佈矩陣 |
| 3.1.5 時間序列特徵 | 探索季節性、趨勢、週期 | 時間序列分解、季節指數 |
| 3.1.6 異常檢測 | 標記異常點、潛在資料問題 | 標記圖、IQR、Z-score |
| 3.1.7 特徵工程提示 | 推薦衍生特徵、轉換 | 新欄位清單 |
| 3.1.8 報告生成 | 將結果匯總於報表 | Markdown、PDF、Jupyter Notebook |
> **思維**:
> 1. **問題先行** – 先明確分析問題,設定關鍵指標。
> 2. **多角度觀察** – 從統計、視覺化、時間序列三面切入。
> 3. **迭代式進行** – 每一次視覺化都可能揭露新的問題,回頭調整資料或模型。
## 3.2 基本統計摘要
使用 `pandas.DataFrame.describe()` 可以一次得到計數、均值、標準差、分位數等資訊。
python
import pandas as pd
# 讀取清洗後的資料
price_df = pd.read_parquet('AAPL.parquet')
# 基本統計摘要
summary = price_df.describe().T
print(summary)
| 變數 | 觀測值 | 平均值 | 標準差 | 最小值 | 25% | 50% | 75% | 最大值 |
|------|--------|--------|--------|--------|-----|-----|-----|-----|
| Close | 5000 | 150.3 | 12.4 | 120.1 | 140.2 | 150.0 | 160.5 | 180.7 |
| Volume | 5000 | 2.1e+06 | 1.2e+06 | 4.2e+05 | 1.3e+06 | 2.0e+06 | 2.8e+06 | 5.6e+06 |
> **提示**:對於異常分佈的變數,使用 `median` 與 `IQR` 更能反映中心趨勢與離散程度。
## 3.3 變量分佈與視覺化
### 3.3.1 折線圖(Time Series Plot)
python
import matplotlib.pyplot as plt
plt.figure(figsize=(12,4))
plt.plot(price_df.index, price_df['Close'], label='Close')
plt.title('AAPL 收盤價時序')
plt.xlabel('日期')
plt.ylabel('收盤價')
plt.legend()
plt.show()
### 3.3.2 箱形圖(Boxplot)
python
import seaborn as sns
sns.boxplot(data=price_df[['Close', 'Volume']])
plt.title('收盤價與成交量箱型圖')
plt.show()
### 3.3.3 正態 QQ-圖
python
import scipy.stats as stats
plt.figure()
stats.probplot(price_df['Close'], dist='norm', plot=plt)
plt.title('收盤價 QQ-圖')
plt.show()
> **解讀**:
> - 折線圖可觀察長期趨勢、週期。
> - 箱形圖顯示離群值與對稱性。
> - QQ-圖判斷是否符合正態分佈;若偏離,可考慮對數轉換或使用非參數方法。
## 3.4 相關性分析
### 3.4.1 相關係數矩陣
python
corr = price_df.corr()
print(corr)
### 3.4.2 熱力圖
python
sns.heatmap(corr, annot=True, cmap='coolwarm', fmt='.2f')
plt.title('變數相關係數熱力圖')
plt.show()
> **共線性檢測**:
> - 若兩變數相關係數 > 0.8,可能需要做特徵選擇或降維。
> - 在機器學習模型(如線性回歸)中,共線性會導致估計不穩定。
## 3.5 時間序列特徵:季節性與趨勢
使用 `statsmodels.tsa.seasonal.seasonal_decompose` 或 `pandas.tseries.offsets` 進行分解。
python
from statsmodels.tsa.seasonal import seasonal_decompose
result = seasonal_decompose(price_df['Close'], model='additive', period=252) # 252 個交易日 ≈ 1 年
result.plot()
plt.show()
> **結果**:
> - **Trend**:長期上升或下降趨勢。
> - **Seasonality**:季節性波動(例如季度、年度)
> - **Residual**:隨機噪聲。
> **實務應用**:
> - 在交易策略中,季節性訊號可作為進出場判斷。
> - 在風險管理中,趨勢變化可作為風險警示。
## 3.6 異常檢測(Outlier Detection)
| 方法 | 公式 | 何時使用 |
|------|------|-----------|
| IQR | Q3−Q1 | 數值型資料離群檢測 |
| Z‑score | (x−μ)/σ | 正態分佈資料 |
| Isolation Forest | 基於樹結構 | 大型高維資料 |
python
# IQR 例子
Q1 = price_df['Close'].quantile(0.25)
Q3 = price_df['Close'].quantile(0.75)
IQR = Q3 - Q1
lower, upper = Q1 - 1.5*IQR, Q3 + 1.5*IQR
outliers = price_df[(price_df['Close'] < lower) | (price_df['Close'] > upper)]
print('離群值數量:', len(outliers))
> **提示**:異常值可能是資料錄入錯誤、重大市場事件或市場操縱。務必先做事件調查再決定處理方式。
## 3.7 特徵工程提示
| 類型 | 典型衍生特徵 | 目的 |
|------|--------------|------|
| 技術指標 | 移動平均、RSI、MACD | 捕捉趨勢與動量 |
| 量化因子 | 變動率、波動率、成交量變化 | 表示市場強度 |
| 時間屬性 | 星期、月份、季節 | 捕捉季節性 |
| 文字特徵 | NLP 取向的情緒指數 | 表示市場情緒 |
python
# 移動平均
price_df['MA20'] = price_df['Close'].rolling(window=20).mean()
price_df['MA50'] = price_df['Close'].rolling(window=50).mean()
> **實務建議**:衍生特徵應根據策略目標選取,過度擴充會增加維度、降低模型可解釋性。
## 3.8 EDA 工具與套件
| 工具 | 說明 | 優勢 |
|------|------|------|
| Pandas | 資料框架 | 高效處理結構化資料 |
| Matplotlib / Seaborn | 靜態圖表 | 調整細節簡單 |
| Plotly / Bokeh | 互動式圖表 | 方便分享與探索 |
| Altair | 宣告式視覺化 | 易於複製與版本控制 |
| JupyterLab | 統合環境 | 交互式編輯、即時輸出 |
| Holoviews + Panel | 數據可視化 + Dashboard | 快速構建交互式儀表板 |
> **選擇建議**:
> - 對於快速迭代與原型設計,建議使用 **Altair** + **Panel** 或 **Plotly Dash**。
> - 對於大規模數據、需要高效內存管理,可使用 **Pandas + Dask**。
## 3.9 實務案例:AAPL 收盤價 EDA
1. **資料導入**:從 Alpha Vantage 下載、清洗、儲存於 Parquet。
2. **基礎統計**:觀察均值、波動率、離群值。
3. **分佈視覺化**:折線圖顯示 2018‑2023 的股價走勢;箱形圖揭露 2020 年疫情期間的極端波動。
4. **相關性**:收盤價與成交量高度正相關,表明市場流動性對價格影響較大。
5. **季節性分解**:發現 2023 年夏季存在高股價季節性。
6. **異常檢測**:確定 2021‑03‑15 為一次非正常跳空,經查證為公司公告。
7. **衍生特徵**:計算 20 日與 50 日移動平均,並導入 14 日 RSI。
8. **報告**:使用 **Jupyter Notebook** 產生 Markdown 報告,並導出為 PDF 分享給投資部門。
> **結語**:探索性資料分析是金融資料科學的第一道門檻。透過系統化的 EDA,我們不僅能快速定位資料問題,也能獲得對市場結構與行為模式的深刻洞察,為後續的建模與策略設計提供堅實基礎。