机器学习实战K近邻3-识别手写体
前面两个小节都给出了完整的代码,这部分我只打算贴出自定义的函数:
#手写体识别,将图像转换为向量格式
#将数据处理成分类器可以识别的格式
def img2vector(filename):
returnVect = zeros((1,1024))#定义一个空矩阵;1024=32*32
fr =open(filename)
for iin range(32):#将每行的头32个字符存在数组中
lineStr = fr.readline()
for jin range(32):#将每列的头32个字符存在数组中
returnVect[0,32*i+j] =int(lineStr[j])
return returnVect
def handwritingClassTest():
hwLabels = []
trainingFileList = listdir('trainingDigits')
m =len(trainingFileList)
trainingMat = zeros((m,1024))#创建m行1024列训练矩阵,每行数据存储一个图像
for iin range(m):
fileNameStr = trainingFileList[i]#获取标签,也就是获取这个数字是几
fileStr = fileNameStr.split('.')[0]
#对文件名进行分割。就是2_45.txt,从.那个地方开始分割文件名,就得到2_45和txt两部分,我是这么理解的
#split()[0] split()里面是空的时候,默认删除空白符,[0]表示取分割后数组的第一个元素
classNumStr =int ((fileStr.split('_'))[0])
hwLabels.append(classNumStr)
trainingMat[i,:] = img2vector('trainingDigits/%s'%fileNameStr)
testFileList = listdir('testDigits')
errorCount =0.0 #初始化错误率
mTest =len(testFileList)
for iin range(mTest):
fileNameStr = testFileList[i]
fileStr = fileNameStr.split('.')[0]
#对文件名进行分割。就是2_45.txt,从.那个地方开始分割文件名,就得到2_45和txt两部分,我是这么理解的
#split()[0] split()里面是空的时候,默认删除空白符,[0]表示取分割后数组的第一个元素
classNumStr =int (fileStr.split('_')[0])
vectorUnderTest = img2vector('trainingDigits/%s'%fileNameStr)
classifierResult = classify0(vectorUnderTest, trainingMat, hwLabels,3)
print "the classifier came back with :%d,the real answer is :%d"%(classifierResult, classNumStr)
if (classifierResult != classNumStr):
errorCount +=1.0
print "the total number of error is %d" % errorCount
print "the total error rate is %s" %float(errorCount/float(mTest))
if __name__ =="__main__":
#datingClassTest()
#classifyperson()
handwritingClassTest()
K近邻算法:
1)必须保存全部数据集,如果训练数据集很大,必须使用大量的存储空间
2)要计算每个数据集的距离值,非常耗时
3)无法给出任何数据的基础结构信息,我们无法知晓平均实例和典型实例样本具体是什么特征
上述代码出现了一个问题,误差相当大,高达了71%,代码运行正常,可能别的地方出了问题,欢迎交流~