基于SVM的数字识别步骤:
1、收集数据:提供的文本文件
2、准备数据:基于二值图像构造向量
3、分析数据:对图像向量进行目测
4、训练算法:采用两种不同的核函数,并对径向基核函数采用不同的设置来运行SMO算法
5、测试算法:编写一个函数来测试不同的核函数并计算错误率
6、使用算法:一个图像识别的完整应用还需要一些图像处理的知识。
构建一个系统去测试手写数字上的分类器:
def img2vector(filename):
returnVect=zeros((1,1024))
fr=open(filename)
for i in range(32):
lineStr=fr.readline()
for j in range(32):
returnVect[0,32*i+j]=int(lineStr[j])
return returnVect
def loadImages(dirName):
from os import listdir
hwLabels=[]
trainingFileList=listdir(dirName)
m=len(trainingFileList)
trainingMat=zeros((m,1024))
for i in range(m):
fileNameStr=trainingFileList[i]
fileStr=fileNameStr.split('.')[0]
classNumStr=int(fileStr.split('_')[0])
if classNumStr==9:
hwLabels.append(-1)
else:
hwLabels.append(1)
trainingMat[i,:]=img2vector('%s/%s'%(dirName,fileNameStr))
return trainingMat,hwLabels
def testDigits(kTup=('rbf',10)):
dataArr,labelArr=loadImages('trainingDigits')
b,alphas=svm_11.smoP(dataArr,labelArr,200,0.0001,10000,kTup)
dataMat=mat(dataArr)
labelMat=mat(labelArr).transpose()
svInd=nonzero(alphas.A>0)[0]
sVs=dataMat[svInd]
labelSV=labelMat[svInd]
print('there are %d Support Vectors' % shape(sVs)[0])
m,n=shape(dataMat)
errorCount=0
for i in range(m):
kernelEval=svm_11.kernelTrans(sVs,dataMat[i,:],kTup)
predict=kernelEval.T*multiply(labelSV,alphas[svInd])+b
if sign(predict)!=sign(labelArr[i]):
errorCount=errorCount+1
print('训练集错误率:',(float(errorCount)/m))
dataArr,labelArr=loadImages()
errorCount = 0
dataMat=mat(dataArr)
labelMat=mat(labelArr).transpose('testDigits')
m,n=shape(dataMat)
for i in range(m):
kernelEval = svm_11.kernelTrans(sVs, dataMat[i, :], kTup)
predict = kernelEval.T * multiply(labelSV, alphas[svInd]) + b
if sign(predict) != sign(labelArr[i]):
errorCount = errorCount + 1
print('测试集错误率:', (float(errorCount) / m))
testDigits()
函数loadImages()是作为k近邻算法中的一部分出现的。它已经被重构为自身的一个函数。其中最大的区别在于,支持向量机中类别标签为-1和+1,,因此,一旦碰到数字9,则输出类别标签-1,否则输出+1,。本质上,支持向量机是一个二类分类器,其分类结果不是+1就是-1。
testDigits()和testRbf()几乎一样,区别在于它调用了loadImages()函数来获得类别标签和数据。kTup是输入参数。
上述代码运行结果: