使用支持向量机进行光学字符识别

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

支持向量机算法的任务就是寻找一块超平面实现分类器的功能,它可以很好的解决线性可分的数据集和线性不可分的数据集,对于线性可分的数据集,就是寻找一条最大间隔超平面:

0?wx_fmt=jpeg
对于线性不可分的数据集,需要使用某种核函数,可以是线性核函数、多项式核函数、高斯核函数和神经网络核函数等。支持向量机算法的理论和应用还可以参考本公众号《基于R语言的支持向量机实现》一文(http://mp.weixin.qq.com/s?__biz=MzIxNjA2ODUzNg==&mid=400629255&idx=1&sn=57d7081aaccbe05959429c514c802a62#rd),这里不再赘述。


一、支持向量机的优缺点

优点:

1)可解决离散的分类和连续数值的预测问题

2)不会过多地受噪声数据的影响

3)精准度高,灵活性强

缺点:

1)寻找最好的模型需要测试不同的核函数和模型参数的组合

2)训练缓慢,尤其是数据维度高或观测量极大的情况下

3)模型结果不易解释

有关支持向量机算法的实现可以使用R语言中e1071包中的svm()函数或kernlab包中的ksvm()函数。


二、函数介绍

有关支持向量机算法的实现可以使用R语言中e1071包中的svm()函数或kernlab包中的ksvm()函数。

由于《基于R语言的支持向量机实现》中使用了e1071包中的svm()函数,本文尝试使用kernlab包中的ksvm()函数,函数语法如下:

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)

x:指定模型的自变量,可以是向量、矩阵,切记不可以是数据框格式

y:指定因变量,可以是因子,也可以是数值型向量

scaled:指定数据是否标准化,默认将原始数据进行标准化处理

type:指定模型是用于离散因变量分类还是连续因变量的预测

kernel:指定使用何种核函数,可以是高斯核函数、线性核函数、多项式核函数等

kpar:指定核函数的参数值,以列表的形式存放

C:指定违反约束条件的惩罚(成本),默认为1

class.weights:为不同水平的类赋予不同的权重,可以提高分类的准确性

cross:整数值,可以指定训练数据集上的k重交叉验证,同样可以提高模型的准确率

na.action:指定缺失值的处理办法,默认将删除缺失值


三、应用

支持向量机非常适合图像数据的处理,它能够学习复杂的图案而不受噪声数据的影响。本文将使用该算法识别如下图所示的英文字母:

0?wx_fmt=jpeg
当图像字符被扫描到计算机中时,它们将转换成像素,包括图像字符的水平尺寸、垂直尺寸、像素的平均水平等指标。

本文所使用的数据来源是《机器学习与R语言》书中的案例数据,数据包含了26个大写英文字母的20000个观测,20个变量体现如上图所示的字母像素点指标。


#读取数据

letters <- read.csv(file = file.choose())

str(letters)

0?wx_fmt=jpeg
除letter变量为因子变量,其余变量均为整数变量。

#生成训练样本和测试样本

set.seed(1234)

index <- sample(x = c(1,2), size = nrow(letters), replace = TRUE, prob = c(0.7,0.3))

train <- letters[index == 1,]

test <- letters[index == 2,]


#查看训练集和测试集中字符比例

train_letter_ratio <- as.data.frame(prop.table(table(train$letter)))

test_letter_ratio <- as.data.frame(prop.table(table(test$letter)))

Ratio <- data.frame(train_letter_ratio = train_letter_ratio, test_letter_ratio = test_letter_ratio[,2])

names(Ratio) <- c('Letters','Train_Ratio','Test_Ratio')

Ratio

0?wx_fmt=jpeg
总体上看,两组数据集中字母的比例几乎接近。


ksvm()函数提供了5种分类的类型,分别是‘C-svc’,‘nu-svc’,‘C-bsvc’,‘spoc-svc’,‘kbb-svc’,同时也提供了4种最常用的核函数,它们是‘rbfdot’,‘polydot’,‘vanilladot’,‘tanhdot’。如何选择这些搭配是一个问题,下面通过循环选择各种组合,挑选出最为理想的参数组合。


library(kernlab)

KSVM <- function(x,y){

type <- c('C-svc','nu-svc','C-bsvc','spoc-svc','kbb-svc')

kernel <- c('rbfdot','polydot','vanilladot','tanhdot')

#用于存放20种组合的预测结果

pred <- array(0, dim=c(nrow(x),5,4))

#用于存放预测错误数

errors <- matrix(0,5,4)

dimnames(errors) <- list(type, kernel)

for(i in 1:5){

for(j in 1:4){

pred[,i,j] <- predict(object = ksvm(x, y, type = type[i], kernel = kernel[j]), newdata = x)

errors[i,j] <- sum(pred[,i,j] != as.integer(y))

}

}

return(errors)

}


由于数据量比较大,模型训练起来非常缓慢,这里从测试集中挑选出2000样本进行测试。

model <- KSVM(x = as.matrix(train[1:2000,-1]), y = train[1:2000,1] )

0?wx_fmt=jpeg
通过对比发现,当type='kbb-svc',kernel='rbfdot'时的组合模型的错误率最低,接下来对该组合的参数进行建模。

#建模

fit2 <- ksvm(x = as.matrix(train[,-1]), y = train[,1], type='kbb-svc', kernel='rbfdot')

#预测

pred2 <- predict(object = fit2, newdata = test[,-1])

#模型的准确率

Freq2 <- table(test[,1], pred)

Freq2

0?wx_fmt=jpeg
accuracy2 <- sum(diag(Freq))/sum(Freq)

accuracy2

0?wx_fmt=jpeg
模型对图像的准确识别率超过94%,测试结果还是比较满意的。


文中的数据和脚本可到如下链接下载:

http://yunpan.cn/c3hGUShAHLpI6 访问密码 fec0


四、总结:文中用到的R包和函数

read.csv()

str()

kernlab包

ksvm()

predict()

table()


五、参考资料

机器学习与R语言

数据挖掘:R语言实战




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值