R語言實現支持向量機SVM應用案例
IRIS數據集簡介
IRIS數據集中的數據源於1936年費希爾法發表的一篇論文。彼時他收集瞭三種鳶尾花(分別標記為setosa、versicolor和virginical)的花萼和花瓣數據。包括花萼的長度和寬度,以及花瓣的長度和寬度。我們將根據這四個特征來建立支持向量機模型從而實現對三種鳶尾花的分類判別任務。
有關數據可以從datasets軟件包中的iris數據集裡獲取,下面我們演示性地列出瞭前5行數據。成功載入數據後,易見其中共包含瞭150個樣本(被標記為setosa、versicolor和virginica的樣本各50個),以及四個樣本特征,分別是Sepal.Length、Sepal.Width、Petal.Length和Petal.Width。
> iris Sepal.Length Sepal.Width Petal.Length Petal.Width Species 1 5.1 3.5 1.4 0.2 setosa 2 4.9 3.0 1.4 0.2 setosa 3 4.7 3.2 1.3 0.2 setosa 4 4.6 3.1 1.5 0.2 setosa 5 5.0 3.6 1.4 0.2 setosa 6 5.4 3.9 1.7 0.4 setosa 7 4.6 3.4 1.4 0.3 setosa 8 5.0 3.4 1.5 0.2 setosa 9 4.4 2.9 1.4 0.2 setosa 10 4.9 3.1 1.5 0.1 setosa
在正式建模之前,我們也可以通過一個圖型來初步判定一下數據的分佈情況,為此在R中使用如下代碼來繪制(僅選擇Petal.Length和Petal.Width這兩個特征時)數據的劃分情況。
library(lattice) xyplot(Petal.Length ~ Petal.Width, data = iris, groups = Species, auto.key = list(corner=c(1, 0)))
上述代碼的執行結果如圖14-13所示,從中不難發現,標記為setosa的鳶尾花可以很容易地被劃分出來。但僅使用Petal.Length和Petal.Width這兩個特征時,versicolor和virginica之間尚不是線性可分的。
函數svm()在建立支持向量機分類模型時有兩種方式。第一種是根據既定公式建立模型,此時的函數使用格式為:
svm(formula, data= NULL, subset, na.action = na.omit , scale= TRUE)
其中:
- formula表示函數模型的形式
- data表示在模型中包含的有變量的一組可選格式數據
- 參數na.action用於指定當樣本數據中存在無效的空數據時系統應該進行怎樣的處理。默認值na.omit表示程序會忽略那些數據缺失的樣本。另外一個可選的賦值為na.fail,它指示系統在遇到空數據時給出一條錯誤信息。
- 參數scale為一個邏輯向量指定特征是護具是否需要標準化(默認標準化為均值0,方差1)
- 索引向量subset用於指定那些將來將被用來訓練模型的采樣數據。
例如,已經知道僅用Petal.Length和Petal.Width這兩個特征時標記為setosa和versicolor的鳶尾花是線性可分的,所以我們用下面的代碼來構建SVM模型:
data(iris) attach(iris) subdata <- iris[iris$Species != 'virginica', ] subdata$Speices <- factor(subdata$Species) model1 <- svm(Species ~ Petal.Length + Petal.Width, data = subdata) plot(model1, subdata, Petal.Length ~ Petal.Width)
繪制的模型如下:
在使用第一種格式建立模型時,若使用數據中的全部特征變量作為模型特征變量時,可以簡要地使用“Species~.”中的“.”代替全部的特征變量。例如下面的代碼就利用瞭全部四種特征來對三種鳶尾花進行分類。
model2 <- svm(Species~., data = iris) summary(model2)
summary函數的結果如下:
> model2 <- svm(Species~., data = iris) > summary(model2) Call: svm(formula = Species ~ ., data = iris) Parameters: SVM-Type: C-classification SVM-Kernel: radial cost: 1 gamma: 0.25 Number of Support Vectors: 51 ( 8 22 21 ) Number of Classes: 3 Levels: setosa versicolor virginica
通過summary函數可以得到關於模型的相關信息。
- 其中,SVM-Type項目說明本模型的類別為C分類器模型;
- SVM-Kernel項目說明本模型所使用的核函數為高斯內積函數且核函數中參數gamma的取值為0.25;
- cost項目說明本模型確定的約束違反成本為1;
- 此外我們可以看到,模型找到瞭51個支持向量:第一類包含有8個支持向量,第二類包含有22個支持想想,第三類包含21個支持向量。
- 最後一行說明模型中的三個類別分別為setosa、versicolor和virginica。
第二種使用svm()函數的方式則是根據所給的數據建立模型。這種方式形式要復雜一些,但是它允許我們以一種更加靈活的方式來構建模型。它的函數使用格式如下(註意我們僅列出瞭其中的主要參數)。
svm(x, y = NULL, scale = TRUE, type = NULL, kernel = "radial", degree = 3, gamma = if (is.vector(x)) 1 else 1 / ncol(x), coef0 = 0, cost = 1, nu = 0.5, subset, na.action = na.omit)
其中:
- x可以是一個數據矩陣,也可以是一個數據向量,同時也可以是一個稀疏矩陣。y是對於x數據的結果標簽,它既可以是字符向量也可以為數值向量。x和y共同決定瞭將要用來建模的訓練數據以及模型的積分形式。
- 參數type用於指定建立模型的類別。支持向量機模型通常可以用作分類模型、回歸模型和異常檢查模型。根據用途的不同,在svm函數中的type可取的值為C-classification、nu-classification、one-classification、eps-regression和nu-regression這五種類型。其中前三種是針對於字符結果變量的分類方式,其中第三種方式為邏輯判別,即判別結果輸出所需判別樣本是否屬於該類別。而後兩種則是針對數值型結果變量的分類方式。
- kernel是指在模型的建立過程中使用的核函數。針對線性不可分的問題,為瞭提高模型預測精度,通常會隻用核函數對原始數據進行變換,提高原始特征維度,解決支持向量機模型線性不可分的問題。svm函數中kernel參數有四個可選核函數,分別為線性核函數、多項式核函數、高斯核函數及神經網絡核函數。其中,高斯核函數與多項式核函數被認為是性能最好、也是最常用的核函數。
核函數有兩種主要類型:局部性核函數和全局性核函數,高斯核函數是一個典型的局部性核函數,而多項式核函數則是一個典型的全局性核函數。局部性核函數僅僅在測試點附近小鄰域內對數據點有影響,其學習能力強,泛化性能較弱;而全局性核函數則相對來說泛化性能較強,學習能力較弱。
- 對於選定的核函數,degree參數是指核函數多項式內積函數中的參數,其默認值為3。gamma參數給出瞭一個核函數中除線性內積函數以外的所有函數的參數,默認值為1.coef0參數是指核函數中多項式內積函數sigmoid內積函數的中的參數,默認值為0.
- 參數cost是軟間隔模型中離群點權重。
- 最後,參數nu是用於nu-regression、nu-classification和one-classification類型中的參數。
一個經驗性的結論為,在利用svm函數建立支持向量機模型時,使用標準化後的數據建立的模型效果更好。根據函數的第二種使用格式,在針對上述數據建立模型時,首先應該將結果變量和特征變量分別提取出來。結果向量用一個向量表示,特征向量用一個矩陣表示。在確定好數據後還應根據數據分析所使用的核函數以及核函數所對應的參數值,通常默認使用高斯內積函數作為核函數。下面給出一段實例代碼:
# 提取iris數據集中除第五列以外的數據作為特征變量 x <- iris[, -5] # 提取iris數據集中第五列數據作為結果變量 y <- iris[, 5] model3 <- svm(x, y, kernel = "radial", gamma = if (is.vector(x)) 1 else 1 / ncol(x))
在使用第二種格式建立模型時,不需要特別強調所建立模型的形式,函數會自動將所有輸入的特征變量數據作為建立模型所需要的特征向量。在上述過程中,確定核函數的gamma系數時所使用的代碼代表的意思為:如果特征向量是向量則gamma值取1,否則gamma值為特征向量個數的倒數。
在利用樣本數據建立模型之後,我們便可以利用模型來進行相應的預測和判別。基於svm函數建立的模型來進行預測時,可以選用函數predict函數來完成相應的工作。在使用該函數時,應該首先確認將要用於預測的樣本數據,並將樣本數據的特征變量整合後放入同一個矩陣。代碼如下:
pred <- predict(model3, x) table(pred, y)
輸出結果:
> pred <- predict(model3, x)
> table(pred, y)
y
pred setosa versicolor virginica
setosa 50 0 0
versicolor 0 48 2
virginica 0 2 48
通常在進行預測之後,還需要檢查模型預測的準確程度,這時便需要使用函數table來對預測結果和真實結果做出對比展示。從上述代碼的輸出中,可以看到在模型預測時,模型將所有屬於setosa類型的鳶尾花全部預測正確;模型將數據versicolor類型的鳶尾花中有48朵預測正確,另外兩朵錯誤的預測為virginica類型;同樣,模型將屬於virginica類型的鳶尾花中的48朵預測正確,但也將另外兩朵錯誤的預測為versicolor類型。
函數predict中的一個可選參數是decision.values,在默認情況下,該參數的缺省值為FALSE。若將其值置為TRUE,那麼函數的返回值中將包含有一個名為decision.values的屬性,該屬性是一個n*c的矩陣。這裡,n是被預測的數據量,c是一個二分類器的決策值。註意,因為我們使用支持向量機對樣本數據進行分類,分類結果可能是有k個類別。那麼這k個類別中任意兩類之間都會有一個二分類器。所以,我麼可以推斷出總共的二分類器數量為K(k-1)/2。決策值矩陣中的列名就是二分類器的標簽。代碼如下:
pred <- predict(model3, x, decision.values = TRUE) attr(pred, "decision.values")[1:4, ]
輸出如下:
> pred <- predict(model3, x, decision.values = TRUE)
> attr(pred, “decision.values”)[1:4, ]
setosa/versicolor setosa/virginica
1 1.196152 1.091757
2 1.064621 1.056185
3 1.180842 1.074542
4 1.110699 1.053012
versicolor/virginica
1 0.6708810
2 0.8483518
3 0.6439798
4 0.6782041
由於我們處理的是一個分類問題。所以分類決策最終是經由一個sign()函數來完成的。從上面的輸出中可以看到,對於樣本數據4而言,標簽setosa/versicolor對應的值大於0,因此屬於setosa類;標簽setosa/virginica對應的值同樣大於0,因此數據setosa類;在二分類器versicolor/virginica中對應的決策值大於0,判定屬於versicolor類。所以,最終樣本數據4被判定數據setosa類。
可視化模型,代碼如下:
> plot(cmdscale(dist(iris[,-5])), + col=c("orange", "blue", "green")[as.integer(iris[,5])], + pch=c("o", "+")[1:150 %in% model3$index + 1]) > > # ?legend > legend(1.8, -0.5, c("setosa","versicolor", "virgincia"), + col = c("orange","blue","green"), lty = 1, + cex = 0.6, + bty = "o", box.lty = 1, box.col = "black")
在圖中我們可以看到,鳶尾花中的第一種setosa類別同其他兩種區別較大,而剩下的versicolor類別和virginica類別卻相差很小,甚至存在交叉難以區分。註意,這是在使用瞭全部四種特征之後仍然難以區分的。這也從另一個角度解釋瞭在模型預測過程中出現的問題,所以模型誤將2朵versicolor 類別的花預測成瞭virginica 類別,而將2朵virginica 類別的花錯誤地預測成瞭versicolor 類別,也就是很正常現象瞭。
到此這篇關於R語言實現支持向量機SVM應用案例的文章就介紹到這瞭,更多相關R語言支持向量機SVM內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- 前端AI機器學習在瀏覽器中訓練模型
- Python matplotlib繪制散點圖配置(萬能模板案例)
- R語言 實現data.frame 分組計數、求和等
- R語言數據預處理操作——離散化(分箱)
- R語言dplyr包之高效數據處理函數(filter、group_by、mutate、summarise)詳解