利用R語言實現支持向量機(SVM)數據挖掘案例
建立模型
svm()函數在建立支持向量機模型的時候有兩種建立方式。簡單地說,一種是根據既定公式建立模型;而另外一種方式則是根據所給的數據模型建立模型。
根據函數的第一種使用格式,針對上述數據建模時,應該先確定所建立的模型所使用的數據,然后再確定所建立模型的結果變量和特征變來那個。代碼如下:
library(e1071)
data(iris)
#建立svm模型
model <- svm(Species~.,data = iris)
在使用第一種格式建立模型時,如果使用數據中的全部特征變量作為模型特征變量時,可以簡要地使用“Species~.”中的“.”代替全部的特征變量。
根據函數的第二種使用格式,在針對iris數據建立模型時,首先應該將結果變量和特征變量分別提取出來。結果變量用一個向量表示,而特征向量用一個矩陣表示。在確定好數據后還應根據數據分析所使用的核函數以及核函數所對應的參數值,通常默認使用高斯內積函數作為核函數,具體分析代碼如下:
#提取iris數據中除第5列以外的數據作為特征變量
x <- iris[,-5]
#提取iris數據中第5列數據作為結果變量
y <- iris[,5]
#建立svm模型
model <- svm(x,y,kernel = "radial", gamma = if(is.vector(x)) 1 else 1/ncol(x))
在使用第二種格式建立模型時,不需要特別強調所建立模型的哪個是,函數會自動將所有輸入的特征變量數據作為建立模型所需要的特征變來那個。
在上述過程中,確定核函數的gamma系數時所使用的R語言所代表的意思為:如果特征向量是向量則gamma值取1,否則gamma值為特征向量個數的倒數。
結果分析
summary(model)
Call:
svm.default(x = x, y = y, kernel = "radial", gamma = if (is.vector(x)) 1 else 1/ncol(x))
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()函數建立的模型進行預測時,我們將用到predict()函數對模型進行預測。在實用predict()函數時,應該首先確認將用於預測的樣本數據,並將樣本數據的特征變量整合放入同一個矩陣,代碼如下:
#確認需要繼續預測的樣本特征矩陣
x <- iris[,1:4]
#根據模型model對x數據進行預測
pred <- predict(model, x)
#隨機挑選8個預測結果進行展示
print(pred[sample(1:150, 8)])
1 131 133 41 79 49 47 93
setosa virginica virginica setosa versicolor setosa setosa versicolor
Levels: setosa versicolor virginica
在進行數據預測時,主要注意的問題就是必須保證用於預測的特征向量的個數應同模型建立時使用的特征向量個數一致,否則將無法預測結果。在使用predict()函數進行預測時,不用刻意去調整預測結果類型。
通過對預測結果的展示,我們可以看到predict()函數在預測時自動識別預測結果的類型,並自動生成了相應的類別名稱。通常在進行預測之后,還需要檢查模型預測的精度,這便需要用到table()函數對預測結果和真實結果做出對比展示。代碼如下:
#模型預測精度展示
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類型。
綜合建模
通過之前對支持向量機理論及支持向量機模型具體應用的介紹,現基於iris數據集 ,綜合介紹利用R語言建立模型的完整過程。
分析數據可以看出,數據需要判別的是三個類別,且三個類別屬於字符類型,所以我們可以選擇的支持向量機分類機就有三類:C-classification、nu-classification、one-classification。同時,可以選擇的核函數有四類:線性核函數(linear)、多項式核函數(polynomial)、徑向基核函數(radial basis,RBF)和神經網絡核函數(sigmoid)。所以在時間和精力允許的情況下,應該盡可能建立所有可能的模型,最后通過比較選出判別結果最優的模型。根據上述分析,利用R語言實現的具體程序代碼如下:
library(e1071)
#將數據集iris按列單獨確認為向量
attach(iris)
#確定特征變量為數據集iris中除去Species中的其他項
x <- subset(iris, select = -Species)
#確定結果變量為數據集iris中的Species項
y <- Species
#確定將要使用的分類方式
type <- c("C-classification","nu-classification","one-classification")
#確定將要使用的核函數
kernel <- c("linear","polynomial","radial","sigmoid")
#初始化預測結果矩陣的三維長度分別為150,3,4
pred <- array(0,dim = c(150,3,4))
#初始化模型精准度矩陣的二維分別為3,4
accuracy <- matrix(0,3,4)
#為方便模型精度計算,將結果變量數量化為1,2,3
yy <- as.integer(y)
#確認i影響的維度代表分類方式
for(i in 1:3){
-
#確認j影響的維度代表核函數
-
for(j in 1:4){
-
#對每一模型進行預測
-
pred[,i,j] <- predict(svm(x,y.type=type[i],kernel=kernel[j]),x)
-
if (i>2) {
-
accuracy[i,j] <- sum(pred[,i,j]!=1)
-
} else {
-
accuracy[i,j] <- sum(pred[,i,j]!=yy)
-
}
-
}
- }
#確定模型精度變量的列名和行名
dimnames(accuracy)=list(type,kernel)
在運行程序中,if語句的使用是因為C-classification和nu-classification與one-classification的模型預測精度精算方式不同,所以應該分別進行計算。在運行程序之后,可以得到所有12個模型所對應的預測精度。程序中accuracy所代表的是模型預測錯誤的個數。
我們將根據這個預測結果挑選出預測錯誤最少的一些 模型,然后再根據實際情況進行詳細分析,最終決定得出最適合本次研究目的的模型。
相應的預測結果如下:
R語言數據挖掘實踐——支持向量機代碼實戰
從表中的模型預測結果可以看出,利用one-classification方式無論采取何種核函數得出的結果錯誤都非常多,所以可以看出該方式不適合這類數據類型的判別。使用one-classification方式進行建模時,數據通常情況下為一個類別的特征,建立的模型主要用於判別其他樣本是否屬於這類。
利用C-classification與高斯核函數結合的模型判別錯誤最少,如果我們建立模型的目的主要是為了總體誤判率最低,並且各種類型判錯的代價是相同的,那么就可以直接選擇這個模型作為最有模型。那么將利用C-classification與高斯核函數介個的模型的預測結果示例代碼如下:
table(pred, y)
y
pred setosa versicolor virginica
setosa 50 0 0
versicolor 0 48 2
virginica 0 2 48
在得到這個較優模型之后,我們將針對這一模型在進行具體的分析和討論,力圖進一步提高模型的預測精度。
可視化分析
在建立支持向量機模型之后,我們來進一步分析模型。在分析過程中將會使用模型可視化以便於對模型的分析。在對模型進行可視化的過程中,我們使用plot()函數對模型進行可視化繪制,代碼如下:
plot(cmdscale(dist(iris[,-5])),
-
col=c("lightgray","black","gray")[as.integer(iris[,5])],
- pch=c("o","+")[1:150 %in% model$index + 1])
legend(2,-0.8,c("setosa","versicolor","virginica"),col = c("lightgray","black","gray"),lty=1)
R語言數據挖掘實踐——支持向量機代碼實戰
通過plot()函數對所建立的支持向量機模型進行可視化之后,所得到的圖像是對模型數據類別的一個總體觀察。圖中"+"表示的是支持向量,“0”表示的是普通樣本點。
從圖中我們可以看到,鳶尾屬中的第一種setosa類別同其他兩種區別較大,而剩下的versicolor和virginica類別卻相差很小,甚至存在交叉難以區分。這也在另一個角度解釋了在模型預測過程中出現的問題,這正是為什么模型將兩朵versicolor類別的話預測成了virginica類別,並將兩朵virginica類別的花預測成了versicolor類別的原因。
在使用plot()函數對所建立的模型進行了總體的觀察后,我們還可以利用plot()函數對模型進行其他角度的可視化分析。我們可以利用plot()函數對模型類別關於模型中任意兩個特征向量的變動過程進行繪圖。繪圖過程如下:
data(iris)
model <- svm(Species~., data = iris)
plot(model, iris, Petal.Width~Petal.Length,fill = FALSE,
- symbolPalette = c("lightgray","black","grey"),svSymbol = "+")
legend(1,2.5,c("setosa","versicolor","virginica"),col = c("lightgray","black","gray"),lty=1)
R語言數據挖掘實踐——支持向量機代碼實戰
通過對模型關於花瓣的寬度和長度對模型類別分類影響的可視化后,我們仍然可以得到一致的結果:setosa類別的花瓣同另外兩個類別相差較大,而versicolor類別的花瓣同virginica類別的花瓣相差較小。
通過模型可視化可以看出,virginica類別的花瓣在長度和寬度的總體水平上都高於其他兩個類別,而versicolor類別的花瓣在長度和寬度的總體水平上處於居中的位置,而setosa類別的花瓣在長度和寬度上都比另外兩個類別小。
優化模型
在模型預測精度結果中我們發現,盡管模型的預測錯誤已經很少,但是所建立的模型還是出現了4個預測錯誤,那么為了尋找到一個最優的支持向量機模型,我們是否能通過一些方式來進一步提高模型的預測精度,最理想的情況就是將模型的預測錯誤率減少為零。
通過對模型的可視化分析后,無論是從總體的總體的角度觀察,還是從模型個別特征的角度觀察,我們都可以得到一致的結論:類別setosa同其他兩個類別的差異較大,而類別versicolor和類別virginica的差異非常小,而且直觀上能看到兩部分出現少許交叉,並且在預測結果中,模型出現判別錯誤的地方也是混淆了累唄versicolor和類別virginica。
因此,針對這種情況,我們可以向導通過改變模型各個類別的比重來對數據進行調整。由於類別setosa同其他兩個類別相差很大,所以我們可以考慮降低類別setosa在模型中的額比重,而提高另外兩個類別的比重,即適當犧牲類別setosa的精度來提高其他兩個類別的精度。這種方法在R語言中可以通過svm()函數中的class.weights參數來進行調整。特別強調的是,class.weights參數所需要的數據必須為向量,並且具有列名,具體過程如下:
#確定模型各個類別的比重為1:1:1
wts <- c(1,1,1)
#確定各個比重對應的類別
names(wts) <- c("setosa","versicolor","virginica")
#建立模型
model1 <- svm(x,y,class.weights = wts)
當模型的各個類別的比重為1:1:1時,則模型就是最原始的模型,預測結果即之前的預測模型。接下來我們適當提高類別versicolor和類別virginica的比重,以觀察對模型的預測精度是否產生影響,是否為正向影響。
首先,我們先將這兩種類別的比重擴大100倍(具體倍數可根據自行調整修改):
wts <- c(1,100,100)
names(wts) <- c("setosa","versicolor","virginica")
model2 <- svm(x,y,class.weights = wts)
pred2 <- predict(model2,x)
table(pred2,y)
y
pred2 setosa versicolor virginica
setosa 50 0 0
versicolor 0 49 1
virginica 0 1 49
通過預測結果的展示發現,通過提高類別versicolor和virginica的比重卻能能對模型的預測精度產生影響,並且能產生正向影響。所以我們可以繼續通過改變權重的方法來視圖提高模型的預測精度。
接下來,我們將這兩個類別的權重在擴大5倍,即相對於原始數據,這兩個類別的權重總共擴大了500倍:
wts <- c(1,500,500)
names(wts) <- c("setosa","versicolor","virginica")
model3 <- svm(x,y,class.weights = wts)
pred3 <- predict(model3,x)
table(pred3,y)
y
pred3 setosa versicolor virginica
setosa 50 0 0
versicolor 0 50 0
virginica 0 0 50
通過對權重的調整之后,我們建立的支持向量機模型能夠將所有樣本全部預測正確。所以在實際構建模型的過程中,在必要的時候可以通過改變各樣本之間的權重比例來提高模型的預測精度。