掌握機器學習算法并不是什么神話。對于大多數(shù)機器學習初學者來說,回歸算法是很多人接觸到的第一類算法,它易于理解、方便使用,堪稱學習工作中的一大神器,但它真的是萬能的嗎?通過這篇文章,論智希望大家明白,有時候,生活中的一些萬金油工具其實并不是我們的唯一選擇。
如果把機器學習看做是一個堆滿刀、劍、斧、弓等兵器的軍械庫,里面有成千上萬種工具,我們的選擇余地的確很大,但我們應該學會在正確的時間和場合使用正確的武器。如果把回歸算法看作是其中的劍,它可以輕松刺穿敵人(數(shù)據(jù))的堅甲,但不能被庖丁用來解牛。對于這類問題高度復雜的數(shù)據(jù)處理任務,一把鋒利的“小刀”——支持向量機(SVM)往往更有效——它可以在較小的數(shù)據(jù)集上工作,并構(gòu)建出更強大的模型。
1. 什么是支持向量機?
在機器學習領域中,支持向量機”(SVM)是一種可用于分類和回歸任務監(jiān)督學習算法,在實踐中,它的主要應用場景是分類。為了解釋這個算法,首先我們可以想象一大堆數(shù)據(jù),其中每個數(shù)據(jù)是高維空間中的一個點,數(shù)據(jù)的特征有多少,空間的維數(shù)就有多少。相應的,數(shù)據(jù)的位置就是其對應各特征的坐標值。為了用一個超平面盡可能完美地分類這些數(shù)據(jù)點,我們就要用SVM算法來找到這個超平面。
在這個算法中,所謂“支持向量”指的是那些在間隔區(qū)邊緣的訓練樣本點,而“機”則是用于分類的那個最佳決策邊界(線/面/超平面)。
2. SVM的工作原理
下面我們用圖像演示如何找出正確的超平面的幾種方法。
情景1
下圖中有三個超平面:A、B和C。那么其中哪個是正確的邊界呢?只需記住一點:SVM選擇的是能分類兩種數(shù)據(jù)的決策邊界。很顯然,相比A和C,B更好地分類了圓和星,所以它是正確的超平面。
情景2
下圖中同樣有A、B、C三個超平面,和情景1不同,這次三個超平面都很好地完成了分類,那么其中哪個是正確的超平面呢?對此,我們再修改一下之前的表述:SVM選擇的是能更好地分類兩種數(shù)據(jù)的決策邊界。
在這里,我們可以繪制數(shù)據(jù)到?jīng)Q策邊界的距離來輔助判斷。如下圖所示,無論是星還是圓,它們到C的距離都是最遠的,因此這里C就是我們要找的最佳決策邊界。
之所以選擇邊距更遠的超平面,是因為它更穩(wěn)健,容錯率更高。如果選擇A或C,如果后期我們繼續(xù)輸入樣本,它們發(fā)生錯誤分類的可能性會更高。
情景3
這里我們先看圖,試著用上一情景的結(jié)論做出選擇。
也許有些讀者最終選擇了B,因為兩類數(shù)據(jù)和它的邊距較A更遠。但是其中有個問題,就是B沒有正確分類,而A正確分類了。那么在SVM算法面前,正確分類和最大邊距究竟孰重孰輕?很顯然,SVM首先考慮的是正確分類,其次才是優(yōu)化數(shù)據(jù)到?jīng)Q策邊界的距離。情景3的正確超平面是A。
情景4
在前幾個例子里,雖然我們把決策邊界表述為超平面,但它們在圖像中都是一條直線,這其實是不符合現(xiàn)實的。如在下圖中,我們就無法用直線進行分類。
紅色的圓點之間出現(xiàn)了一顆藍色的星,并且它和其他同類數(shù)據(jù)不在同一側(cè)。那么我們是否要繪制一條曲線來分類?或者說,是否要把它單獨氛圍一類?答案是否定的。
對比情景3,我們可以推斷此處的星是一個異常值,所以在這里SVM算法不受分類前提困擾,可以直接在圓和星之間找出一個最合適的超平面進行分類。換句話說,SVM對于異常值是有效的。
情景5
讓我們繼續(xù)關注直線這個話題。在下圖中,兩類數(shù)據(jù)之間已經(jīng)不具備直線邊界了,那么SVM算法會怎么分類?請想象電視劇中大俠拍桌震起酒杯的畫面。圖中目前只有X和Y兩個特征,為了分類,我們可以添加一個新特征Z = X2+ Y2,并繪制數(shù)據(jù)點在X軸和Z軸上的位置。
數(shù)據(jù)點被“震起來”后,星和圓在Z軸上出現(xiàn)了一個清晰的決策邊界,它在上圖中表示為一條二維的線,這里有幾個注意點:
Z的所有值都是正的,因為它是X和Y的平方和;
在原圖中,圓的分布比星更靠近坐標軸原點,這也是它們在Z軸上的值較低的原因。
在SVM中,我們通過增加空間維度能很輕易地在兩類數(shù)據(jù)間獲得這樣的線性超平面,但另一個亟待解決的問題是,像Z = X2+ Y2這樣的新特征是不是都得由我們手動設計?不需要,SVM中有一種名為kernel的函數(shù),它們能把低維輸入映射進高維空間,把原本線性不可分的數(shù)據(jù)變?yōu)榫€性可分,我們也稱它們?yōu)楹撕瘮?shù)。
核函數(shù)主要用于非線性分離問題。簡而言之,它會自動執(zhí)行一些非常復雜的數(shù)據(jù)轉(zhuǎn)換,然后根據(jù)你定義的標簽或輸出找出分離數(shù)據(jù)的過程。
當我們把數(shù)據(jù)點從三維壓縮回二維后,這個超平面就成了一個圓圈:
3. 如何在Python和R中實現(xiàn)SVM
在Python中,scikit-learn是一個受眾極廣的方便又強大的機器學習算法庫,所以我們可以直接在scikit-learn里找到SVM。
#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軟件包可用于輕松創(chuàng)建SVM,它具有輔助函數(shù)以及Naive Bayes分類器的代碼,和Python大體相同。
#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)
4. 如何調(diào)整SVM參數(shù)
在機器學習中,調(diào)參是提高模型性能額一種有效做法,我們先來看看SVM中的可用參數(shù)。
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)
這里我們只介紹幾個重要參數(shù)的調(diào)參方法。
kernel:之前我們已經(jīng)介紹了kernel是什么,關于它,我們可以挑選各種函數(shù):線性的、RBF核的、poly函數(shù)等(默認值為RBF核)。對非線性超平面來說,后兩種核函數(shù)效果顯著。以下是幾個例子:
例1:線性核函數(shù)
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)
# create a mesh to plot in
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()
例2:RBF核函數(shù)
把核函數(shù)類型更改為rbf,然后從圖中觀察變化。
svc = svm.SVC(kernel ='rbf',C = 1,gamma = 0).fit(X,y)
如果你有大量特征(> 1000),我建議你選擇線性內(nèi)核,因為它們在高維空間內(nèi)線性可分的概率更高。除此之外,那rbf就是個不錯的選擇,但是不要忘記交叉驗證其參數(shù)來避免過擬合。
gamma:rbf、poly和sigmoid的核系數(shù)。gamma值越高,模型就回更努力地擬合訓練數(shù)據(jù)集,所以它也是導致過擬合的一個要因。
例3:gamma = 0.01和100
svc = svm.SVC(kernel ='rbf',C = 1,gamma = 0).fit(X,y)
C: 誤差項的懲罰參數(shù)C,它還控制著決策邊界的平滑與否和正確分類訓練點之間的權(quán)衡。
例4:C = 100和1000
自始自終,我們都要記得用交叉驗證來有效組合這些參數(shù),防止模型過擬合。
5. SVM的優(yōu)點和缺點
優(yōu)點
效果很好,分類邊界清晰;
在高維空間中特別有效;
在空間維數(shù)大于樣本數(shù)的情況下很有效;
它使用的是決策函數(shù)中的一個訓練點子集(支持向量),所以占用內(nèi)存小,效率高。
缺點
如果數(shù)據(jù)量過大,或者訓練時間過長,SVM會表現(xiàn)不佳;
如果數(shù)據(jù)集內(nèi)有大量噪聲,SVM效果不好;
SVM不直接計算提供概率估計,所以我們要進行多次交叉驗證,代價過高。
小結(jié)
本文介紹了什么是支持向量機、SVM的工作原理、如何在Python和R中實現(xiàn)SVM、如何調(diào)參以及它的的優(yōu)點和缺點。希望讀者能在閱讀完畢后動手試一試,不要受近年來出現(xiàn)的“有DL還要學SVM嗎?”的說法的影響,經(jīng)典的算法總有其可貴之處,它也是進公司面試時的一大熱門題目。
如果不知道從何開始,可以嘗試做做論智的這道題:
-
SVM
+關注
關注
0文章
154瀏覽量
32376 -
機器學習
+關注
關注
66文章
8349瀏覽量
132312
原文標題:從示例中理解SVM算法(附代碼)
文章出處:【微信號:jqr_AI,微信公眾號:論智】歡迎添加關注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關推薦
評論