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 相关文章推荐
paramiko模块安装和使用(远程登录服务器)
Jan 27 Python
编写Python脚本来获取Google搜索结果的示例
May 04 Python
Python语言实现机器学习的K-近邻算法
Jun 11 Python
python实现计算倒数的方法
Jul 11 Python
在Ubuntu系统下安装使用Python的GUI工具wxPython
Feb 18 Python
使用Python对MySQL数据操作
Apr 06 Python
Python编程实现二叉树及七种遍历方法详解
Jun 02 Python
Django 开发环境配置过程详解
Jul 18 Python
详解django实现自定义manage命令的扩展
Aug 13 Python
Django 拼接两个queryset 或是两个不可以相加的对象实例
Mar 28 Python
python使用re模块爬取豆瓣Top250电影
Oct 20 Python
Django怎么在admin后台注册数据库表
Nov 14 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
PHP5 面向对象程序设计
2008/02/13 PHP
ThinkPHP文件上传实例教程
2014/08/22 PHP
php查询mysql大量数据造成内存不足的解决方法
2015/03/04 PHP
php图片上传类 附调用方法
2016/05/15 PHP
jQuery 表单验证插件formValidation实现个性化错误提示
2009/06/23 Javascript
JavaScript面向对象之静态与非静态类
2010/02/03 Javascript
jquery.boxy弹出框(后隔N秒后自动隐藏/自动跳转)
2013/01/15 Javascript
JS实现下拉框的动态添加(附效果)
2013/04/03 Javascript
JavaScript String.replace函数参数实例说明
2013/06/06 Javascript
js的.innerHTML = ""IE9下显示有错误的解决方法
2013/09/16 Javascript
jquery text()方法取标签中的文本
2014/07/25 Javascript
Bootstrap实现带动画过渡的弹出框
2016/08/09 Javascript
详解webpack+gulp实现自动构建部署
2017/06/29 Javascript
Vue按需加载的具体实现
2017/12/02 Javascript
基于模板引擎Jade的应用(详解)
2017/12/12 Javascript
vue使用v-if v-show页面闪烁,div闪现的解决方法
2018/10/12 Javascript
[05:35]DOTA2英雄梦之声_第13期_拉比克
2014/06/21 DOTA
python实现获取Ip归属地等信息
2016/08/27 Python
Python数据结构与算法之图的广度优先与深度优先搜索算法示例
2017/12/14 Python
Python使用matplotlib填充图形指定区域代码示例
2018/01/16 Python
pycharm显示远程图片的实现
2019/11/04 Python
python 读取.nii格式图像实例
2020/07/01 Python
python处理写入数据代码讲解
2020/10/22 Python
几个Shell Script面试题
2014/04/18 面试题
设计模式的基本要素是什么
2014/04/21 面试题
毕业学生推荐信
2013/12/01 职场文书
最新的咖啡店创业计划书
2013/12/30 职场文书
《都江堰》教学反思
2014/02/07 职场文书
司法局火灾防控方案
2014/06/05 职场文书
建设工地安全标语
2014/06/07 职场文书
拉歌口号大全
2014/06/13 职场文书
大学生找工作求职信
2014/07/09 职场文书
2014年稽查工作总结
2014/12/20 职场文书
2015年社区服务活动总结
2015/03/25 职场文书
PHP中strval()函数实例用法
2021/06/07 PHP
HTML5页面打开微信小程序功能实现
2022/09/23 HTML / CSS