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中文分词实现方法(安装pymmseg)
Jun 14 Python
Python爬取三国演义的实现方法
Sep 12 Python
Python学习小技巧之列表项的拼接
May 20 Python
基于hashlib模块--加密(详解)
Jun 21 Python
Python复制Word内容并使用格式设字体与大小实例代码
Jan 22 Python
python Django的web开发实例(入门)
Jul 31 Python
python+jinja2实现接口数据批量生成工具
Aug 28 Python
浅析PEP570新语法: 只接受位置参数
Oct 15 Python
关于多元线性回归分析——Python&SPSS
Feb 24 Python
django-orm F对象的使用 按照两个字段的和,乘积排序实例
May 18 Python
Pytorch上下采样函数--interpolate用法
Jul 07 Python
Python中json.dumps()函数的使用解析
May 17 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
CI框架出现mysql数据库连接资源无法释放的解决方法
2016/05/17 PHP
Thinkphp3.2.3分页使用实例解析
2016/07/28 PHP
PHP实现简单的计算器
2020/08/28 PHP
在IE模态窗口中自由查看HTML源码的方法
2007/03/08 Javascript
用js实现手把手教你月入万刀(转贴)
2007/11/07 Javascript
css图片自适应大小
2007/11/28 Javascript
javascript 命名规则 变量命名规则
2010/02/25 Javascript
最佳JS代码编写的14条技巧
2011/01/09 Javascript
jquery获得option的值和对option进行操作
2013/12/13 Javascript
jquery等待效果示例
2014/05/01 Javascript
jQuery不使用插件及swf实现无刷新文件上传
2014/12/08 Javascript
pace.js页面加载进度条插件
2015/09/29 Javascript
最实用的jQuery分页插件
2016/10/09 Javascript
深入理解bootstrap框架之入门准备
2016/10/09 Javascript
深入理解vue.js双向绑定的实现原理
2016/12/05 Javascript
JavaScript实现元素滚动条到达一定位置循环追加内容
2017/12/28 Javascript
Node.js实现一个HTTP服务器的方法示例
2019/05/13 Javascript
Vue组件跨层级获取组件操作
2020/07/27 Javascript
python调用机器喇叭发出蜂鸣声(Beep)的方法
2015/03/23 Python
用Python代码来绘制彭罗斯点阵的教程
2015/04/03 Python
python中尾递归用法实例详解
2015/04/28 Python
Python实现带百分比的进度条
2016/06/28 Python
django之跨表查询及添加记录的示例代码
2018/10/16 Python
Python并发:多线程与多进程的详解
2019/01/24 Python
Python的历史与优缺点整理
2020/05/26 Python
ETO男装官方网店:ETO Jeans
2019/02/28 全球购物
2014年十一国庆向国旗敬礼寄语
2014/04/11 职场文书
中学生关于梦想的演讲稿
2014/08/22 职场文书
乡镇2014法制宣传日活动总结
2014/11/01 职场文书
英语感谢信范文
2015/01/20 职场文书
商务英语求职信范文
2015/03/19 职场文书
答辩状格式范本
2015/05/22 职场文书
军事博物馆观后感
2015/06/05 职场文书
推荐六本经典文学奖书籍:此生必读
2019/08/22 职场文书
基于Python和openCV实现图像的全景拼接详细步骤
2021/10/05 Python
详解Redis的三种常用的缓存读写策略步骤
2022/05/06 Redis