1990 年代中期 SVM 剛問世時,在統計與機器學習界引起了不小的轟動。原因不只來自於它的優秀表現與成功的行銷包裝,更因為它的數學形式看起來既新穎又神秘——在允許部分違反邊界的同時找到最佳分離超平面,還用核心函數將資料映射到高維度空間以處理非線性邊界——這一切看起來與傳統的分類方法(如邏輯回歸、線性判別分析)完全不同。
然而,隨著時間推移,SVM 與古典統計方法之間的深層連結逐漸浮現。本章節的核心訊息是:SVM 和邏輯回歸本質上是同一框架下的不同實作——它們只是選擇了不同的損失函數。就像同一個引擎可以裝在不同的車殼裡,SVM 和邏輯回歸共享相同的「損失+懲罰」最佳化框架,差別只在於損失函數的形狀。
SVM 的原始表述(式 9.12–9.15)是用幾何語言描述的——最大化邊界、容忍部分違反。但這個看似幾何的問題可以改寫成一個更通用的「損失函數+懲罰項」形式:
其中 \(f(x_i) = \beta_0 + \beta_1 x_{i1} + \cdots + \beta_p x_{ip}\) 是線性決策函數,\(\lambda \ge 0\) 是調節參數。這個改寫讓 SVM 瞬間變得不再神秘——它完全符合我們在前幾章反覆看到的模式:
| 方法 | 損失函數 \(L(X,y,\beta)\) | 懲罰項 \(P(\beta)\) |
|---|---|---|
| Ridge Regression | \(\sum (y_i - \hat{y}_i)^2\)(平方誤差) | \(\sum \beta_j^2\)(L2) |
| Lasso | \(\sum (y_i - \hat{y}_i)^2\)(平方誤差) | \(\sum |\beta_j|\)(L1) |
| 支援向量分類器 | \(\sum \max[0, 1 - y_i f(x_i)]\)(hinge loss) | \(\sum \beta_j^2\)(L2) |
| 邏輯回歸 | \(\sum \log[1 + e^{-y_i f(x_i)}]\)(logistic loss) | 可加 L1 / L2 / Elastic Net |
注意 SVM 的懲罰項是 L2 懲罰(Ridge 風格)——這意味著 \(\lambda\) 扮演與 SVM 的 \(C\) 參數相反的角色:\(\lambda\) 大 ≈ \(C\) 小(更多違反邊界、低變異高偏差),\(\lambda\) 小 ≈ \(C\) 大(嚴格邊界、高變異低偏差)。
SVM 使用 hinge loss(鉸鏈損失),邏輯回歸使用的則是 logistic loss。兩者長得很像,但有一個關鍵差異:
核心差異:當 \(y \cdot f(x) \ge 1\)(即觀測值落在邊界的正確一側),hinge loss 精確為零——這些觀測值完全不會影響分類器。而 logistic loss 永遠不為零,只是當觀測值離決策邊界很遠時變得很小。這就是為什麼 SVM 只有「支援向量」影響最終模型的原因。
# Colab + 本機相容資料路徑
try:
from google.colab import drive
drive.mount('/content/drive')
DATA_PATH = '/content/drive/MyDrive/ISLP_data/'
except ImportError:
DATA_PATH = '/tmp/'
import numpy as np
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
# 計算 hinge loss 和 logistic loss
yf = np.linspace(-4, 4, 500)
hinge_loss = np.maximum(0, 1 - yf)
logistic_loss = np.log(1 + np.exp(-yf))
fig, ax = plt.subplots(figsize=(9, 5))
ax.plot(yf, hinge_loss, 'b-', linewidth=2.5, label='SVM Hinge Loss: max[0, 1 − y·f]')
ax.plot(yf, logistic_loss, 'r--', linewidth=2.5, label='Logistic Loss: log[1 + e^(−y·f)]')
# 標示關鍵區域
ax.axvline(x=1, color='gray', linestyle=':', alpha=0.7)
ax.axhline(y=0, color='gray', linestyle='-', alpha=0.3)
ax.annotate('y·f = 1(邊界)', xy=(1, 0.2), xytext=(1.8, 1.5),
arrowprops=dict(arrowstyle='->', color='gray'), fontsize=10, color='#8b949e')
ax.annotate('Hinge = 0\n(正確側不影響模型)', xy=(2.5, 0), xytext=(3.5, 1.0),
arrowprops=dict(arrowstyle='->', color='#58a6ff'), fontsize=10, color='#58a6ff')
ax.annotate('Logistic 永遠 > 0\n(每個觀測值都有影響)', xy=(-2, 2.2), xytext=(-3.5, 3.5),
arrowprops=dict(arrowstyle='->', color='#f85149'), fontsize=10, color='#f85149')
ax.fill_between(yf[yf >= 1], 0, hinge_loss[yf >= 1], alpha=0.08, color='#3fb950')
ax.text(2.0, 0.06, 'hinge = 0 區間', fontsize=9, color='#3fb950', ha='center')
ax.set_xlabel('y · f(x) (正值 = 分類正確,負值 = 分類錯誤)', fontsize=11)
ax.set_ylabel('Loss', fontsize=11)
ax.set_title('圖 9.12:SVM Hinge Loss vs Logistic Regression Loss', fontsize=13, color='#58a6ff')
ax.legend(fontsize=10, loc='upper right')
ax.set_ylim(-0.1, 7)
ax.grid(True, alpha=0.15)
plt.tight_layout()
plt.show()
由於兩者的損失函數形狀相似,SVM 和邏輯回歸在實務上經常給出非常接近的結果。選擇的關鍵在於資料的「分離程度」:
在疾病篩檢中(如 COVID-19 快篩),陽性與陰性族群的特徵值常常高度重疊(發燒、咳嗽、疲勞等症狀在兩族群中都可能出現)。此時 logistic loss 的「平滑漸進」特性更適合——它不會像 hinge loss 那樣在邊界處突然截斷資訊,能更好地捕捉重疊區域中的機率梯度。而且邏輯回歸直接輸出機率 \(P(Y=1|X)\),這對臨床風險評估至關重要。
垃圾郵件和正常郵件的特徵空間通常有清晰的語義邊界——包含「免費」、「中獎」、「點擊領取」等詞彙的郵件與正常商務郵件在詞頻特徵上分離度較高。SVM 的 hinge loss 在這種情況下表現出色:它只關注邊界附近的「難分郵件」(支援向量),對明顯是垃圾或明顯是正常的郵件直接無視,計算效率高且分類邊界清晰。
銀行審核貸款時,不僅需要準確的分類(核貸/拒貸),更需要可解釋的機率輸出。邏輯回歸可以直接給出違約機率,且係數有明確的 odds-ratio 解釋(「收入每增加 1 單位,違約 odds 降低 X%」),這是金融監管機構(如巴塞爾協定)所要求的。SVM 雖然分類準確度可能更高,但缺乏這種直接的機率校準。
課本提出了一個有趣的歷史觀察:核心方法(kernel trick)並非 SVM 獨有。我們完全可以用核心函數來擴展邏輯回歸或其他分類方法——這與第 7 章的非線性方法(樣條、GAM)密切相關。然而由於歷史因素,核心方法在 SVM 領域的應用遠比邏輯回歸普遍。這提醒我們:工具的流行程度不等於其獨特性——許多「SVM 特有」的特性其實是通用技術被品牌化的結果。
SVM 不僅能做分類,還能做迴歸——稱為 支援向量回歸(Support Vector Regression, SVR)。傳統最小平方法迴歸最小化所有殘差的平方和,而 SVR 採用不同的損失函數:只有絕對值大於某個門檻 \(\epsilon\) 的殘差才會被計入損失。這就像是把 SVM 的「邊界」概念延伸到迴歸問題——在 \(\epsilon\)-tube 內的預測誤差被視為「可以接受」,不計入損失。
這在訊號處理和穩健迴歸中有重要應用——當資料含有離群值時,SVR 比最小平方法更不受極端值影響。
| 特性 | SVM | 邏輯回歸 |
|---|---|---|
| 損失函數 | Hinge: max[0, 1−y·f] | Logistic: log[1+e^(−y·f)] |
| 損失在 y·f ≥ 1 時 | 精確為零 | 極小但 > 0 |
| 受影響的觀測值 | 僅支援向量 | 全部觀測值 |
| 機率輸出 | 需 Platt scaling 後處理 | 原生輸出 P(Y=1|X) |
| 預設邊界類型 | 線性(可用核心擴展) | 線性(可手動加非線性特徵) |
| 懲罰項 | L2(Ridge 風格) | L1 / L2 / Elastic Net 均可 |
| 核心方法 | 生態成熟、廣泛使用 | 理論可行、實務少用 |
| 類別重疊時 | 表現較差 | 表現較好 |
| 類別分離時 | 表現較好 | 表現尚可 |
| 迴歸版本 | SVR(ε-insensitive loss) | 無直接對應(但 GLM 框架涵蓋) |
| 最佳應用場景 | 高維度、清晰邊界的分類 | 需要機率校準、可解釋性、重疊類別 |