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 相关文章推荐
Python3实现的腾讯微博自动发帖小工具
Nov 11 Python
python的迭代器与生成器实例详解
Jul 16 Python
使用Python编写一个简单的tic-tac-toe游戏的教程
Apr 16 Python
Python使用asyncio包处理并发详解
Sep 09 Python
Python字典的核心底层原理讲解
Jan 24 Python
pyqt5 实现多窗口跳转的方法
Jun 19 Python
Django学习之文件上传与下载
Oct 06 Python
python实现将视频按帧读取到自定义目录
Dec 10 Python
pycharm通过anaconda安装pyqt5的教程
Mar 24 Python
Python selenium键盘鼠标事件实现过程详解
Jul 28 Python
python glom模块的使用简介
Apr 13 Python
Python中文分词库jieba(结巴分词)详细使用介绍
Apr 07 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
我的论坛源代码(十)
2006/10/09 PHP
解析PHP中ob_start()函数的用法
2013/06/24 PHP
PHP的preg_match匹配字符串长度问题解决方法
2014/05/03 PHP
Yii数据读取与跳转参数传递用法实例分析
2016/07/12 PHP
PHP中使用jQuery+Ajax实现分页查询多功能操作(示例讲解)
2017/09/17 PHP
jquery实现文本框鼠标右击无效以及不能输入的代码
2010/11/05 Javascript
js history对象简单实现返回和前进
2013/10/30 Javascript
jQuery实现新消息闪烁标题提示的方法
2015/03/11 Javascript
举例详解AngularJS中ngShow和ngHide的使用方法
2015/06/19 Javascript
js实现页面a向页面b传参的方法
2016/05/29 Javascript
js 实现数值的千分位及保存小数方法(推荐)
2016/08/01 Javascript
输入框点击时边框变色效果的实现方法
2016/12/26 Javascript
详解ElementUI之表单验证、数据绑定、路由跳转
2017/06/21 Javascript
JS基于正则表达式实现的密码强度验证功能示例
2017/09/21 Javascript
详解webpack自定义loader初探
2018/08/29 Javascript
解决angularJS中input标签的ng-change事件无效问题
2018/09/13 Javascript
vue轻量级框架无法获取到vue对象解决方法
2019/05/12 Javascript
vue iview的菜单组件Mune 点击不高亮的解决方案
2019/11/01 Javascript
微信公众号H5之微信分享常见错误和问题(小结)
2019/11/14 Javascript
python 解析XML python模块xml.dom解析xml实例代码
2014/02/07 Python
最基础的Python的socket编程入门教程
2015/04/23 Python
Python中subprocess的简单使用示例
2015/07/28 Python
win10系统中安装scrapy-1.1
2016/07/03 Python
python实现批量修改文件名代码
2017/09/10 Python
基于Python数据可视化利器Matplotlib,绘图入门篇,Pyplot详解
2017/10/13 Python
Python+OpenCV让电脑帮你玩微信跳一跳
2018/01/04 Python
关于python中密码加盐的学习体会小结
2019/07/15 Python
使用python写一个自动浏览文章的脚本实例
2019/12/05 Python
Python 实现自动登录+点击+滑动验证功能
2020/06/10 Python
python 怎样进行内存管理
2020/11/10 Python
size?丹麦官网:英国伦敦的球鞋精品店
2019/04/15 全球购物
什么是Linux虚拟文件系统VFS
2012/01/31 面试题
公司中层干部的自我评价分享
2014/03/01 职场文书
优秀学生干部先进事迹材料
2014/05/26 职场文书
农行心得体会
2014/09/02 职场文书
公司酒会致辞
2015/07/30 职场文书