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 创建子进程模块subprocess详解
Apr 08 Python
Python获取运行目录与当前脚本目录的方法
Jun 01 Python
Python字符串切片操作知识详解
Mar 28 Python
快速排序的算法思想及Python版快速排序的实现示例
Jul 02 Python
python+opencv实现动态物体追踪
Jan 09 Python
对python内置map和six.moves.map的区别详解
Dec 19 Python
python开发之anaconda以及win7下安装gensim的方法
Jul 05 Python
python 命令行传入参数实现解析
Aug 30 Python
python boto和boto3操作bucket的示例
Oct 30 Python
Python爬虫Scrapy框架CrawlSpider原理及使用案例
Nov 20 Python
Scrapy实现模拟登录的示例代码
Feb 21 Python
基于Python实现流星雨效果的绘制
Mar 18 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集成百度Ueditor 1.4.3
2014/11/23 PHP
详解WordPress开发中wp_title()函数的用法
2016/01/07 PHP
javascript 选择文件夹对话框(web)
2009/07/07 Javascript
jQuery AJAX实现调用页面后台方法和web服务定义的方法分享
2012/03/01 Javascript
jquery ajax的success回调函数中实现按钮置灰倒计时
2013/11/19 Javascript
跟我学Nodejs(二)--- Node.js事件模块
2014/05/21 NodeJs
js的flv视频播放器插件使用方法
2015/06/23 Javascript
基于Jquery实现仿百度百科右侧导航代码附源码下载
2015/11/27 Javascript
jQuery ajaxForm()的应用
2016/10/14 Javascript
jQuery+CSS3实现点赞功能
2017/03/13 Javascript
vuex 使用文档小结篇
2018/01/11 Javascript
基于Vuex无法观察到值变化的解决方法
2018/03/01 Javascript
vue插件开发之使用pdf.js实现手机端在线预览pdf文档的方法
2018/07/12 Javascript
基于vue实现移动端圆形旋钮插件效果
2018/11/28 Javascript
JS+canvas五子棋人机对战实现步骤详解
2020/06/04 Javascript
[42:20]Winstrike vs VGJ.S 2018国际邀请赛淘汰赛BO3 第二场 8.23
2018/08/24 DOTA
python在指定目录下查找gif文件的方法
2015/05/04 Python
python实现的多线程端口扫描功能示例
2017/01/21 Python
PyQt5每天必学之弹出消息框
2018/04/19 Python
python处理document文档保留原样式
2019/09/23 Python
如何在django中实现分页功能
2020/04/22 Python
用 Python 制作地球仪的方法
2020/04/24 Python
深入理解Python 多线程
2020/06/16 Python
Python中openpyxl实现vlookup函数的实例
2020/10/28 Python
全面解析HTML5中的标准属性与自定义属性
2016/02/18 HTML / CSS
Canvas多边形绘制的实现方法
2019/08/05 HTML / CSS
玩具反斗城美国官网:Toys"R"Us
2016/09/17 全球购物
阿波罗盒子:Apollo Box
2017/08/14 全球购物
日本最大的药妆连锁店:Matsukiyo松本清药妆店
2017/11/23 全球购物
施华洛世奇意大利官网:SWAROVSKI意大利
2018/07/23 全球购物
建筑公司文秘岗位职责
2013/11/29 职场文书
20年同学聚会邀请函
2014/02/04 职场文书
机关搬迁方案
2014/05/18 职场文书
月度优秀员工获奖感言
2014/08/16 职场文书
教师业务学习材料
2014/12/16 职场文书
会议简讯范文
2015/07/20 职场文书