返回目錄
A
數據洞察:從資料到決策的科學方法 - 第 6 章
第6章 無監督式學習與深度學習
發布於 2026-02-21 02:05
# 第6章 無監督式學習與深度學習
> 本章將帶領讀者走進資料科學的兩大分支:**無監督式學習**(Clustering、Dimensionality‑Reduction)與**深度學習**(Convolutional Neural Networks、Recurrent Neural Networks 等)。在完成監督式模型後,往往會遇到「資料標籤不足」或「需從資料本身抽取隱含結構」的情境,本章提供實務範例與工具,協助讀者在此類場景中發掘價值。
---
## 6.1 無監督式學習概覽
| 目的 | 方法 | 常用指標 | 典型應用 |
|---|---|---|---|
| **分群** | K‑Means、DBSCAN、Gaussian Mixture | SSE、Silhouette、Calinski‑Harabasz | 市場細分、客戶分層 |
| **降維** | PCA、t‑SNE、UMAP | Explained Variance、Kurtosis | 可視化、特徵壓縮 |
| **異常檢測** | Isolation Forest、LOF、One‑Class SVM | ROC‑AUC、Precision‑Recall | 欺詐偵測、品質控制 |
> **核心概念**:無監督式學習不依賴標籤,而是依靠資料本身的結構或相似度。選擇適當的距離度量、初始化策略與停止條件對結果影響甚大。
### 6.1.1 K‑Means 範例
```python
import numpy as np
from sklearn.datasets import make_blobs
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
# 產生模擬資料
X, _ = make_blobs(n_samples=300, centers=4, cluster_std=0.60, random_state=42)
# K‑Means 估算
kmeans = KMeans(n_clusters=4, init='k-means++', random_state=42)
kmeans.fit(X)
labels = kmeans.labels_
print('Silhouette score:', silhouette_score(X, labels))
```
> **小技巧**:使用 `k-means++` 初始化可避免初始中心過於集中,提升收斂速度與結果穩定性。
### 6.1.2 DBSCAN 範例
```python
from sklearn.cluster import DBSCAN
from sklearn.metrics import confusion_matrix
# DBSCAN 參數說明
# eps:鄰域半徑,min_samples:最小樣本數
model = DBSCAN(eps=0.5, min_samples=5)
labels = model.fit_predict(X)
print('Noise points:', np.sum(labels == -1))
```
> **提示**:DBSCAN 能自動識別噪音點(-1 標籤),非常適合處理非球形分布。
## 6.2 降維技巧
### 6.2.1 主成分分析(PCA)
PCA 透過正交變換將資料投射到一組彼此正交的基底上,保留最大方差。PCA 常用於資料可視化、去除多重共線性。
```python
from sklearn.decomposition import PCA
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X)
print('Explained variance ratio:', pca.explained_variance_ratio_)
```
### 6.2.2 t‑SNE 與 UMAP
t‑SNE 與 UMAP 是非線性降維方法,適合高維資料的可視化。UMAP 計算速度較快,且保留全局結構。
```python
from umap import UMAP
umap_model = UMAP(n_neighbors=15, min_dist=0.1)
X_umap = umap_model.fit_transform(X)
```
> **對比**:t‑SNE 需要較多計算時間,UMAP 亦可處理大型資料集,建議先用 UMAP 進行快速探索,再視需求使用 t‑SNE。
## 6.3 深度學習基礎
### 6.3.1 為何選擇深度學習?
* **自動特徵抽取**:CNN、RNN 能自動學習複雜模式,減少人工特徵工程。
* **非結構化資料**:影像、語音、文字皆可直接輸入網路,無需手動轉換。
* **可擴充性**:網路層數、節點可調整,應對不同複雜度需求。
### 6.3.2 TensorFlow 與 PyTorch
| 框架 | 優點 | 典型用法 |
|---|---|---|
| TensorFlow | 部署友善、TensorBoard | 大規模訓練、雲端服務 |
| PyTorch | 易於除錯、動態圖 | 研究原型、快速迭代 |
> **建議**:初學者可先使用 PyTorch 進行快速實驗,待熟悉後再切換至 TensorFlow 進行部署。
## 6.4 卷積神經網路(CNN)
### 6.4.1 基本結構
1. **Convolution 層**:提取局部特徵。
2. **Pooling 層**:降低維度,增強不變性。
3. **Fully‑Connected 層**:進行分類或回歸。
4. **Dropout**:減少過擬合。
### 6.4.2 範例:手寫數字分類
```python
import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transforms
# 資料前處理
transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5,), (0.5,))])
train_dataset = datasets.MNIST(root='.', train=True, download=True, transform=transform)
train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=64, shuffle=True)
# 模型定義
class SimpleCNN(nn.Module):
def __init__(self):
super(SimpleCNN, self).__init__()
self.conv1 = nn.Conv2d(1, 32, kernel_size=3, padding=1)
self.pool = nn.MaxPool2d(2, 2)
self.fc1 = nn.Linear(32 * 14 * 14, 128)
self.fc2 = nn.Linear(128, 10)
self.dropout = nn.Dropout(0.25)
def forward(self, x):
x = self.pool(torch.relu(self.conv1(x)))
x = x.view(-1, 32 * 14 * 14)
x = torch.relu(self.fc1(x))
x = self.dropout(x)
x = self.fc2(x)
return x
model = SimpleCNN()
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)
# 訓練迴圈(簡化)
for epoch in range(5):
for data, target in train_loader:
optimizer.zero_grad()
output = model(data)
loss = criterion(output, target)
loss.backward()
optimizer.step()
print(f'Epoch {epoch+1} complete.')
```
> **實務建議**:使用 **early stopping** 或 **learning‑rate scheduler** 可有效避免過擬合與學習率過大。
## 6.5 循環神經網路(RNN)與 Transformer
### 6.5.1 循環結構
* **LSTM**、**GRU**:解決梯度消失問題,適合長序列。
* **Bidirectional**:雙向閱讀,提升上下文理解。
```python
class SimpleRNN(nn.Module):
def __init__(self, input_size, hidden_size, num_layers, num_classes):
super(SimpleRNN, self).__init__()
self.rnn = nn.LSTM(input_size, hidden_size, num_layers, batch_first=True)
self.fc = nn.Linear(hidden_size, num_classes)
def forward(self, x):
out, _ = self.rnn(x)
out = out[:, -1, :] # 取最後時間步
out = self.fc(out)
return out
```
### 6.5.2 Transformer:序列‑到‑序列模型的未來
* **Self‑Attention**:並行計算,適合大規模文本。
* **BERT、GPT** 等預訓練模型可直接 fine‑tune,快速解決多種 NLP 任務。
---
## 6.6 模型評估與部署
| 方法 | 評估工具 | 部署策略 |
|---|---|---|
| **無監督** | Silhouette、Elbow、UMAP 可視化 | 交叉驗證 + 迭代調參 |
| **CNN** | TensorBoard、Matplotlib | Flask + TorchServe |
| **RNN** | BLEU、ROUGE、Accuracy | ONNX、Edge‑TPU |
> **提示**:在部署前務必使用 **資料增強**(Data Augmentation)與 **模型壓縮**(Quantization、Pruning)降低推論延遲。
## 6.6 案例研究:從客戶行為到推薦系統
1. **資料前處理**:先完成 K‑Means 分群,得到客戶類別。
2. **特徵壓縮**:利用 PCA 將高維行為資料壓縮至 50 個主成分。
3. **自動化特徵**:使用 **Auto‑Encoder**(自編碼器)進行進一步抽取。
4. **推薦模型**:將分群結果與自編碼器輸出作為特徵,輸入一個簡易 Feed‑Forward NN 進行偏好預測。
> **結語**:無監督式學習與深度學習雖然不依賴標籤,但需要精心設計距離度量、網路架構與訓練策略。透過本章的實務範例與工具,讀者將能在 **資料標籤缺失** 或 **資料結構複雜** 的情境下,仍然獲得可落地的洞察與價值。
---
**後續章節**:第 7 章將聚焦於模型部署與雲端服務,協助讀者將本章學到的無監督模型與深度網路正式投入生產環境。