天天看點

黑箱方法 支援向量機②

支援向量機

1. R中svm介紹

  • R的函數包e1071提供了libsvm的接口。使用e1071包中svm函數可以得到與libsvm相同的結果。write.svm()更是可以把R訓練得到的結果寫為标準的Libsvm格式,以供其他環境下libsvm的使用。下面我們來看看svm()函數的用法。有兩種格式都可以。
> # svm函數的基本文法及參數解釋
> svm(formula, data = NULL, ..., subset, na.action =na.omit, scale = TRUE)
# formula:指定參與分析的變量公式
# subset:為索引向量,指定分析的樣本資料
# na.action:針對缺失值的處理方法,預設會删除缺失值所在的行
# scale:邏輯參數,是否标準化變量,預設标準化處理
           
> 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,
+ class.weights = NULL, cachesize = 40, tolerance = 0.001, epsilon = 0.1,
+ shrinking = TRUE, cross = 0, probability = FALSE, fitted = TRUE,...,subset,
+ na.action = na.omit)
# x:可以是矩陣,可以是向量,也可以是稀疏矩陣
# y:分類變量
# type:指定模組化的類别,支援向量機通常用于分類、回歸和異常值檢測,預設情況下,svm模型根據因變量y是否為因子,type選擇C-classification或eps-regression
# kernel:指定模組化過程中使用的核函數,目的在于解決支援向量機線性不可分問題。函數中有四類核函數可選,即線性核函數、多項式核函數、高斯核函數和神經網絡核函數
# degree:用于多項式核函數的參數,預設為3
# gamma:用于除線性核函數之外的所有核函數參數,預設為1
# coef0:用于多項式核函數和神經網絡核函數的參數,預設為0
# nu:用于nu-classification、nu-regression和one-classification回歸類型中的參數
# class.weights:指定類權重
# cachesize:預設緩存大小為40M
# cross:可為訓練集資料指定k重交叉驗證
# probability:邏輯參數,指定模型是否生成各類的機率預測,預設不産生機率值
# fitted:邏輯參數,是否将分類結果包含在模型中,預設生成拟合值
           

degree:多項式核的次數,預設為3

gamma:除去線性核外,其他核的參數,預設為1/資料維數

coef0:多項式核與sigmoid核的參數,預設為0.

cost:C分類中懲罰項c的取值

nu:Nu分類,單一分類中nu的值

cross:做k折交叉驗證,計算分類正确性。

首先,對于分類問題而言,svm()han函數中的'type'參數有C-classification、nu-classification和one-classification三種選項,  

核函數'kernel'參數有linear、polynomial、radial和sigmoid四種選項,  
           

2. 一個具體的小例子。

我們依然使用iris資料集(R中自帶的關于三類植物的資料集)來做svm分類。如下

data(iris)
ir<-iris
set.seed(124)
count.test<-round(runif(50,1,150))
test<-ir[count.test,]
library(e1071)
sv<-svm(Species~.,data=ir,cross=5,type='C-classification',kernel='sigmoid')
summary(sv) #檢視支援向量機sv的具體資訊,發現做5倍交叉驗證的正确率為92%
pre<-predict(sv,test)#對測試樣本作預測。pre是一個類别向量。
dim(test[test$Species!=pre,])[1]/dim(test)[1]#計算錯誤率

[1] 0.06

我們發現錯誤率為6%

3.執行個體操作

#=========================================================

#--------load file and divide the data to train and test

#========================================================
setwd("E:\\Rwork")
library(e1071)
svm_data <- read.csv("BLCA.mRNA.for.rf.csv",header = T)
svm_data <- svm_data[,-1]
set.seed(1234)
index <- sample(nrow(svm_data),0.7*nrow(svm_data))
svm_train <- svm_data[index,]
svm_test <- svm_data[-index,]
svm_train$subtype <- as.character(svm_train$subtype)
svm_train$subtype <- as.factor(svm_train$subtype)
svm_test$subtype <- as.character(svm_test$subtype)
svm_test$subtype <- as.factor(svm_test$subtype)
#================================================

#----------establish the mdel

#================================================


x <- svm_train[,-1]

y <- svm_train[,1]

library(e1071)

SVM <- function(x,y){
  
  type <- c('C-classification','nu-classification','one-classification')
  
  kernel <- c('linear','polynomial','radial','sigmoid')
  
  #用于存放12種組合的預測結果
  
  pred <- array(0, dim=c(nrow(x),3,4))
  
  #用于存放預測錯誤數
  
  errors <- matrix(0,3,4)
  
  dimnames(errors) <- list(type, kernel)
  
  for(i in 1:3){
    
    for(j in 1:4){
      
      pred[,i,j] <- predict(object = svm(x, y, type = type[i], kernel = kernel[j]), newdata = x)
      
      if(i > 2) errors[i,j] <- sum(pred[,i,j] != 1)
      
      else errors[i,j] <- sum(pred[,i,j] != as.integer(y))
      
    }
    
  }
  
  return(errors)
  
}

SVM(x = x, y = y)


classifier <- svm(x = x, y = y, type = 'C-classification', 
             kernel = 'radial')


           
> SVM(x = x, y = y)
                   linear polynomial radial sigmoid
C-classification        0          0      0       1
nu-classification       7          0      4       9
one-classification    145        187    142     152
           

發現type為C-classification和radial 及 linear等時error最低

  • 交叉驗證
#================================================

#----------K-fold corss validation

#================================================
library(caret)
folds <- createFolds(svm_train$subtype, k=10)
cv <- lapply(folds, function(x) {
  training_fold = svm_train[-x,]
  test_fold = svm_train[x,]
  classifier = svm(formula = subtype ~.,
                   data =training_fold,
                   type = "C-classification",
                   kernal = "radial")
  confusion=table(test_fold$subtype,predict(classifier,test_fold,type="class"))
  accuracy=sum(diag(confusion))/sum(confusion)
  return(accuracy)
})

           

繼續閱讀