当前位置:   article > 正文

机器学习:k-近邻算法(三)sklearn手写数字识别

sklearn手写数字识别

目录

一、实战背景

二、sklearn

1、sklearn的简介

2、sklearn安装

 3.sklearn实现k-近邻算法简介

三、使用sklearn实现手写数字识别

 1、提供的数据是32x32的二进制图像,将其转化为1x1024的向量。编写代码如下:

2.调用sklearn.neighbors.KNeighborsClassifier实现手写数字识别

3.main函数实现

4.测试结果

四、自己用Python写k-近邻算法分类器实现

1.代码如下:

2.测试结果如下:


一、实战背景

这里的手写数字数据经过图形处理,被处理成了相同颜色和大小,宽高为32x32,采用文本的格式存储图像,数字的文本格式如下图:

这些文本格式的数据文件的命名也有特点,格式为:数字的值_该数字的样本序号,如下图所示:

 数据集的下载地址:数据集下载

对于处理好的文本,这里采用python提供的第三方库Sklearn构建手写数字系统,当然也可以用上一小节(机器学习:K-近邻算法(二)约会网站配对效果_晶哥哥&的博客-CSDN博客)的方法设计K-近邻算法分类器。

二、sklearn

1、sklearn的简介

参考:手写数字识别中的sklearn简介

2、sklearn安装

在安装sklearn之前需要安装两个库,即numpy+mkl和scipy,这里不建议用pip安装,第三方库的下载地址:http://www.lfd.uci.edu/~gohlke/pythonlibs/

在网页中找到对应的版本的numpy+mkl和scipy,Ctrl+F可以出现搜索框搜索这两个库,如下图所示

 

 分析这里边的数字代表什么,例如

 (1)1.22.3代表你python中numpy库的版本号

(2)cp38代表你python的版本号为3.8.x

(3)amd64代表你电脑的位数为64

根据自己的电脑和安装的Python选择,如何查看python版本号和numpy库的版本号,看下面:

先打开cmd,然后按照下方输入

 

scipy中的数字理解和上边一样,这里介绍scipy的版本查看:

接着上面的cmd往下输入

这两个.whl文件下载完成后,输入下面箭头所指的命令下载安装sklearn,这里注意,要先退出python环境,输入:exit(0),然后再输入箭头所指的命令

 3.sklearn实现k-近邻算法简介

官网英文文档:英文文档

里面有sklearn.neighbors.KNeighborsClassifier参数介绍,方法介绍,可以参考这个大佬的文章介绍:参数中文介绍

三、使用sklearn实现手写数字识别

 1、提供的数据是32x32的二进制图像,将其转化为1x1024的向量。编写代码如下:

  1. import numpy as np
  2. def img2vector(filename):
  3. #初始化1x1024向量
  4. returnVect=np.zeros((1,1024))
  5. #打开文件
  6. file=open(filename)
  7. #将数据的每一行一次存放到向量中
  8. for i in range(32):
  9. #读取一行数据
  10. lineStr=file.readline()
  11. for j in range(32):
  12. returnVect[0,32*i+j]=int(lineStr[j])
  13. #返回转换后的1x1024向量
  14. return returnVect

2.调用sklearn.neighbors.KNeighborsClassifier实现手写数字识别

编写代码如下:

  1. from sklearn.neighbor import KNeighborsClassifier as KNN
  2. from os import listdir
  3. import numpy as np
  4. def handwriteClassTest():
  5. #获得训练集的类别labels
  6. hwLabels=[]
  7. #获取trainingDigits目录下的文件名
  8. trainingFileList=listdir('trainingDigits')
  9. #得到文件的个数
  10. m=len(trainingFileList)
  11. #初始化训练集矩阵
  12. trainingMat=np.zeros((m,1024))
  13. #从文件中解析出训练集的类别
  14. for i in range(m):
  15. #获得文件的名字
  16. fileNameStr=trainingFileList[i]
  17. #获得分类的数字
  18. classNumber=int(fileNameStr.split('_')[0])
  19. #将类别添加到类别Labels中
  20. hwLabels.append(classNumber)
  21. #将每一个文件的数据存放到训练集中
  22. trainingFileList[i,:]=img2vector('trainingDigits/%s'%(fileNameStr))
  23. #构建KNN分类器,调用
  24. neigh=KNN(n_neighbors=5,algorithm='auto')
  25. #拟合模型
  26. neigh.fit(trainingMat,hwLabels)
  27. #获取测试集下文件
  28. testFlieList=listdir('testDigits')
  29. #获取测试集的文件个数
  30. mTest=len(testFileList)
  31. #错误计数器
  32. errorCount=0.0
  33. #从文件中获取测试集类别
  34. for i in range(mTest):
  35. #获取文件的名字
  36. fileNameStr=testFileList[i]
  37. #获取类别
  38. classNumber=int(fileNameStr.split('_'[0]))
  39. #获得测试集向量1x1024
  40. vectorUnderTest=img2vector('testDigits/%s'%(fileNameStr))
  41. #获得预测结果
  42. classfierResult=neigh.predict(vectorUnderTest)
  43. print('分类返回结果为%d\t真实结果为%d'%(classfierResult,classNumber))
  44. if classfierResult!=classNumber:
  45. errorCount+=1.0
  46. print('总共错了%d个数据,错误率为%f%%'%(errorCount,errorCount/mTest*100))

3.main函数实现

  1. if __name__=='__main__':
  2. handwriteClassTest()

4.测试结果

 

四、自己用Python写k-近邻算法分类器实现

1.代码如下:

  1. import numpy as np
  2. import operator
  3. from os import listdir
  4. '''
  5. 函数说明:KNN算法分类器,做距离计算找出前k个距离最小的结果中最小距离分类
  6. 参数:
  7. inX---用于分类的数据,测试集
  8. dataSet---用于训练的数据,训练集
  9. labels--分类标签
  10. k---KNN算法参数,选择距离最小的k个点
  11. '''
  12. def classify0(inX,dataSet,labels,k):
  13. #获取训练集的行数
  14. dataSetsize=dataSet.shape[0]
  15. #矩阵相减
  16. diffMat=np.tile(inX,(dataSetsize,1))-dataSet
  17. #平方
  18. sqDiffMat=diffMat**2
  19. #平方后的数据相加
  20. sqDistances=sqDiffMat.sum(1)
  21. #开平方,得到距离
  22. distances=sqDistances**0.5
  23. #获取distances中元素从小到大后索引值
  24. sortedDistIndices=distances.argsort()
  25. #初始化记录类别数的字典
  26. classCount={}
  27. #计算前k个距离的类别个数
  28. for i in range(k):
  29. #取出前k个元素的类别
  30. voteIlabel=labels[sortedDistIndices[i]]
  31. #计算类别次数
  32. classCount[voteIlabes]=classCount.get(voteIlabel,0)+1
  33. #按照值降序排列
  34. sortedClassCount=sorted(classCount.items(),key=operator.itemgetter(1),reverse=True)
  35. #返回次数最多的类别
  36. return sortedClassCount[0][0]
  37. '''
  38. 函数说明:将32x32的二进制图像转化为1x1024向量
  39. 参数:filename----文件名
  40. '''
  41. def img2vector(filename):
  42. #初始化1x1024向量
  43. returnVect=np.zeros((1,1024))
  44. #打开文件
  45. file=open(filename)
  46. #按行读取
  47. for i in range(32):
  48. #读取一行
  49. lineStr=file.readline()
  50. #将每一行数据一次存放到returnVect
  51. for j in range(32):
  52. returnVect[0,i*32+j]=int(lineStr[j])
  53. #返回转换后的1x1024向量
  54. return returnVect
  55. '''
  56. 函数说明:手写数字分类测试
  57. '''
  58. def handwriteClassTest():
  59. #初始化训练集labels
  60. hwLabels=[]
  61. #获取训练集文件下的文件
  62. trainingFileList=listdir('trainingDigits')
  63. #获得文件个数
  64. m=len(trainingFileList)
  65. #初始化训练集矩阵
  66. trainingMat=np.zeros((m,1024))
  67. #从文件中解析类别
  68. for i in range(m):
  69. #获得文件名字
  70. fileNameStr=trainingFileList[i]
  71. #获得分类的数字
  72. classNumber=int(filenNameStr.split('_')[0])
  73. #将获得类别添加
  74. hwLabels.append(classNumber)
  75. #将文件的数据存储到训练集矩阵
  76. trainingMat[i,:]=img2vector('trainingDigits/%s'%(fileNameStr))
  77. #获得测试集文件下的文件名
  78. testFileList=listdir('testDigits')
  79. #测试集数据的数量
  80. mTest=len(testFileList)
  81. #错误计数
  82. errorCount=0.0
  83. #从文件中解析测试集的类别并进行分类
  84. for i in range(mTest):
  85. #获得文件名
  86. fileNameStr=testFileList[i]
  87. #获得类别数字
  88. classNumber=int(fileNameStr.split('_')[0])
  89. #获得测试的1x1024向量,用于训练
  90. vectorUnderTest=img2vector('testDigits/%s'%(fileNameStr))
  91. #获得预测结果
  92. classifierReult=classify0(vectorUnderTest,trainingMat,hwLabels,3)
  93. print('分类返回结果%d/t真实分类结果%d'%(classifierReult,classNumber))
  94. if classifierReult!=classNumber:
  95. errorCount+=1.0
  96. print('总共错了%d个数据\n错误率为%f%%'%(errorCount,errorCount/mTest*100))
  97. '''
  98. 函数说明:main函数
  99. '''
  100. if __name__=='__main__':
  101. handwriteClassTest()

2.测试结果如下:

 

 

ps:

k-近邻算法结束。

K-近邻算法理解遗留问题,它的缺点:无法给出数据的内在含义。不理解数据的内在含义

批注:我学习的博主Jack Cui,网址:Jack Cui | 关注人工智能及互联网的个人网站 (cuijiahua.com)

我就是看他的学习记录学习的,详细学习内容可进入他的网站学习。我写文章主要目的是为了再次熟悉代码和记录不会的知识点。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/248524?site
推荐阅读
相关标签
  

闽ICP备14008679号