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安装mysql-python简明笔记(ubuntu环境)
Jun 25 Python
Ubuntu16.04/树莓派Python3+opencv配置教程(分享)
Apr 02 Python
Python paramiko模块的使用示例
Apr 11 Python
python多线程调用exit无法退出的解决方法
Feb 18 Python
Flask框架工厂函数用法实例分析
May 25 Python
python解释器spython使用及原理解析
Aug 24 Python
Python视频编辑库MoviePy的使用
Apr 01 Python
python实现文字版扫雷
Apr 24 Python
Python enumerate() 函数如何实现索引功能
Jun 29 Python
解决Pyinstaller打包软件失败的一个坑
Mar 04 Python
使用Django框架创建项目
Jun 10 Python
Django框架模板用法详解
Jun 10 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
咖啡机如何保养和日常清洁?
2021/03/03 冲泡冲煮
PHP函数学习之PHP函数点评
2012/07/05 PHP
25个优雅的jQuery Tooltip插件推荐
2011/05/25 Javascript
用示例说明filter()与find()的用法以及children()与find()的区别分析
2013/04/26 Javascript
JavaScript省市联动实现代码
2014/02/15 Javascript
jQuery菜单插件superfish使用指南
2015/04/21 Javascript
JavaScript实现图片DIV竖向滑动的方法
2015/04/25 Javascript
Angular.JS通过指令操作DOM的方法
2017/05/10 Javascript
利用forever和pm2部署node.js项目过程
2017/05/10 Javascript
Vue.js在数组中插入重复数据的实现代码
2017/11/17 Javascript
详解vue-cli之webpack3构建全面提速优化
2017/12/25 Javascript
vue.js 实现点击按钮动态添加li的方法
2018/09/07 Javascript
利用hasOwnProperty给数组去重的面试题分享
2018/11/05 Javascript
jquery+css3实现的经典弹出层效果示例
2020/05/16 jQuery
vue3中轻松实现switch功能组件的全过程
2021/01/07 Vue.js
python生成随机图形验证码详解
2017/11/08 Python
浅析Windows 嵌入python解释器的过程
2019/07/26 Python
python 实现多线程下载m3u8格式视频并使用fmmpeg合并
2019/11/15 Python
Python3.7安装PyQt5 运行配置Pycharm的详细教程
2020/10/15 Python
细说CSS3中box属性中的overflow-x属性和overflow-y属性值的效果
2014/07/21 HTML / CSS
CSS3使用transition属性实现过渡效果
2018/04/18 HTML / CSS
深入浅析CSS3中的Flex布局整理
2020/04/27 HTML / CSS
乐天旅游台湾网站:Rakuten Travel TW
2017/06/01 全球购物
Dillard’s百货官网:Dillards.com
2018/05/26 全球购物
建筑公司文秘岗位职责
2013/11/29 职场文书
客服部工作职责范本
2014/02/14 职场文书
化学系大学生自荐信范文
2014/03/01 职场文书
优乐美广告词
2014/03/14 职场文书
学习雷锋活动总结
2014/04/29 职场文书
县政府领导班子“四风”方面突出问题整改措施
2014/09/23 职场文书
办公室主任个人对照检查材料思想汇报
2014/10/11 职场文书
2014年残疾人工作总结
2014/12/06 职场文书
大学生考试作弊被抓检讨书
2014/12/27 职场文书
博物馆观后感
2015/06/05 职场文书
承诺书的内容有哪些,怎么写?
2019/06/21 职场文书
python脚本框架webpy模板赋值实现
2021/11/20 Python