National Central University
Uedu Main Site
Explore Uedu
Student Console
Register as Member/Login
Research Informed Consent Center
Survey Center
Educational Big Data Challenge
Claim or create a course
Try an AI Scenario Task
Support & Messages
Uptime Data

UeduGPTs

--

Jupyters

3

Local AI

--

Uedu Code

--

中央大學 AQI 80 24°C PM2.5 21
AI Reply Desktop Notifications

Show a desktop notification when the AI TA finishes replying

Chat Message Notifications

Notify me when classmates post messages in the forum

Sound notification

Play an alert sound whenever there is a new notification

Unit 11

支援向量機

間隔、支援向量與核函數
Interaction實作 30 minute(s)

Learning Objectives

  • 算出一條直線的間隔,說明支援向量機要最大化什麼
  • 說明支援向量是什麼,以及 C 怎麼影響間隔與支援向量的數量
  • 用加一個特徵的例子說明核函數的想法,並說明 RBF 核的 gamma 怎麼影響過擬合
  • 說明 SVC 為什麼要先標準化,並用 pipeline 寫出來

可以分開的直線有很多條,選哪一條?

兩群點可以用一條直線分開時,這樣的直線通常有無限多條。第 7 課的羅吉斯迴歸會找到其中一條,但有些直線貼著某一邊的點經過,新的資料只要稍微偏一點就分錯了。

支援向量機(support vector machine,SVM)的想法很直接:選離兩邊最近的點都盡量遠的那一條。這個距離叫間隔(margin)。Corinna Cortes 與 Vladimir Vapnik 在 1995 年的論文《Support-Vector Networks》提出了這個方法的軟間隔版本,也就是今天常用的形式。

一條直線寫成 w·x + b = 0。類別標成 +1 與 −1 時,一個點到直線的(帶正負的)距離是:

距離 = y × (w·x + b) / ||w||

答對時是正的,分錯邊時是負的。一條直線的好壞,就看所有點裡最小的那個距離。

逐步看:算三條直線的間隔

六個點,兩個類別。三條候選直線都能把它們分開,但離兩邊的距離不同。

只有最靠近邊界的點說了算

間隔最大的直線只由離它最近的那幾個點決定,這些點叫支援向量(support vector)。把其他點移動一點或刪掉(只要沒有越過間隔),直線完全不會變。

SVC 把 w·x + b 的大小調整成間隔邊上的點剛好等於 ±1,這時候兩條虛線(等於 +1 與 −1)之間的間隔寬度是 2 / ||w||。所以最大化間隔等於讓 ||w|| 盡量小。

訓練好之後:

屬性 內容
svm.support_ 支援向量在訓練資料裡的編號
svm.support_vectors_ 支援向量本身
svm.n_support_ 每個類別有幾個
svm.coef_、svm.intercept_ w 與 b(只有線性核才有 coef_)

逐步看:SVC 找到的邊界與支援向量

40 個用亂數產生的點,兩群分得開。看最後的圖:實線是邊界、虛線是間隔、圈起來的是支援向量。

分不開怎麼辦:軟間隔與 C

真實資料常常分不開,或者為了一個離群點,把間隔擠得很窄也不值得。軟間隔允許有些點進入間隔、甚至分錯邊,但要付出代價。C 決定這個代價有多高:

C 模型的態度 間隔 支援向量 風險
小 寬容,寧可有點犯錯也要間隔寬 寬 多 欠擬合
大 嚴格,盡量不犯錯 窄 少 過擬合

間隔裡面的點和分錯邊的點都算支援向量,所以間隔越寬,支援向量越多。SVC 的預設是 C=1.0。

逐步看:C 怎麼影響間隔

200 個點、兩群有重疊。看輸出的欄位:間隔寬度、支援向量數、訓練與測試準確率。

核函數:把資料送到分得開的空間

有些資料用直線怎麼分都不行,例如一圈包著一圈。但如果多加一個特徵 x1² + x2²(到原點距離的平方),內圈的值都小、外圈的值都大,在三維空間裡用一個平面就能切開。

支援向量機的訓練與預測,最後都只用到兩筆資料的內積。所以不必真的算出高維的特徵,只要有一個函數能直接算出「兩筆資料在高維空間裡的內積」就夠了,這個函數叫核函數(kernel)。

最常用的是 RBF 核(SVC 的預設):

K(a, b) = exp(−gamma × ||a − b||²)

兩個點越近,值越接近 1;越遠越接近 0,可以當成「相似度」。預測時,模型把新資料和每個支援向量比相似度,加權投票。

逐步看:同心圓,直線不行,核函數可以

用 make_circles 產生一圈包一圈的資料。比較三種做法的測試準確率。

互動練習:調 C、換核函數、調 gamma

實心是訓練資料、空心是測試資料。實線是決策邊界,虛線是間隔,黑圈是支援向量。這裡的支援向量機是小工具自己寫的求解器,解的是 SVC 同一個問題,資料少時結果相近。

gamma 與標準化

RBF 核有兩個要一起調的超參數:C 與 gamma。gamma 控制一個訓練點影響的範圍:

gamma 影響範圍 邊界 風險
小 大 平滑,接近直線 欠擬合
大 小 彎彎曲曲,包住每個點 過擬合

SVC 的預設 gamma="scale",也就是 1 / (特徵數 × X.var()),會依資料的變異數調整。

RBF 核裡面有距離,所以支援向量機和 k 近鄰一樣受尺度影響。make_pipeline 可以把標準化和模型接在一起,fit 時只用訓練資料算平均與標準差,比較不會寫錯。

逐步看:gamma 的影響與標準化

前半段用 make_moons 看 gamma;後半段用 students.csv(程式產生的模擬資料,不是任何學校的真實資料)看標準化。

什麼時候用支援向量機

  • 適合:資料量不大(幾千到幾萬筆)、特徵不少、邊界可能彎曲;文字分類也常用線性核。
  • 不適合:資料量很大時,訓練時間會快速增加(SVC 的文件提醒,超過數萬筆可以考慮 LinearSVC 等其他做法)。
  • 要注意:SVC 預設不輸出機率(probability=False),要機率就設 probability=True,訓練會變慢;模型也不像決策樹那樣能直接讀懂。
  • C 與 gamma 要一起調,常見做法是用交叉驗證搜尋(第 14 課)。

實作:寫一個算間隔的函數

完成 margin(w, b, X, y):回傳所有點裡最小的帶正負距離 y × (w·x + b) / ||w||。結果是負的表示有點分錯邊。

你的輸出
預期輸出

小測驗:支援向量機

1.

下面程式會印出什麼?

import numpy as np
w = np.array([3.0, 4.0])
b = -2.0
x = np.array([1.0, 1.0])
print((x @ w + b) / np.linalg.norm(w))
2.

訓練好線性 SVM 之後,刪掉一個離邊界很遠、不是支援向量的訓練點再重新訓練,邊界會怎樣?

3.

把 C 從 100 調到 0.01,通常會發生什麼?

4.

RBF 核的 SVM 訓練準確率 0.99、測試準確率 0.84,幾乎每個訓練點都是支援向量。優先試什麼?

5.

下面哪一種寫法比較不容易造成資料洩漏?

第 1 次作答

重點整理

  • 支援向量機找間隔最大的邊界;間隔寬度是 2 / ||w||。
  • 邊界只由支援向量決定,其他點對它沒有影響。
  • C:小=寬容、間隔寬、支援向量多;大=嚴格、間隔窄。預設 C=1.0。
  • 核函數不必真的算高維特徵,就能得到彎曲的邊界。RBF 核(預設)的 gamma 越大,邊界越彎、越容易過擬合。
  • 裡面有距離,所以要標準化;用 make_pipeline(StandardScaler(), SVC())。
  • 下一課換成文字資料:用字出現的次數與條件機率做分類。
這一課完成了!
Next lesson:單純貝氏與文字分類
你目前沒有登入,學習進度只存在這個瀏覽器。 Login 後,進度會跟著帳號,換電腦也看得到。