深入SVM:支持向量機核的作用是什麼
您可能聽説過所謂的內核技巧,這是一種支持向量機(SVMs)處理非線性數據的小技巧。這個想法是將數據映射到一個高維空間,在這個空間中數據變成線性,然後應用一個簡單的線性支持向量機。聽起來很複雜,但操作起來確實如此。儘管理解該算法的工作原理可能比較困難,但理解它們試圖實現的目標卻相當容易。往下讀,自然就會明白了!
支持向量機是如何工作的呢?支持向量機可用於分類和迴歸任務,但是在本文中,我們將主要關注前者。讓我們首先考慮具有線性可分的兩個類的數據。我們將創建兩個獨立的點團,並使用scikit-learn對它們擬合成一個線性支持向量機。注意,我們在擬合模型之前對數據進行了標準化,因為支持向量機對特徵的尺度很敏感。
X, y = make_blobs(n_samples=100, centers=2, n_features=2, random_state=42)
pipe = make_pipeline(StandardScaler(), LinearSVC(C=1, loss="hinge"))
pipe.fit(X, y)
plot_svm(pipe, X)
customplot_svm()函數的輸出將在下面看到,它由相當多的matplotlib代碼組成。
有許多行可以完美地將這兩個類分開,確切地説,有無窮多行。SVM擬合的直線的特殊之處在於,它是兩個虛線標記的直線之間的中間線,並且這條線距離兩個類之間的距離近似相等。這樣,支持向量機的決策線(標記為實黑線)離兩個類的距離越遠越好,保證了模型能很好地泛化到新的例子。
用紅色圈出的直線邊界上的觀測稱為支持向量,因為它們確定直線的位置。如果我們增加一些這條直線外的觀察,它不會改變位置。
注:這是一個硬邊分類的例子,這意味着不允許觀察到邊界。或者,我們可以做一個軟邊界分類:允許對頻段進行一些加寬。這會減小異常值的影響,並且可以由LinearSVC()中的參數C控制:例如,我們原本將其設置為1,隨後減少到0.1,將會導致更寬的直線,但其中會有一些觀察值。不管怎樣,這和我們的內容沒有什麼關係。
現實生活中的大多數數據集都不是線性可分的。讓我們看看線性SVM是如何處理月亮形狀的數據的。
X, y = make_moons(n_samples=100, noise=0.1, random_state=42)
pipe = make_pipeline(StandardScaler(), LinearSVC(C=1, loss="hinge"))
pipe.fit(X, y)
plot_svm(pipe, X)
這看起來不太好,讓我們想想該怎麼處理這樣的數據。
將數據映射到更高維度
在我們討論支持向量機內核和它們的作用之前,讓我們先看看它們利用的一個思想:在高維空間中,數據變得線性可分的可能性更大。
下面兩幅圖清楚地説明了這一點。當我們只有一個特徵x1時,我們不能用一條線把數據分開。加上另一個特徵x2,等於x1的平方時,分離這兩個類變得容易。
支持向量機的內核到底是什麼?
那麼,內核技巧是關於什麼的呢?這只是一種向數據添加更多特性、希望使其線性可分的智能方法。因為添加它們將使模型時間複雜度增加,創作者利用一些神奇的數學特性(不在本文的範圍),使我們能夠獲得相同的結果而模型運行速度並沒有變慢。
兩種常見的核是多項式核和高斯徑向基函數(RBF)核。它們添加的特性的類型不同,讓我們來看看它們的功能!
多項式核添加的多項式特徵
創造更多特徵的一種方法是在一定程度上使用它們的多項式組合。例如,有兩個特徵A和B, 2次多項式將產生6個特徵:1(任何特徵都為0次冪),A, B, A², B²和AB。我們可以手動使用scikit-learn庫的PolynomialFeatures()很容易地添加這些功能:
X, y = make_moons(n_samples=100, noise=0.1, random_state=42)
pipe = make_pipeline(StandardScaler(),
PolynomialFeatures(degree=3),
LinearSVC(C=5))
pipe.fit(X, y)
plot_svm(pipe, X)
或者我們可以簡單地使用多項式核:
X, y = make_moons(n_samples=100, noise=0.1, random_state=42)
pipe = make_pipeline(StandardScaler(), SVC(kernel="poly", degree=3, C=5, coef0=1))
pipe.fit(X, y)
plot_svm(pipe, X)
您可以自己驗證兩個實現生成兩個大致相同的圖形,有點像這樣:
使用內核的好處是,您可以調整核的屬性,從而增加數據在這個高維空間中線性可分的可能性,而不會降低模型的速度。
對於我們的月亮數據,很明顯,從散點圖可以看出3次多項式是足夠的。但是,對於更復雜的數據集,可能需要使用更高的次數。這時內核技巧的威力可以更好地體現出來。
基於高斯RBF核的相似性特徵
另一種向數據添加更多特徵的方法是使用所謂的相似特徵。相似特性度量現有特性的值與地標的距離。讓我們實際一點:我們有一個只有一個特徵的數據集,x1。我們想要創建兩個相似特徵,所以我們選擇兩個標準,即從我們的單一特徵中選擇參考值。比如-1和1。然後,對於每個x1的值,我們計算它與第一個地標的距離。這是我們新的相似性特徵,x2。然後我們做同樣的事情,比較x1和第二個參考值來得到x3。現在我們甚至不需要原始的特性x1!這兩個新的相似特徵使我們的數據很容易分離。
那麼,如何計算每次目標點到參考值的距離呢?一個普遍的選擇是使用高斯徑向基函數RBF。定義為:
其中x是我們最初的特徵,而參數γ是0.3。
例如,在我們唯一的原始特徵上,第一次觀察的得分為-3。我們計算x2=exp(-0.3 *(3 -(1))²)≈0.30,x3=exp(-0.3 *(3 -(1))²)≈0.01。這是右圖最下面的兩點。
在上面的例子中,我們幸運地選擇了兩個恰巧運行良好的參考。在實踐中,一個特徵可能需要很多參考,這意味着許多新的相似特徵。這將大大降低支持向量機的速度——除非我們使用內核技巧!與多項式核類似,RBF核允許我們獲得完全相同的結果,就好像我們在原始特徵的每個值上都添加了一個參考,實現過程而不需要我們去做。讓我們在月亮形狀的數據上試試。
X, y = make_moons(n_samples=100, noise=0.1, random_state=42)
pipe = make_pipeline(StandardScaler(), SVC(kernel="rbf", gamma=0.3, C=5))
pipe.fit(X, y)
plot_svm(pipe, X)
決策邊界看起來相當不錯,但是您可能已經注意到一些分類錯誤的示例。我們可以通過調整參數γ的方式來解決這個問題,它作為一個正則化器——越小則決策邊界越平滑,這可以防止過擬合。然而,在本例中,我們似乎還沒有完全匹配,所以我們將γ增加到0.5。
現在所有的特徵都正確分類了!
總結
支持向量機通過尋找離數據儘可能遠的線性決策邊界來進行分類。它們在線性可分離數據方面工作得很好,但在其他方面則經常失敗。
為了使非線性數據線性可分(從而方便支持向量機),我們可以給數據添加更多的特徵,因為在高維空間中,數據線性可分的概率會增加。
兩種常用的新特徵類型是現有特徵的多項式組合(多項式特徵)和從參考計算的距離,即一些參考值(相似特徵)。
實際上,添加它們可能會降低模型的速度。
內核技巧策略利用一些數學屬性來提供相同的結果並有效提高模型速度,就像我們添加了一些額外的特性,而速度上沒有添加它們一樣。
多項式核和RBF核可以分別添加多項式特徵和相似度特徵。
引用
Geron A., 2019, 2nd edition, Hands-On Machine Learning with Scikit-Learn and TensorFlow: Concepts, Tools, and Techniques to Build Intelligent Systems
感謝閲讀!我希望你學到一些有用的東西,這將提高你的項目水平
作者:Michał Oleszak
本文代碼:https://github.com/MichalOleszak/KnowledgeBank/blob/master/blog_posts/svm_kernels/svm_kernels.ipynb)
deephub翻譯組:孟翔傑