支援向量機(Support Vector Machine)

Elven Hu
10 min readApr 6, 2024

--

前言:本文將介紹SVM的基本原理、如何在Python中使用SVM進行分類,以及一些實際應用範例。

支援向量機(Support Vector Machine,SVM)是一種監督式學習模型,用於分類和迴歸分析。

補充:
所謂監督式學習是指從標記的數據中學習預測模型,即模型的輸入數據與對應的輸出數據都已知。
非監督式學習是指從未標記的數據中學習模型,即僅有輸入數據而沒有對應的輸出數據。

SVM的基本原理

SVM的目標是找到一個最佳的超平面(在二維空間中就是一條直線),將不同類別的數據分開。這條超平面應該使得兩個不同類別的數據點距離超平面的間隔最大化,這些距離稱為邊界(margin),如下圖A。

圖片來源:https://www.geeksforgeeks.org/introduction-to-support-vector-machines-svm/

SVM 的優點之一是能夠處理高維數據,並且在應用中表現良好。它還可以通過使用不同的kernel函數來適應不同類型的數據。

在SVM中,核函數(kernel function)是一個用來計算數據點之間相似度的函數。SVM 在特徵空間中尋找一個最佳的超平面來分隔不同類別的數據點,但有時數據可能不是線性可分的,如圖B,這時就需要使用核函數將數據映射到高維空間,使得在這個高維空間中數據變得線性可分。

四種SVC分類器:

  1. LinearSVC (線性)
  2. kernel=’linear’ (線性)
  3. kernel=’poly’ (非線性)
  4. kernel=’rbf’ (非線性)
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
from sklearn.svm import LinearSVC
from sklearn.metrics import accuracy_score

# 加載鳶尾花數據集
iris = datasets.load_iris()
X = iris.data
y = iris.target

# 將數據集分為訓練集和測試集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0)

# 標準化特徵
sc = StandardScaler()
X_train = sc.fit_transform(X_train)
X_test = sc.transform(X_test)

# 線性核函數 (LinearSVC)
svm_linear_svc = LinearSVC(random_state=0)
svm_linear_svc.fit(X_train, y_train)
y_pred_linear_svc = svm_linear_svc.predict(X_test)
accuracy_linear_svc = accuracy_score(y_test, y_pred_linear_svc)
print('線性核函數 (LinearSVC) 準確率:', accuracy_linear_svc)

# 線性核函數 (SVC)
svm_linear = SVC(kernel='linear', random_state=0)
svm_linear.fit(X_train, y_train)
y_pred_linear = svm_linear.predict(X_test)
accuracy_linear = accuracy_score(y_test, y_pred_linear)
print('線性核函數 (SVC) 準確率:', accuracy_linear)

# 多項式核函數
svm_poly = SVC(kernel='poly', degree=3, random_state=0)
svm_poly.fit(X_train, y_train)
y_pred_poly = svm_poly.predict(X_test)
accuracy_poly = accuracy_score(y_test, y_pred_poly)
print('多項式核函數準確率:', accuracy_poly)

# RBF 核函數
svm_rbf = SVC(kernel='rbf', random_state=0)
svm_rbf.fit(X_train, y_train)
y_pred_rbf = svm_rbf.predict(X_test)
accuracy_rbf = accuracy_score(y_test, y_pred_rbf)
print('RBF 核函數準確率:', accuracy_rbf)
線性核函數 (LinearSVC) 準確率: 0.9555555555555556
線性核函數 (SVC) 準確率: 0.9777777777777777
多項式核函數準確率: 0.8888888888888888
RBF 核函數準確率: 0.9777777777777777

另外,SVM 也能做回歸分析,叫做SVR(Support Vector Regression)

支持向量回歸(Support Vector Regression, SVR)是一種用於執行回歸任務的機器學習算法。它與支持向量機(SVM)類似,但適用於回歸問題。

SVR的基本原理

SVR模型可以簡單理解為,通過在每個訓練樣本周圍創建一個”間隔帶”,這個「間隔帶」的間距為ϵ,對所有落入到間隔帶內的樣本不計算損失,並最小化損失和最大化”間隔帶”的寬度來找到最佳的模型,同時利用核函數處理非線性問題,從而實現回歸任務。

圖片來源:https://zhuanlan.zhihu.com/p/400028363

上圖顯示了SVR的基本狀況:

  1. f(x)=wx+b是我們最終要求得的模型函數
  2. f(x)+ ϵ和f(x)- ϵ是間隔帶的上下邊緣

三種SVR迴歸器:

  1. kernel=’linear’ (線性)
  2. kernel=’poly’ (非線性)
  3. kernel=’rbf’ (非線性)
import matplotlib.pyplot as plt
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVR
from sklearn.metrics import r2_score

# 加載波士頓房屋數據集
boston = load_boston()
X = boston.data
y = boston.target

# 將數據集分為訓練集和測試集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)

# 標準化特徵
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)

# 創建 SVR 模型並訓練
svr_rbf = SVR(kernel='rbf', C=100, gamma=0.1)
svr_lin = SVR(kernel='linear', C=100)
svr_poly = SVR(kernel='poly', C=100, degree=3)

svr_rbf.fit(X_train, y_train)
svr_lin.fit(X_train, y_train)
svr_poly.fit(X_train, y_train)

# 進行預測
y_pred_rbf = svr_rbf.predict(X_test)
y_pred_lin = svr_lin.predict(X_test)
y_pred_poly = svr_poly.predict(X_test)

# 計算 R 平方值
r2_rbf = r2_score(y_test, y_pred_rbf)
r2_lin = r2_score(y_test, y_pred_lin)
r2_poly = r2_score(y_test, y_pred_poly)

# 可視化預測結果
plt.figure(figsize=(10, 6))
plt.scatter(y_test, y_pred_rbf, color='navy', lw=2, label='RBF model')
plt.scatter(y_test, y_pred_lin, color='c', lw=2, label='Linear model')
plt.scatter(y_test, y_pred_poly, color='cornflowerblue', lw=2, label='Polynomial model')
plt.plot([y_test.min(), y_test.max()], [y_test.min(), y_test.max()], 'k--', lw=2)
plt.xlabel("Actual Price")
plt.ylabel("Predicted Price")
plt.title("Support Vector Regression")
plt.legend()
plt.show()

print("RBF Kernel SVR R^2:", r2_rbf)
print("Linear Kernel SVR R^2:", r2_lin)
print("Polynomial Kernel SVR R^2:", r2_poly)
RBF Kernel SVR R^2: 0.7494542120027616
Linear Kernel SVR R^2: 0.5254241262895836
Polynomial Kernel SVR R^2: 0.663164777573324

計算三種不同核函數的 SVR 模型的 R 平方值,這是衡量模型預測準確度的一個指標。 R 平方值越接近 1,表示模型的預測越準確。

上圖,每個點代表一個房屋的實際價格和預測價格,而黑色虛線則代表理想的預測線。

總結

SVM(Support Vector Machine)和 SVR(Support Vector Regression)是基於支持向量機(SVM)算法的兩個變體,用於分類和回歸任務。

總體來說,SVM 和 SVR 都是基於相同的原理,但適用於不同的問題類型。SVM 用於分類問題,SVR 用於回歸問題。在應用中,你可以根據你的問題類型和需求選擇適合的模型。

--

--