基于R语言的支持向量机实现

数据挖掘一般包含四类算法,即分类、聚类、预测和关联,分类中常用的有Logistic回归、决策树、贝叶斯、支持向量机等算法,本文将针对支持向量机做一个简单的介绍和应用。

支持向量机是数据挖掘中的一项新技术,是借助于最优化方法来解决机器学习问题的新工具,开始成为克服“维度灾难”和过学习等困难的强有力手段。

支持向量机的简介

这里用一个线性分类器来引入支持向量机的原理,下图为线性分类器的一个例子:

0?wx_fmt=jpeg
从图中可知,线性可分的那条直线即为分类器,在高维中,这条直线称为超平面。很明显A点和W点同属于一类,而B点恰好在分类器上,无法正确判断它属于哪个类别。图中的omiga就为点到线的距离,在分类器中,希望点到线的距离越大越好,越大越能说明分类的可信度越高,正如A点和W点。

如果在高维分类器中,就可以将点到线的距离理解为点到超平面的距离,根据点到面的距离公式:

0?wx_fmt=jpeg
可以将距离公式用向量的形式表示为:

0?wx_fmt=jpeg
为了能够求解距离的最大化,即:0?wx_fmt=jpeg
可以将图中的式子改写为:0?wx_fmt=jpeg
这就将最大化问题变为了求解最小化的问题,这是一个典型的二次规划问题,从而使问题简单化,进一步可以方便的求出参数w和b。

上面所介绍的是基于线性可分的情况,对于现实数据中很大一部分都是线性不可分的,这时就要考虑使用核函数将特征映射到高维中,解决线性不可分问题。如图所示,原始特征是线性不可分的,通过高斯核函数变换后,就可以实现新的线性可分:

0?wx_fmt=jpeg

R语言用语

支持向量机可通过e1071包中的svm()函数实现,有关该函数的语法如下:

svm(formula, data = NULL, ..., subset,

na.action =na.omit, scale = TRUE)


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)


formula指定参与分析的变量公式,类似于y~x1+x2;

data指定分析的数据集;

subset为一个索引向量,指定分析的样本数据;

na.action针对缺失值的处理方法,默认会删除缺失值所在的行;

scale逻辑参数,是否标准化变量,默认标准化处理;

x可以是矩阵,可以是向量,也可以是稀疏矩阵;

y为分类变量;

type指定建模的类别,支持向量机通常用于分类、回归和异常值检测,默认情况下,svm模型根据因变量y是否为因子,type选择C-classification或eps-regression。

kernel指定建模过程中使用的核函数,目的在于解决支持向量机线性不可分问题。有四类核函数可选,即线性核函数、多项式核函数、径向基核函数(高斯核函数)和神经网络核函数研究人员发现,识别率最高,性能最好的是径向基核函数(默认的kernel值),其次是多项式核函数,最差的是神经网络核函数

degree用于多项式核函数的参数,默认为3;

gamma用于除线性核函数之外的所有核函数参数,默认为1;

coef0用于多项式核函数和神经网络核函数的参数,默认为0;

nu用于nu-classification、nu-regression和one-classification回归类型中的参数

class.weights指定类权重;

cachesize默认缓存大小为40M;

cross可为训练集数据指定k重交叉验证;

probability逻辑参数,指定模型是否生成各类的概率预测,默认不产生概率值;

fitted逻辑参数,是否将分类结果包含在模型中,默认生成拟合值。


应用

对于分类问题,支持向量机的type参数有C-classification、nu-classification和one-classification三种选项,核函数kernel参数有linear、polynomial、radial和sigmoid四种选项,为了综合比较这12种组合的模型效果,编辑脚本如下:

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)

}

有关该函数需要注意的几点:

1)x为分析的自变量数据框或矩阵;

2)y为分析的因变量向量,必须为因子

3)nu-classification、one-classification与C-classification的预测返回值不同,所以在统计错误预测时分if条进行两种处理。


这里以R中自带的iris数据集为例,看看这12种组合在该数据集中的优劣:

x <- iris[,1:4]

y <- iris[,5]

SVM(x = x, y = y)

0?wx_fmt=jpeg
根据以上结果,type='C-classification',kernel='radial'的返回错判量最小,故可以考虑这种组合对iris进行分类。


model <- svm(x = iris[,1:4], y = iris[,5], type = 'C-classification', kernel = 'radial')

pred <- predict(object = model, newdata = iris[,1:4])

Freq <- table(iris[,5], pred)

Freq

accuracy <- sum(diag(Freq))/sum(Freq)

accuracy

0?wx_fmt=jpeg
正确分类率达到97.3%,但任然发现有4个样本被误判,为了进一步提高分类效果,可以考虑使用svm函数中的class.weights参数为不同的类指定权重一般规则是:某个类与其他类存在明显差异时,考虑给予较小的权重,某些类之间差异较小时,考虑给予较大的权重


library(ggplot2)

p <- ggplot(data = iris)

p <- p + geom_point(mapping = aes(x = Petal.Length, y = Petal.Width, colour = Species))

p

0?wx_fmt=png
从图中明显得出setosa与versicolor、virginica存在明显差异,故考虑赋给setosa的权重小一点,而赋给versioolor和virginica的权重大一些。


#给versicolor和virginica分布赋予200和500的权重,而setosa只赋予1的权重

weights <- c(1,200,500)

names(weights) <- c('setosa','versicolor','virginica')

model2 <- svm(x = iris[,1:4], y = iris[,5], type = 'C-classification', kernel = 'radial', class.weights = weights)

pred2 <- predict(object = model2, newdata = iris[,1:4])

Freq2 <- table(iris[,5], pred2)

Freq2

accuracy2 <- sum(diag(Freq2))/sum(Freq2)

accuracy2

0?wx_fmt=jpeg
这个时候,模型的分类正确率提高到99.3%。


参考资料:

数据挖掘:R语言实战

http://www.chinakdd.com/article-W82k0g2822JE712.html

http://blog.csdn.net/passball/article/details/7661887/


总结:文中涉及到的R包和函数

e1071包

svm()

predict()

ggplot2包

ggplot()

geom_point()

  • 1
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值