R语言之支持向量机

分类: R语言学习 |
- 在线性可分的情况下,存在这样的超平面把空间中的类分开,并且该超平面与类的距离最大即最大边缘超平面,它等价于求解约束的凸二次最优化问题,此时是在原输入空间(n维)内寻找最大边缘超平面;
- 在线性不可分的情况下,可以允许个别样本分类错误,但需要借助非线性映射把原输入数据变换到高维空间,在该空间搜索最大边缘超平面,将该超平面对应到原输入空间的非线性超平面。
- 分离超平面(separating hyperplane):处理分类问题的时候需要一个决策边界,这种决策边界将两类事物相分离,而线性的决策边界就是分离超平面。
- 最大边缘超平面(Maximal Margin Hyperplane):分离超平面可以有很多个,怎么找最好的那个呢,SVM的作法是找一个“最中间”的。换句话说,就是这个平面要尽量和两边保持距离,以留足余量,减小泛化误差,保证稳健性。在数学上找到这个最大边缘超平面的方法是一个二次规划问题。
- 软边缘(Soft Margin):在线性不可分情况下就要考虑软边缘了。软边缘可以破例允许个别样本跑到其它类别的地盘上去。但要使用参数来权衡两端,一个是要保持最大边缘的分离,另一个要使这种破例不能太离谱。这种参数就是对错误分类的惩罚程度C。
- 核函数(Kernel Function),为了解决完美分离的问题,SVM还提出一种思路,就是将原始数据映射到高维空间中去,直觉上可以感觉高维空间中的数据变的稀疏,有利于“分清敌我”。那么映射的方法就是使用“核函数”。如果这种“核技术”选择得当,高维空间中的数据就变得容易线性分离了。而且可以证明,总是存在一种核函数能将数据集映射成可分离的高维数据。维数过高的害处就是会出现过度拟合。
- Linear:使用它的话就成为线性向量机,效果基本等价于Logistic回归。但它可以处理变量极多的情况,例如文本挖掘。
- polynomial:多项式核函数,适用于图像处理问题。
- Radial basis:高斯核函数,最流行易用选择。参数包括了sigma,其值若设置过小,会有过度拟合出现。
- sigmoid:反曲核函数,多用于神经网络的激活函数。
http://s12/mw690/0024CtGngy70QEAsWG77b&690
二、支持向量机应用
## S4 method for signature 'formula'
ksvm(x, data = NULL, ..., subset, na.action = na.omit, scaled =
TRUE)
## S4 method for signature 'vector'
ksvm(x, ...)
## S4 method for signature 'matrix'
ksvm(x, y = NULL, scaled = TRUE, type = NULL,kernel ="rbfdot", kpar
= "automatic",
C = 1, nu = 0.2, epsilon = 0.1, prob.model = FALSE,class.weights =
NULL, cross = 0, fit = TRUE, cache = 40,tol = 0.001, shrinking =
TRUE, ...,subset, na.action = na.omit)
注
type的参数:
C-svc C
classification;nu-svc nu
classification;C-bsvc bound-constraint svm
classification
spoc-svc Crammer, Singer native
multi-class;kbb-svc Weston, Watkins native
multi-class
one-svc novelty
detection;eps-svr
epsilon regression
nu-svr nu regression;eps-bsvr
bound-constraint svm regression
vanilladot Linear kernel;tanhdot Hyperbolic tangent kernel
laplacedot Laplacian kernel;besseldot Bessel kernel
anovadot ANOVA RBF kernel;splinedot Spline kernel;stringdot String kernel
2)degree, scale, offset for the Polynomial kernel "polydot"
3)scale, offset for the Hyperbolic tangent kernel function "tanhdot"
4)sigma, order, degree for the Bessel kernel "besseldot".
5)sigma, degree for the ANOVA kernel "anovadot".
6)length, lambda, normalized for the "stringdot" kernel where lengthis the length of the strings considered, lambda the decay factor and normalizeda logical parameter determining if the kernel evaluations should be normalized.
- 分类算法
library(kernlab)
irismodel <-
ksvm(Species ~ ., data = iris,type = "C-bsvc", kernel
= "rbfdot",kpar = list(sigma = 0.1), C = 10, prob.model = TRUE)
irismodel
fitted(irismodel) #拟合值
#预测值
predict(irismodel, iris[c(3, 10, 56, 68, 107,
120), -5], type = "probabilities")
#Ksvm支持自定义核函数。如
k <- function(x, y) {
(sum(x * y) + 1) * exp(0.001 * sum((x - y)^2))
}
class(k) <- "kernel"
data(promotergene)
gene <- ksvm(Class ~
.,data=promotergene[c(1:20,80:100),],kernel = k,C = 10, cross =
5)
- 回归算法
x <-
seq(-20,20,0.1)
y <-
sin(x)/x + rnorm(401,sd=0.03)
regm <- ksvm(x,y,epsilon=0.01,kpar=list(sigma=16),cross=3)
plot(x,y,type="l") lines(x,predict(regm,x),col="red")
library(e1071)
data(cats, package="MASS")
inputData <- data.frame(cats[, c (2,3)], response = as.factor(cats$Sex)) # response as factor
传递给函数svm()的关键参数是kernel、cost和gamma
Kernel指的是支持向量机的类型,它可能是线性SVM、多项式SVM、径向SVM或Sigmoid SVM。
Cost是违反约束时的成本函数
gamma是除线性SVM外其余所有SVM都使用的一个参数。
还有一个类型参数,用于指定该模型是用于回归、分类还是异常检测。但是这个参数不需要显式地设置,因为支持向量机会基于响应变量的类别自动检测这个参数,响应变量的类别可能是一个因子或一个连续变量。所以对于分类问题,一定要把你的响应变量作为一个因子。
线性支持向量机:
svmfit <- svm(response ~ ., data = inputData, kernel = "linear", cost = 10, scale = FALSE) # linear svm, scaling turned OFF
print(svmfit)
plot(svmfit, inputData) compareTable <- table (inputData$response, predict(svmfit))# tabulate
mean(inputData$response != predict(svmfit)) # 19.44% misclassification error
径向支持向量机:径向基函数作为一个受欢迎的内核函数,可以通过设置内核参数作为“radial”来使用。当使用一个带有“radial”的内核时,结果中的超平面就不需要是一个线性的了。通常定义一个弯曲的区域来界定类别之间的分隔,这也往往导致相同的训练数据,更高的准确度。
svmfit <- svm(response ~ ., data = inputData, kernel = "radial", cost = 10, scale = FALSE) # radial svm, scaling turned OFF
print(svmfit)
plot(svmfit,
inputData)
compareTable <- table (inputData$response,
predict(svmfit)) # tabulate
mean(inputData$response != predict(svmfit)) #
18.75% misclassification error
寻找最优参数:可以使用tune.svm()函数,来寻找svm()函数的最优参数。
set.seed(100) # for reproducing results
rowIndices <- 1 :
nrow(inputData) # prepare row
indices
sampleSize <- 0.8 * length(rowIndices) # training sample size
trainingRows<- sample (rowIndices, sampleSize) # random sampling
trainingData <- inputData[trainingRows, ] # training data
testData <- inputData[-trainingRows, ] # test data
tuned <- tune.svm(response ~., data = trainingData, gamma = 10^(-6:-1), cost = 10^(1:2)) # tune
summary (tuned) # to select best gamma and cost
结果证明,当cost为100,gamma为0.001时产生最小的错误率。利用这些参数训练径向支持向量机。
svmfit <- svm (response ~ ., data = trainingData, kernel = "radial", cost = 100, gamma=0.001, scale = FALSE) # radial svm, scaling turned OFF
print(svmfit) plot(svmfit, trainingData) compareTable <- table (testData$response, predict(svmfit, testData)) # comparison table mean(testData$response != predict(svmfit, testData)) # 13.79% misclassification error
- 分类算法
library(e1071) set.seed(1234) ind<-sample(2,nrow(iris),replace=TRUE,prob=c(0.7,0.3)) train<-iris[ind==1,] test<-iris[ind==2,] svm<-svm(train[,1:4],train[,5],type="C-classification",cost=10,kernel="radial",probability=TRUE,scale=FALSE) pred<-predict(svm,test[,1:4],decision.values=TRUE) 或者 model <- svm(Species ~ ., data = iris,method = "C-classification", kernel = "radial",cost = 10, gamma = 0.1) summary(model) plot(model, iris, Petal.Width ~Petal.Length, slice = list(Sepal.Width = 3,Sepal.Length = 4)) pre=predict(model, iris,type='class') table(pre,iris$Species)
- 回归算法
library(e1071)
library(DMwR)
algae <- algae[-manyNAs(algae), ] clean.algae <- knnImputation(algae[,1:12],k=10) norm.data <- scale(clean.algae[,4:12]) #数据标准化 library(e1071) model.svm <- svm(a1~., norm.data) preds <- predict(model.svm, norm.data) plot(preds~ scale(clean.algae$a1))
install.packages("klaR")
library(MASS)
library(klaR)