【典型演算法】SVM演算法
小編說:機器學習演算法眾多,全部掌握,一則不可能,二則沒必要。如何靈活掌握和應用機器學習演算法呢?小編認為,精通機器學習一些典型的演算法,包括演算法的原理、演算法的演變、演算法的優劣、演算法的應用等。從今日起,【R語言】公眾號會陸續推出機器學習典型演算法一系列文章。這些文章的來源,要麼是轉載,要麼是翻譯,要麼是投稿,要麼是眾包等。從多個途徑,多個維度,利用R語言來理解和實現機器學習中典型演算法。歡迎夥伴們參與進來,你可以分享你所認為的機器學習典型演算法是什麼?你可以向小編投稿。你可以向小編推送好的資源。
支持向量機是一個相對較新和較先進的機器學習技術,最初提出是為了解決二類分類問題,現在被廣泛用於解決多類非線性分類問題和回歸問題。繼續閱讀本文,你將學習到支持向量機如何工作,以及如何利用R語言實現支持向量機。
支持向量機如何工作?簡單介紹下支持向量機是做什麼的:
假設你的數據點分為兩類,支持向量機試圖尋找最優的一條線(超平面),使得離這條線最近的點與其他類中的點的距離最大。有些時候,一個類的邊界上的點可能越過超平面落在了錯誤的一邊,或者和超平面重合,這種情況下,需要將這些點的權重降低,以減小它們的重要性。
這種情況下,「支持向量」就是那些落在分離超平面邊緣的數據點形成的線。
無法確定分類線(線性超平面)時該怎麼辦?
此時可以將數據點投影到一個高維空間,在高維空間中它們可能就變得線性可分了。它會將問題作為一個帶約束的最優化問題來定義和解決,其目的是為了最大化兩個類的邊界之間的距離。
我的數據點多於兩個類時該怎麼辦?此時支持向量機仍將問題看做一個二元分類問題,但這次會有多個支持向量機用來兩兩區分每一個類,直到所有的類之間都有區別。
工程實例
讓我們看一下如何使用支持向量機實現二元分類器,使用的數據是來自MASS包的cats數據集。在本例中你將嘗試使用體重和心臟重量來預測一隻貓的性別。我們拿數據集中20%的數據點,用於測試模型的準確性(在其餘的80%的數據上建立模型)。
# Setuplibrary(e1071)data(cats, package="MASS")inputData <- data.frame(cats[,="" c="" (2,3)],="" response="as.factor(cats$Sex))" #="" response="" as="">線性支持向量機傳遞給函數svm()的關鍵參數是kernel、cost和gamma。Kernel指的是支持向量機的類型,它可能是線性SVM、多項式SVM、徑向SVM或Sigmoid SVM。Cost是違反約束時的成本函數,gamma是除線性SVM外其餘所有SVM都使用的一個參數。還有一個類型參數,用於指定該模型是用於回歸、分類還是異常檢測。但是這個參數不需要顯式地設置,因為支持向量機會基於響應變數的類別自動檢測這個參數,響應變數的類別可能是一個因子或一個連續變數。所以對於分類問題,一定要把你的響應變數作為一個因子。
# linear SVMsvmfit <- svm(response="" ~="" .,="" data="inputData," kernel="linear" ,="" cost="10," scale="FALSE)" #="" linear="" svm,="" scaling="" turned="" offprint(svmfit)plot(svmfit,="" inputdata)comparetable=""><- table="" (inputdata$response,="" predict(svmfit))="" #="" tabulatemean(inputdata$response="" !="predict(svmfit))" #="" 19.44%="" misclassification="">徑向支持向量機
徑向基函數作為一個受歡迎的內核函數,可以通過設置內核參數作為「radial」來使用。當使用一個帶有「radial」的內核時,結果中的超平面就不需要是一個線性的了。通常定義一個彎曲的區域來界定類別之間的分隔,這也往往導致相同的訓練數據,更高的準確度。
# radial SVMsvmfit <- svm(response="" ~="" .,="" data="inputData," kernel="radial" ,="" cost="10," scale="FALSE)" #="" radial="" svm,="" scaling="" turned="" offprint(svmfit)plot(svmfit,="" inputdata)comparetable=""><- table="" (inputdata$response,="" predict(svmfit))="" #="" tabulatemean(inputdata$response="" !="predict(svmfit))" #="" 18.75%="" misclassification="">尋找最優參數
你可以使用tune.svm()函數,來尋找svm()函數的最優參數。
### Tuning# Prepare training and test dataset.seed(100) # for reproducing resultsrowIndices <- 1="" :="" nrow(inputdata)="" #="" prepare="" row="" indicessamplesize=""><- 0.8="" *="" length(rowindices)="" #="" training="" sample="" sizetrainingrows=""><- sample="" (rowindices,="" samplesize)="" #="" random="" samplingtrainingdata=""><- inputdata[trainingrows,="" ]="" #="" training="" datatestdata=""><- inputdata[-trainingrows,="" ]="" #="" test="" datatuned=""><- tune.svm(response="" ~.,="" data="trainingData," gamma="10^(-6:-1)," cost="10^(1:2))" #="" tunesummary="" (tuned)="" #="" to="" select="" best="" gamma="" and=""># Parameter tuning of "svm":# - sampling method: 10-fold cross validation## - best parameters:# gamma cost# 0.001 100## - best performance: 0.26## - Detailed performance results:# gamma cost error dispersion# 1 1e-06 10 0.36 0.09660918# 2 1e-05 10 0.36 0.09660918# 3 1e-04 10 0.36 0.09660918# 4 1e-03 10 0.36 0.09660918# 5 1e-02 10 0.27 0.20027759# 6 1e-01 10 0.27 0.14944341# 7 1e-06 100 0.36 0.09660918# 8 1e-05 100 0.36 0.09660918# 9 1e-04 100 0.36 0.09660918# 10 1e-03 100 0.26 0.18378732# 11 1e-02 100 0.26 0.17763883# 12 1e-01 100 0.26 0.15055453結果證明,當cost為100,gamma為0.001時產生最小的錯誤率。利用這些參數訓練徑向支持向量機。
svmfit <- svm="" (response="" ~="" .,="" data="trainingData," kernel="radial" ,="" cost="100," gamma="0.001," scale="FALSE)" #="" radial="" svm,="" scaling="" turned="" offprint(svmfit)plot(svmfit,="" trainingdata)comparetable=""><- table="" (testdata$response,="" predict(svmfit,="" testdata))="" #="" comparison="" tablemean(testdata$response="" !="predict(svmfit," testdata))="" #="" 13.79%="" misclassification="">F MF 6 3M 1 19網格圖
一個2-色的網格圖,能讓結果看起來更清楚,它將圖的區域指定為利用SVM分類器得到的結果的類別。在下邊的例子中,這樣的網格圖中有很多數據點,並且通過數據點上的傾斜的方格來標記支持向量上的點。很明顯,在這種情況下,有很多越過邊界違反約束的點,但在SVM內部它們的權重都被降低了。
# Grid Plotn_points_in_grid = 60 # num grid points in a linex_axis_range <- range="" (inputdata[,="" 2])="" #="" range="" of="" x="" axisy_axis_range=""><- range="" (inputdata[,="" 1])="" #="" range="" of="" y="" axisx_grid_points=""><- seq="" (from="x_axis_range[1]," to="x_axis_range[2]," length="n_points_in_grid)" #="" grid="" points="" along="" x-axisy_grid_points=""><- seq="" (from="y_axis_range[1]," to="y_axis_range[2]," length="n_points_in_grid)" #="" grid="" points="" along="" y-axisall_grid_points=""><- expand.grid="" (x_grid_points,="" y_grid_points)="" #="" generate="" all="" grid="" pointsnames="" (all_grid_points)=""><- c("hwt",="" "bwt")="" #="" renameall_points_predited=""><- predict(svmfit,="" all_grid_points)="" #="" predict="" for="" all="" points="" in="" gridcolor_array=""><- c("red",="" "blue")[as.numeric(all_points_predited)]="" #="" colors="" for="" all="" points="" based="" on="" predictionsplot="" (all_grid_points,="" col="color_array," pch="20," cex="0.25)" #="" plot="" all="" grid="" pointspoints="" (x="trainingData$Hwt," y="trainingData$Bwt," col="c("red"," "blue")[as.numeric(trainingdata$response)],="" pch="19)" #="" plot="" data="" pointspoints="" (trainingdata[svmfit$index,="" c="" (2,="" 1)],="" pch="5," cex="2)" #="" plot="" support="">來源:http://blog.jobbole.com/84714/
推薦閱讀:
※012 Integer to Roman[M]
※Leetcodes Solution 45 Jump Game II
※演算法導論第二課——漸進分析
※九章演算法 | Facebook 面試題 : 有手續費的買賣股票問題
※015 3Sum[M]
