機器學習新手必看:一文搞定SVM演算法

景略集智發表於2019-03-04

掌握機器學習演算法根本不難。大多數初學者從迴歸開始學習,雖然學習和使用它很簡單,但是這能解決我們的目的嗎?當然不能!因為你可以做的不僅僅是迴歸問題!

我們可以將機器學習演算法看作是裝滿斧頭、劍、刀片、弓、匕首等的軍械庫。你有各種工具,但你應該學會在正確的時間綜合使用它們。

作為一個類比,我們將“迴歸”看作一把能夠有效切割資料的劍,但它無法處理高度複雜的資料。相反,支援向量機(SVM)演算法就像一把鋒利的刀 ——它可以在較小的資料集上工作,而在這些小資料集上面,在搭建模型時,它的效能卻強大的多。

本文我們一起學習 SVM 機器學習演算法從初級到高階的相關知識。示例+程式碼,一文搞定支援向量機演算法。

目錄

  • 什麼是 SVM 演算法?

  • SVM 演算法是如何工作的 ?

  • 如何在 Python 和 R 語言中實現 SVM?

  • 如何調整 SVM 的引數?

  • SVM 的優點和缺點

什麼是 SVM 演算法?

支援向量機(SVM) 是一個監督學習演算法,既可以用於分類問題也可以用於迴歸問題。但是,SVM演算法還是主要用在分類問題中。在 SVM 演算法中,我們將資料繪製在 n 維空間中(n 代表資料的特徵數),每個特徵數的值是特定座標的值。然後我們通過查詢可以將資料分成兩類的超平面(請參照下圖)。

機器學習新手必看:一文搞定SVM演算法

支援向量指的是觀察的樣本在 n 維空間中的座標,SVM 是將樣本分成兩類的最佳超平面。

SVM 是如何工作的?

上面的簡介告訴我們 SVM 是通過超平面將兩類樣本分開。現在我們的主要問題是:“如何將兩類樣本分開”。別擔心,這個問題並不像你想象的那麼難!

首先我們來看:

找出正確的超平面(場景-1):在這裡,我們有三個超平面(A,B 和 C)。 現在,找出正確的超平面並用星和圓區分。

機器學習新手必看:一文搞定SVM演算法

對於識別正確的超平面,你需要記住一條經驗法則:“選擇更好地隔離兩個類的超平面”。在我們這裡的例子中,超平面“B”非常出色地完成了這項工作。

找出正確的超平面(場景-2):在這裡,我們有三個超平面(A,B 和 C),並且所有的類都被進行了很好的隔離。現在,我們如何確定正確的超平面?

機器學習新手必看:一文搞定SVM演算法

在這裡,最大化最近資料點(任一類)和超平面之間的距離將有助於我們決定正確的超平面。這個距離被稱為邊距。請看下圖:

機器學習新手必看:一文搞定SVM演算法

在上面,你可以看到,與 A 和 B 相比,超平面 C 的邊距很大。因此,我們將這個正確的超平面命名為 C.另一個選擇邊距更大超平面的原因是魯棒性更強。如果我們選擇一個具有較低邊距的超平面,那麼很有可能會錯誤分類。

找出正確的超平面(場景-3):提示:使用上一節討論的規則來找出正確的超平面。

機器學習新手必看:一文搞定SVM演算法

可能有些朋友會選擇超平面 B,因為它比 A 具有更高的邊距。但是,這裡有一個問題,SVM 演算法在選擇超平面方面,會優先考慮正確分類而非更大的邊距。這裡,超平面 B 有分類錯誤,而 A 已經正確分類。因此,A 才是正確的超平面。

我們能區分兩個類別嗎?(情景-4):下圖中,我無法用一條直線將這兩個類別分開,因為其中一個星星位於圈圈的領域之內,也就是離散值。

機器學習新手必看:一文搞定SVM演算法

我之前提過,如果一個星跑到了另一邊,那麼它就是星類別的離散值。SVM 的一個特徵就是會忽略離散值並找到具有最大邊距的超平面。因此,我們可以說,SVM 對於離散值具有魯棒性。

機器學習新手必看:一文搞定SVM演算法

找到超平面以分離不同類(場景-5):在下面的場景中,我們沒法讓線性超平面區分這兩個類,那麼 SVM 如何對這兩個類進行分類?到現在為止,我們只看到了線性超平面。

機器學習新手必看:一文搞定SVM演算法

SVM 可以很方便的解決這個問題!它可以通過引入附加特徵解決。在這裡,我們增加一個新的 z=x^2+y^2 特徵。現在,我們繪製軸 x 和 z 上的資料點:

機器學習新手必看:一文搞定SVM演算法

在上面的情節中,要考慮的要點是:

  • z 的所有值總是正值,因為它是是 x 和 y 的平方和。

  • 在原始圖中,紅色點離 x 和 y 軸更近,z 值相對較小,星相對較遠會有較大的 z 值。

在 SVM 中,這兩個類之間很容易有一個線性超平面。但是,另一個亟待解決的問題是,我們是否需要手動新增此功能才能擁有超平面?不需要,SVM 有一個叫核函式的功能。核函式具有將低維資料轉化成高維資料的作用。它將不可分離的問題轉換成可分離的問題,這些函式被稱為核心。它主要用於非線性分離問題。簡而言之,它執行一些非常複雜的資料轉換,然後根據您定義的標籤或輸出找出分離資料的過程。

當我們在原始輸入空間中檢視超平面時,它看起來像一個圓圈:

機器學習新手必看:一文搞定SVM演算法

現在,我們來看看在資料科學挑戰中應用 SVM 演算法的方法。

如何在 Python 和 R 語言中實現 SVM?

在 Python 中,scikit-learn 是一個在機器學習演算法中被廣泛使用的庫,SVM 也可以在 scikit-learn 庫中使用,並遵循相同的結構(匯入庫,物件建立,擬合模型和預測)。讓我們來看下面的程式碼:

#Import Library
from sklearn import svm
#Assumed you have, X (predictor) and Y (target) for training data set and x_test(predictor) of test_dataset
# Create SVM classification object 
model = svm.svc(kernel=`linear`, c=1, gamma=1) 
# there is various option associated with it, like changing kernel, gamma and C value. Will discuss more # about it in next section.Train the model using the training sets and check score
model.fit(X, y)
model.score(X, y)
#Predict Output
predicted= model.predict(x_test)
複製程式碼

使用 R 語言中的 e1071 軟體包可以輕鬆建立 SVM。它具有輔助函式以及 Naive Bayes 分類器的程式碼。在 R 和 Python 中建立 SVM 遵循類似的方法,現在讓我們來看看下面的程式碼

#Import Library
require(e1071) #Contains the SVM 
Train <- read.csv(file.choose())
Test <- read.csv(file.choose())
# there are various options associated with SVM training; like changing kernel, gamma and C value.

# create model
model <- svm(Target~Predictor1+Predictor2+Predictor3,data=Train,kernel=`linear`,gamma=0.2,cost=100)

#Predict Output
preds <- predict(model,Test)
table(preds)
複製程式碼

如何調整 SVM 的引數?

為機器學習演算法調整引數值有效地提高了模型效能。我們來看看 SVM 可用的引數列表。

sklearn.svm.SVC(C=1.0, kernel=`rbf`, degree=3, gamma=0.0, coef0=0.0, shrinking=True, probability=False,tol=0.001, cache_size=200, class_weight=None, verbose=False, max_iter=-1, random_state=None)
複製程式碼

我們來討論其中最重要的三個引數為: “kernel”, “gamma” 和“C”。

Kernel(核函式):我們已經在上面介紹過了。這裡,我們有不少適用的選擇,如“linear”,“rbf”,“poly”等等(預設值是“rbf”)。這裡“rbf”和“poly”對於非線性超平面很有用。我們來看看這個例子,我們已經使用線性核函式對雙特徵鳶尾花資料集的兩個特徵進行了分類。

示例:使用線性核函式

import numpy as np
import matplotlib.pyplot as plt
from sklearn import svm, datasets
複製程式碼
# import some data to play with
iris = datasets.load_iris()
X = iris.data[:, :2] # we only take the first two features. We could
 # avoid this ugly slicing by using a two-dim dataset
y = iris.target
複製程式碼
# we create an instance of SVM and fit out data. We do not scale our
# data since we want to plot the support vectors
C = 1.0 # SVM regularization parameter
svc = svm.SVC(kernel=`linear`, C=1,gamma=0).fit(X, y)
複製程式碼
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
h = (x_max / x_min)/100
xx, yy = np.meshgrid(np.arange(x_min, x_max, h),
 np.arange(y_min, y_max, h))

複製程式碼
plt.subplot(1, 1, 1)
Z = svc.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
plt.contourf(xx, yy, Z, cmap=plt.cm.Paired, alpha=0.8)
複製程式碼
plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.Paired)
plt.xlabel(`Sepal length`)
plt.ylabel(`Sepal width`)
plt.xlim(xx.min(), xx.max())
plt.title(`SVC with linear kernel`)
plt.show()
複製程式碼
機器學習新手必看:一文搞定SVM演算法

示例:使用rbf核函式

將核函式型別更改為 rbf,並檢視影響。

svc = svm.SVC(kernel=`rbf`, C=1,gamma=0).fit(X, y)
複製程式碼
機器學習新手必看:一文搞定SVM演算法

如果你有大量特徵(> 1000),我建議選擇線性核函式,因為它更有可能在高維空間中線性分離。此外,也可以使用 rbf,但不要忘記交叉驗證其引數以避免過度擬合。

gamma:rbf 函式、Poly 函式和 S 型函式的係數。gamma 值越大,SVM 就會傾向於越準確的劃分每一個訓練集裡的資料,這會導致泛化誤差較大和過擬合問題。

例如:讓我們區分一下,如果我們有不同的 gamma 值,如 0,10 或 100:

svc = svm.SVC(kernel=`rbf`, C=1,gamma=0).fit(X, y)
複製程式碼
機器學習新手必看:一文搞定SVM演算法

C: 錯誤項的懲罰引數 C。它還控制平滑決策邊界和正確分類訓練點之間的權衡。

機器學習新手必看:一文搞定SVM演算法

我們應該始終考慮交叉驗證分數,以有效組合這些引數並避免過度擬合。

在 R 語言中,SVM 的引數可以像在 Python 中一樣進行調整。下面提到的是 e1071 軟體包中的相應引數:

  • 核心引數可以調整為“線性”,“聚合”,“rbf”等。

  • Gamma 值可以通過設定“Gamma”引數進行調整。

  • Python 中的 C 值由 R 中的“Cost”引數進行調整。

SVM 的優點和缺點

優點:

  • 對於邊界清晰的分類問題效果好;

  • 對高維分類問題效果好;

  • 當維度高於樣本數的時候,SVM 較為有效;

  • 因為最終只使用訓練集中的支援向量,所以節約記憶體

缺點:

  • 當資料量較大時,訓練時間會較長;

  • 當資料集的噪音過多時,表現不好;

  • SVM 不直接提供結果的概率估計,它在計算時直接使用 5 倍交叉驗證。

實踐練習

找到有效的附加特徵,以便得到用於分離類的超平面,如下圖所示:

機器學習新手必看:一文搞定SVM演算法

在下面的註釋部分回答變數名稱。

結尾筆記

在本文中,我們詳細介紹了機器學習演算法 SVM,包括了它的工作概念,Python 中的實現過程,通過調整引數來優化模型的技巧,優點和缺點,以及最後的練習題。建議你親自使用 SVM 並通過調整引數來分析該模型的功能。

集智主站出品的 Scikit-learn 教程也曾講過如何用 SVM 演算法解決問題:點選檢視


新手福利

假如你是機器學習小白,但又希望能以最高效的方式學習人工智慧知識,我們這裡正好有個免費學習AI的機會,讓你從零到精通變身AI工程師,不瞭解一下?

機會傳送門:戳這裡!!

這可能是正點趕上AI這班車的最好機會,不要錯過哦。

相關文章