# 機器學習 03:支援向量機 ###### tags: `ML model`, `SVM` ## SVM分類 - **線性SVM** 找到一個決策邊界(decision boundary)讓兩類之間的邊界(margins)最大化,使其可以完美區隔開來。 ![](https://i.imgur.com/82N3dEI.png) 以向量形式: ![](https://i.imgur.com/DpKjQiV.png) 決策邊界是節測函數等於 0 的集合,而決策函數等於 1 和 -1 的點,會左右形成一個邊距,所以 SVM 的訓練過程也是尋找適當的 w 和 b 找出最寬的邊距及避免邊距違規(margin violation,實例可以在街道中間或錯誤的那邊)。 ![](https://i.imgur.com/zEFWoQx.png) 若在兩條邊界各取一點 $x_-$ 和 $x_+$,則我們要求的就是 margin 最大寬度 = $x_-$ 和 $x_+$ 於法向量的投影,也就是 $Max(\frac{2}{|\vec W|}$)。 而要求 $Max(\frac{2}{|\vec W|}$) 也就是微分要趨近於 0: $Max(\frac{2}{|\vec W|}$) = $Min(\frac{2}{|\vec W|}$)' = $Min(\frac{-2}{|\vec W|^2}$) = $Min(\frac{1}{2}|\vec W|^2) = Min(\frac{1}{2}W^TW)$ 此外 SVM 對特徵的尺度很敏感: ![](https://i.imgur.com/H4KOFt6.png) - **硬邊距分類(hard margin classification)** 嚴格要求所有實例必須在街道外,稱為硬邊距分類,但此做法有兩個缺點 1. 只能處理可線性分割的資料 2. 對離群值敏感 ![](https://i.imgur.com/vxHBQoZ.png) 在左圖中,無法找到硬邊距;而右圖的決策邊界與沒有離群值的資料有很大的差異。 **硬邊距分類的分類目標為:$Min (\frac{1}{2}W^TW)$** - **軟邊距分類(soft margin classification)** 避免這些問題是使用更靈活的模型,除了要讓街道盡量寬大之外,也要放寬邊距違規實例數(margin violation,實例可以在街道中間或錯誤的那邊)。 因此 SVM 有一個超參數為:對於誤差項的懲罰係數 C,當 C 上升,邊距違規數量下降。而同時若 SVM 過擬合時,可以降低 C 來將它正則化。 ![](https://i.imgur.com/O6hYgYI.png) **軟邊距分類的分類目標為:$Min(\frac{1}{2}W^TW + C \sum\limits_{i=1}^mζ^{(i)})$,其中 $ζ^{(i)}$ 為第 i 個實例允許違規邊距的程度。** --- 以 sklearn 實現: ```python= import numpy as np from sklearn import datasets from sklearn.pipeline import Pipeline from sklearn.preprocessing import StandardScaler from sklearn.svm import LinearSVC iris = datasets.load_iris() X = iris["data"][:, (2, 3)] # petal length, petal width y = (iris["target"] == 2).astype(np.float64) # Iris virginica svm_clf = Pipeline([ ("scaler", StandardScaler()), # 務必將 loss 設為 hinge(用於最大間格分類) ("linear_svc", LinearSVC(C=1, loss="hinge", random_state=42)), ]) svm_clf.fit(X, y) ``` --- - **非線性 SVM 分類** 最簡單的做法可用 PolynomialFeatures 將特徵轉換成高維特徵,並搭配 StandardScaler 和 LinearSVC。 ![](https://i.imgur.com/V7fYMjU.png) 話雖如此,在多項式次數很低的情況下,這個方法無法處理很複雜的資料;在次數很高的情況下,會建立大量特徵讓模型過於緩慢。 - 多項式 kernal 這是一種不必實際加入許多多項式特徵,就可以得到一樣結果的數學技術。 ```python= from sklearn.svm import SVC poly_kernel_svm_clf = Pipeline([ ("scaler", StandardScaler()), # degree:幾次多項式 # coef0 (r):控制模型受高次多項式和低次多項式的影響程度 ("svm_clf", SVC(kernel="poly", degree=3, coef0=1, C=5)) ]) poly_kernel_svm_clf.fit(X, y) ``` ![](https://i.imgur.com/3kTcpiE.png) 如果模型過擬合,可以降低多項是次數,如果欠擬合,可以增加多項式次數。 - 高斯 RBF Kernal - **核函數Kernal Trick** 核函數是在數據的每一類中選定一組點(稱為 Landmark 點),然後計算每一個數據點與這個 Landmark 點的相似度,這種相似度的定義方式就稱為核函數。高斯 RBF Kernal 為: <font size=5>**$$RBF = e^{-\gamma||x-l||^2} = e^{-\gamma \times Distance^2}$$**</font> 其中**超參數 $\gamma$ 為正則化參數,類似上面提到的 C,如果過擬合就要降低它($\gamma$ 越大越容易得到封閉決策邊界)**。 ![](https://i.imgur.com/ebzllAH.png) Kernal Trick 目標具體而言就是計算決策函數,其中 θ 為特徵,f 為相似度函數,計算每一個點與其他 Landmark 的相似度,當 x 和 landmark 十分接近時,特徵值為約等於 1;當 x 和 landmark 距離很遠時,特徵值為約等於 0: ![](https://i.imgur.com/ymZ3s8T.png) 訓練集中的每一個點都需要被當成 Landmark 點,即假設訓練集中有(A,B,C,D,E)五個點,當把 A 作為訓練對象時,BCDE 四個點均為 Landmark 點,此時要分別計算 A 點與 BCDE 四點的相似度,然後分別乘以對應的 θ 值(該值為提前預設,並在模型訓練的過程中不斷更新)並相加,當最後的和大於等於 0 時,我們把A點歸類為 y = 1,否則歸類為 y = 0。**SVM 的訓練過程,就是不斷尋找 θ 最小值的過程。而決策線就是集合所有 y = 0的點**。 以 sklearn 實現: ```python= rbf_kernel_svm_clf = Pipeline([ ("scaler", StandardScaler()), ("svm_clf", SVC(kernel="rbf", gamma=5, C=0.001)) ]) rbf_kernel_svm_clf.fit(X, y) ``` --- ### SVM回歸 SVM回歸的目標不是控制邊距違規並在兩個類別之間找到最寬的街道,而是盡量將所有實例放在街道上面,同時控制街道之外的實例。而控制街道寬度的超參數是 $ε$ ![](https://i.imgur.com/8HQU58z.png) 以 sklearn 實現: ```python= from sklearn.svm import SVR svm_poly_reg = SVR(kernel="poly", degree=2, C=100, epsilon=0.1, gamma="scale") svm_poly_reg.fit(X, y) ``` 也可以使用 kernelized SVM 來處理非線性回歸任務: ![](https://i.imgur.com/wsGNdhC.png) 以 sklearn 實現: ```python= from sklearn.svm import SVR svm_poly_reg = SVR(kernel="poly", degree=2, C=100, epsilon=0.1, gamma="scale") svm_poly_reg.fit(X, y) ``` --- ## 計算複雜度 雖然 SVC 支援 kernal trick,但由於時間複雜度介於 $O(m^2 \times n)$ ~ $O(m^3 \times n)$,代表當訓練實例變多時,速度會急遽下降。<font color="#f00">**因此這個演算法非常適合複雜的小型或中型資料集,尤其是特徵很稀疏的情況**</font>。 | 類別 | 時間複雜度 | 支援離合訓練 | 需要縮放 | kernal trick | | --------- | ---------- | ------------ | -------- | ------------ | | LinearSVC | $O(m \times n)$ | 否 | 是 | 無 | | SGDClassifier | $O(m \times n)$| 是 | 是 | 無 | | SVC | $O(m^2 \times n)$ ~ $O(m^3 \times n)$ | 否 | 是 | 有 | --- ### reference 1. 精通機器學習,使用 Scikit-Learn, Keras 與 Tensorflow-Aurelien Greon 2. [機器學習-支撐向量機(support vector machine, SVM)詳細推導](https://medium.com/@chih.sheng.huang821/%E6%A9%9F%E5%99%A8%E5%AD%B8%E7%BF%92-%E6%94%AF%E6%92%90%E5%90%91%E9%87%8F%E6%A9%9F-support-vector-machine-svm-%E8%A9%B3%E7%B4%B0%E6%8E%A8%E5%B0%8E-c320098a3d2e) 3. [[吴恩达机器学习笔记]12支持向量机4核函数和标记点kernels and landmark](https://blog.csdn.net/u013555719/article/details/82469039) 4. [SVM纯讲解(无数学公式讲解)](https://zhuanlan.zhihu.com/p/54551404)