python使用KNN算法识别手写数字


Posted in Python onApril 25, 2019

本文实例为大家分享了python使用KNN算法识别手写数字的具体代码,供大家参考,具体内容如下

# -*- coding: utf-8 -*-
#pip install numpy
import os
import os.path
from numpy import *
import operator
import time
from os import listdir
 
"""
描述:
  KNN算法实现分类器
参数:
  inputPoint:测试集
  dataSet:训练集
  labels:类别标签
  k:K个邻居
返回值:
  该测试数据的类别
"""
def classify(inputPoint,dataSet,labels,k):
  dataSetSize = dataSet.shape[0] #已知分类的数据集(训练集)的行数
  #先tile函数将输入点拓展成与训练集相同维数的矩阵,再计算欧氏距离
  diffMat = tile(inputPoint,(dataSetSize,1))-dataSet #样本与训练集的差值矩阵
 
  # print(inputPoint);
  sqDiffMat = diffMat ** 2 #sqDiffMat 的数据类型是nump提供的ndarray,这不是矩阵的平方,而是每个元素变成原来的平方。
  sqDistances = sqDiffMat.sum(axis=1)  #计算每一行上元素的和
  # print(sqDistances);
  distances = sqDistances ** 0.5   #开方得到欧拉距离矩阵
  # print(distances);
  sortedDistIndicies = distances.argsort() #按distances中元素进行升序排序后得到的对应下标的列表,argsort函数返回的是数组值从小到大的索引值
  # print(sortedDistIndicies);
 
  # classCount数据类型是这样的{0: 2, 1: 2},字典key:value
  classCount = {}
  # 选择距离最小的k个点
  for i in range(k):
    voteIlabel = labels[ sortedDistIndicies[i] ]
    # print(voteIlabel)
    # 类别数加1
    classCount[voteIlabel] = classCount.get(voteIlabel,0)+1
  print(classCount)# {1: 1, 7: 2}
  #按classCount字典的第2个元素(即类别出现的次数)从大到小排序
  sortedClassCount = sorted(classCount.items(), key = operator.itemgetter(1), reverse = True)
  print(sortedClassCount)# [(7, 2), (1, 1)]
  return sortedClassCount[0][0]
 
"""
描述:
  读取指定文件名的文本数据,构建一个矩阵
参数:
  文本文件名称
返回值:
  一个单行矩阵
"""
def img2vector(filename):
 returnVect = []
 fr = open(filename)
 for i in range(32):
  lineStr = fr.readline()
  for j in range(32):
   returnVect.append(int(lineStr[j]))
 return returnVect
 
"""
描述:
  从文件名中解析分类数字,比如由0_0.txt得知这个文本代表的数字分类是0
参数:
  文本文件名称
返回值:
  一个代表分类的数字
"""
def classnumCut(fileName):
  fileStr = fileName.split('.')[0]
  classNumStr = int(fileStr.split('_')[0])
  return classNumStr
 
"""
描述:
  构建训练集数据向量,及对应分类标签向量
参数:
  无
返回值:
  hwLabels:分类标签矩阵
  trainingMat:训练数据集矩阵
"""
def trainingDataSet():
  hwLabels = []
  trainingFileList = listdir('trainingDigits')   #获取目录内容
  m = len(trainingFileList)
  # zeros返回全部是0的矩阵,参数是行和列
  trainingMat = zeros((m,1024))    #m维向量的训练集
  for i in range(m):
    # print (i);
    fileNameStr = trainingFileList[i]
    hwLabels.append(classnumCut(fileNameStr))
    trainingMat[i,:] = img2vector('trainingDigits/%s' % fileNameStr)
  return hwLabels,trainingMat
 
"""
描述:
  主函数,最终打印识别了多少个数字以及识别的错误率
参数:
  无
返回值:
  无
"""
def handwritingTest():
  """
  hwLabels,trainingMat 是标签和训练数据,
  hwLabels 是一个一维矩阵,代表每个文本对应的标签(即文本所代表的数字类型)
  trainingMat是一个多维矩阵,每一行都代表一个文本的数据,每行有1024个数字(0或1)
  """
  hwLabels,trainingMat = trainingDataSet() #构建训练集
  testFileList = listdir('testDigits') #获取测试集
  errorCount = 0.0    #错误数
  mTest = len(testFileList)    #测试集总样本数
  t1 = time.time()
  for i in range(mTest):
    fileNameStr = testFileList[i]
    classNumStr = classnumCut(fileNameStr)
    # img2vector返回一个文本对应的一维矩阵,1024个0或者1
    vectorUnderTest = img2vector('testDigits/%s' % fileNameStr)
    #调用knn算法进行测试
    classifierResult = classify(vectorUnderTest, trainingMat, hwLabels, 3)
    # 打印测试出来的结果和真正的结果,看看是否匹配
    print ("the classifier came back with: %d, the real answer is: %d" % (classifierResult, classNumStr))
    # 如果测试出来的值和原值不相等,errorCount+1
    if (classifierResult != classNumStr):
      errorCount += 1.0
  print("\nthe total number of tests is: %d" % mTest)   #输出测试总样本数
  print ("the total number of errors is: %d" % errorCount )  #输出测试错误样本数
  print ("the total error rate is: %f" % (errorCount/float(mTest))) #输出错误率
  t2 = time.time()
  print ("Cost time: %.2fmin, %.4fs."%((t2-t1)//60,(t2-t1)%60) ) #测试耗时
 
"""
描述:
  指定handwritingTest()为主函数
"""
if __name__ == "__main__":
 handwritingTest()

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python专用方法与迭代机制实例分析
Sep 15 Python
Python用GET方法上传文件
Mar 10 Python
python实现计算倒数的方法
Jul 11 Python
彻底理解Python list切片原理
Oct 27 Python
python3连接MySQL数据库实例详解
May 24 Python
python opencv旋转图像(保持图像不被裁减)
Jul 26 Python
python opencv读mp4视频的实例
Dec 07 Python
python3.6+selenium实现操作Frame中的页面元素
Jul 16 Python
让你的Python代码实现类型提示功能
Nov 19 Python
python实现微信打飞机游戏
Mar 24 Python
Python中的wordcloud库安装问题及解决方法
May 27 Python
只需要这一行代码就能让python计算速度提高十倍
May 24 Python
Python3.5运算符操作实例详解
Apr 25 #Python
Python对象转换为json的方法步骤
Apr 25 #Python
Python+PyQt5实现美剧爬虫可视工具的方法
Apr 25 #Python
详解用python实现基本的学生管理系统(文件存储版)(python3)
Apr 25 #Python
Python基础教程之if判断,while循环,循环嵌套
Apr 25 #Python
python3通过selenium爬虫获取到dj商品的实例代码
Apr 25 #Python
NumPy 数组使用大全
Apr 25 #Python
You might like
php数组对百万数据进行排除重复数据的实现代码
2010/06/08 PHP
Eclipse中php插件安装及Xdebug配置的使用详解
2013/04/25 PHP
php对象和数组相互转换的方法
2015/05/12 PHP
Yii2使用自带的UploadedFile实现的文件上传
2016/06/20 PHP
PHP排序算法之快速排序(Quick Sort)及其优化算法详解
2018/04/21 PHP
ThinkPhP+Apache+PHPstorm整合框架流程图解
2020/11/23 PHP
jquery实现树形二级菜单实例代码
2013/11/20 Javascript
jquery的clone方法应用于textarea和select的bug修复
2014/06/26 Javascript
javascript 事件处理示例分享
2014/12/31 Javascript
同一个网页中实现多个JavaScript特效的方法
2015/02/02 Javascript
JQuery的ON()方法支持的所有事件罗列
2015/02/28 Javascript
完美实现仿QQ空间评论回复特效
2015/05/06 Javascript
jQuery ajax提交Form表单实例(附demo源码)
2016/04/06 Javascript
JavaScript自定义分页样式
2017/01/17 Javascript
jquery append与appendTo方法比较
2017/05/24 jQuery
简单的网页广告特效实例
2017/08/19 Javascript
浅析vue-router jquery和params传参(接收参数)$router $route的区别
2018/08/03 jQuery
微信小程序调用后台service教程详解
2020/11/06 Javascript
python发送伪造的arp请求
2014/01/09 Python
Numpy中矩阵matrix读取一列的方法及数组和矩阵的相互转换实例
2018/07/02 Python
opencv python 基于KNN的手写体识别的实例
2018/08/03 Python
对pandas写入读取h5文件的方法详解
2018/12/28 Python
如何实现Django Rest framework版本控制
2019/07/25 Python
对python中UDP,socket的使用详解
2019/08/22 Python
谈一谈数组拼接tf.concat()和np.concatenate()的区别
2020/02/07 Python
virtualenv介绍及简明教程
2020/06/23 Python
Python 防止死锁的方法
2020/07/29 Python
Python模块zipfile原理及使用方法详解
2020/08/04 Python
CSS3中新增的对文本和字体的设置
2020/02/03 HTML / CSS
Saks Fifth Avenue澳洲/亚太地区:萨克斯第五大道精品百货店
2019/06/09 全球购物
英国家具、照明、家居用品网上商店:Wayfair.co.uk
2020/02/13 全球购物
德国的大型美妆个护电商:Flaconi
2020/06/26 全球购物
LINUX下线程,GDI类的解释
2016/12/14 面试题
优秀教师推荐材料
2014/12/16 职场文书
出生证明范本
2015/06/15 职场文书
追悼会答谢词范文
2015/09/29 职场文书