R語言分類之支持向量機(SVM)
一、數據準備
> library(C50)n> data(churn)n> churnTrain<-churnTrain[,!names(churnTrain)%in%c("state","area_code","account_length")]n> set.seed(2)n> ind<-sample(2,nrow(churnTrain),replace = T,prob = c(0.7,0.3))n> trainset<-churnTrain[ind==1,]n> testset<-churnTrain[ind==2,]n
二、操作
> library(e1071)n> model<-svm(churn~.,data = trainset,kernel="radial",cost=1,gamma=1/ncol(trainset))n> summary(model)nnCall:nsvm(formula = churn ~ ., data = trainset, kernel = "radial", cost = 1, gamma = 1/ncol(trainset))nnnParameters:n SVM-Type: C-classification n SVM-Kernel: radial n cost: 1 n gamma: 0.05882353 nnNumber of Support Vectors: 691nn ( 394 297 )nnnNumber of Classes: 2 nnLevels: n yes non
三、原理
支持向量機構建了一個超平面,使得高維特徵空間內兩個類的邊緣間隔最大,定義超平面的向量就被稱為支持向量。
SVM的優勢就在於利用了面向工程問題的核函數,能夠提供準確率非常高的分類模型,同時藉助增則向可以避免模型的過度適應,用戶也不用擔心諸如局部最優和多重共線性難題。SVM演算法最重要的弊端是對模型進行訓練和測試的速度很慢,模型處理需要的時間冗長,因而演算法不適合應用於規模比較大的數據集,另外SVM的結果很難解釋,如何確定合適的核函數也是一個難點,而正則化也是用戶需要考慮的問題。
通過訓練函數SVM,用戶可以確定和函數、成本函數以及ganmma函數。對於核函數的選擇,默認選擇radial(徑向函數),用戶還可以選擇線性核函數形狀,默認為數據維度的倒數(1/數據維度),提高gamma值同城會增加支持向量的數量。考慮成本函數,默認通常為1,此時正則向也是常熟,正則向越大,邊界越小
四、支持向量機的懲罰因子
支持向量機能夠通過最大化邊界得到一個優化的超平面以完成對訓練數據的分離,不過有時演算法也允許被錯誤分類樣本的存在,懲罰因子能實現SVM對分類誤差及分離邊界的控制,如果控制因子比較小,分離間隔會比較大(軟間隔)講產生比較多的被錯分樣本;相反當加大懲罰因子時,會縮小分類間隔,從而減小錯分樣本。
1、準備
> library(dplyr)n> data("iris")n iris.subset<-subset(iris,select=c("Sepal.Length","Sepal.Width","Species"),Species%in%c("setosa","virginica"))n
2、調用plot函數繪製散點圖,其中sepal.length為x軸,sepal.width為y軸:
> plot(x=iris.subset$Sepal.Length,y=iris.subset$Sepal.Width,col=iris.subset$Species,pch=19)n
將懲罰因子設置為1,利用iris.subset數據集訓練SVM:
> svm.model<-svm(Species~.,data = iris.subset,kernel="linear",cost=1,scale = F)n
將支持向量用藍色的圈標記出來:
> points(iris.subset[svm.model$index,c(1,2)],col="blue",cex=2)n
加分割線
> w=t(svm.model$coefs)%*%svm.model$SVn> b=-svm.model$rhon> abline(a=-b/w[1,2],b=-w[1,1]/w[1,2],col="red",lty=5)n
將懲罰因子設置為1000,重新訓練一個SVM分類器;
> plot(x=iris.subset$Sepal.Length,y=iris.subset$Sepal.Width,col=iris.subset$Species,pch=19)n> svm.model<-svm(Species~.,data = iris.subset,kernel="linear",cost=1000,scale = F,type=C-classification)n> points(iris.subset[svm.model$index,c(1,2)],col="blue",cex=2)n> w=t(svm.model$coefs)%*%svm.model$SVn> b=-svm.model$rhon> abline(a=-b/w[1,2],b=-w[1,1]/w[1,2],col="red",lty=5)n
五、實現SVM模型的可視化
1、準備數據並繪製
> data("iris")n> model.iris<-svm(Species~.,data=iris)n> plot(model.iris,iris,Petal.Width~Petal.Length,slice=list(Sepal.Width=3,Sepal.Length=4))n
2、調用plot函數,繪製svm對象model,x軸和y軸分別為tatal_intl_charge和total_day_minutes:
> model<-svm(churn~.,churnTrain)n> plot(model,churnTrain,total_day_minutes~total_intl_charge)n
3、原理
第一張圖中,我們基於iris數據集訓練得到支持向量機,並調用plot函數繪製了該SVM模型
在參數列表中,plot函數的第一個參數為模型名稱,第二個參數為指定的樣本數據集(該數據集必須與構建模型的數據集一致)第三個參數是對分類圖坐標軸的說明,默認情況下,plot函數將繪製一個二維(x軸-y軸)的散點圖。我們選擇了Petal.Length和Petal.Width作為散點圖的兩個坐標軸,分別是x軸和y軸
其中x代表支持向量,o代表樣例數據,,選擇不同顏色顯示(綠色代表Viginica,紅色代表Versicolor,黑色代表Setoca)最後一個參數slice,僅在變數個數大於2的時候設置。本例中我們設置了兩個變數,並分別用常數3和4為其附值。
六、基於支持向量機訓練模型實現類預測
1、準備
使用之前設置好的model的支持向量機模型
2、操作
利用已經夠賤的svm模型和測試數據集樹形預測他的類別:
> svm.pred<-predict(model,testset[,!names(testset)%in%c("churn")])n
根據預測結果和測試數據集的類別,調用table函數建立分類:
> svm.table<-table(svm.pred,testset$churn)nn> svm.tablennsvm.pred yes non yes 95 8n no 46 869n
調用classAgreement計算分類一致性係數
> classAgreement(svm.table)n$diagn[1] 0.9469548nn$kappan[1] 0.7493823nn$randn[1] 0.8994384nn$crandn[1] 0.6988815n
調用confusionMatrix基於分類表評測預測性能:
> library(caret)n> confusionMatrix(svm.table)nConfusion Matrix and Statisticsnnnsvm.pred yes non yes 95 8n no 46 869nn Accuracy : 0.947 n 95% CI : (0.9314, 0.9599)n No Information Rate : 0.8615 n P-Value [Acc > NIR] : < 2.2e-16 nn Kappa : 0.7494 n Mcnemars Test P-Value : 4.777e-07 nn Sensitivity : 0.67376 n Specificity : 0.99088 n Pos Pred Value : 0.92233 n Neg Pred Value : 0.94973 n Prevalence : 0.13851 n Detection Rate : 0.09332 n Detection Prevalence : 0.10118 n Balanced Accuracy : 0.83232 nn Positive Class : yes n
解釋:
本節引入了一個新函數classAgreement用來計算一個二維列聯錶行列之間的多種一致性係數,包括diag係數,kappa係數,rand係數以及crand係數等。其中,diag係數為分類表的主對角線上數據點的百分比,kappa係數是對diag係數隨機一致性的修正(出現隨機一致性的概率)rand代表聚類評價指標(Rand index),主要用來衡量兩個聚類簇之間的相似性;crand係數是出現元素隨機分類情況時對Rand index修正的結果
最後我們使用caret包的confusionMatrix函數來評測分類模型的性能,訓練後的支持向量機分類正確率可達0.9185
七、調整支持向量機
1、準備
準備好訓練數據集trainset
2、操作
首先調用tune.svm調整支持向量機:
> tuned<-tune.svm(churn~.,data = trainset,gamma = 10^(-6:-1),cost = 10^(1:2))n
使用summary函數得到調整後的模型相關信息
> summary(tuned)nnParameter tuning of 『svm』:nn- sampling method: 10-fold cross validation nn- best parameters:n gamma costn 0.01 100nn- best performance: 0.07947641 nn- Detailed performance results:n gamma cost error dispersionn1 1e-06 10 0.14771981 0.02532118n2 1e-05 10 0.14771981 0.02532118n3 1e-04 10 0.14771981 0.02532118n4 1e-03 10 0.14771981 0.02532118n5 1e-02 10 0.08984363 0.01916272n6 1e-01 10 0.09071503 0.01843012n7 1e-06 100 0.14771981 0.02532118n8 1e-05 100 0.14771981 0.02532118n9 1e-04 100 0.14771981 0.02532118n10 1e-03 100 0.12007016 0.02188463n11 1e-02 100 0.07947641 0.01409617n12 1e-01 100 0.12744626 0.02427064n
使用由tuning函數得到的最佳參數設置支持向量機:
> model.tuned<-svm(churn~.,data = trainset,gamma=tuned$best.parameters$gamma,cost=tuned$best.parameters$cost)n> summary(model.tuned)nnCall:nsvm(formula = churn ~ ., data = trainset, gamma = tuned$best.parameters$gamma, n cost = tuned$best.parameters$cost)nnnParameters:n SVM-Type: C-classification n SVM-Kernel: radial n cost: 100 n gamma: 0.01 nnNumber of Support Vectors: 547nn ( 304 243 )nnnNumber of Classes: 2 nnLevels: n yes non
調用predict函數基於剛配置好的svm模型進行類標號的預測:
> svm.tuned.pred<-predict(model.tuned,testset[,!names(testset)%in%c("churn")])n
基於測試數據集的預測類別和實際類別產生分類表:
> svm.tuned.table<-table(svm.tuned.pred,testset$churn)n> svm.tuned.tablennsvm.tuned.pred yes non yes 95 24n no 46 853n
調用classAgreement函數得到相關係數完成演算法性能評測:
> classAgreement(svm.tuned.table)n$diagn[1] 0.9312377nn$kappan[1] 0.691678nn$randn[1] 0.871806nn$crandn[1] 0.6303615n
最後調用confusionMatrix函數評測優化後的模型性能:
> confusionMatrix(svm.tuned.table)nConfusion Matrix and Statisticsnnnsvm.tuned.pred yes non yes 95 24n no 46 853nn Accuracy : 0.9312 n 95% CI : (0.9139, 0.946)n No Information Rate : 0.8615 n P-Value [Acc > NIR] : 1.56e-12 nn Kappa : 0.6917 n Mcnemars Test P-Value : 0.01207 nn Sensitivity : 0.67376 n Specificity : 0.97263 n Pos Pred Value : 0.79832 n Neg Pred Value : 0.94883 n Prevalence : 0.13851 n Detection Rate : 0.09332 n Detection Prevalence : 0.11690 n Balanced Accuracy : 0.82320 nn Positive Class : yes n
原理:
為了調整支持向量機可以採用試錯法來尋找最佳的gamma和懲罰因子。
本例中,我們將gamma參數的可能範圍設定為10^-6~10^-1,懲罰因子選擇了10 和100,使用svm.tune函數可以得到12組不同的參數組合。函數採用10遍交叉檢驗的方法來獲得每次組合的錯誤偏差,最後選擇誤差最優的參數組合。從summary表可知,gamma等於0.01和懲罰因子為100時,演算法模型的性能最優
當得到最佳參數後,我們再訓練一個新的支持向量機
(完)
推薦閱讀:
※SVM的核函數如何選取?
※想研究下SVM,有什麼好的文章或者經驗之談可以分享下不?
※機器學習演算法實踐-SVM核函數和軟間隔
※諸如「拉普拉斯這樣的積分變換中的核函數」與「SVM中用來分類的核函數」是一回事么?