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的线程来解决生产者消费问题的示例
Apr 02 Python
python生成词云的实现方法(推荐)
Jun 13 Python
python使用fcntl模块实现程序加锁功能示例
Jun 23 Python
python3操作mysql数据库的方法
Jun 23 Python
Python tkinter模块中类继承的三种方式分析
Aug 08 Python
对python中的for循环和range内置函数详解
Apr 17 Python
编写多线程Python服务器 最适合基础
Sep 14 Python
详解django自定义中间件处理
Nov 21 Python
python xpath获取页面注释的方法
Jan 14 Python
对Python的多进程锁的使用方法详解
Feb 18 Python
django框架CSRF防护原理与用法分析
Jul 22 Python
Python:合并两个numpy矩阵的实现
Dec 02 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函数file_get_contents超时处理的方法详解
2013/06/03 PHP
sql注入与转义的php函数代码
2013/06/17 PHP
php模拟ping命令(php exec函数的使用方法)
2013/10/25 PHP
yii2高级应用之自定义组件实现全局使用图片上传功能的方法
2016/10/08 PHP
php 一维数组的循环遍历实现代码
2017/04/10 PHP
输入自动提示搜索提示功能的使用说明:sugggestion.txt
2013/09/02 Javascript
解决jquery插件冲突的问题
2014/01/23 Javascript
jquery ui bootstrap 实现自定义风格
2014/11/14 Javascript
JS实现同时搜索百度和必应的方法
2015/01/27 Javascript
Bootstrap缩略图与警告框学习使用
2017/02/08 Javascript
TableSort.js表格排序插件使用方法详解
2017/02/10 Javascript
bootstrap自定义样式之bootstrap实现侧边导航栏功能
2018/09/10 Javascript
在webstorm开发微信小程序之使用阿里自定义字体图标的方法
2018/11/15 Javascript
vue引入微信sdk 实现分享朋友圈获取地理位置功能
2019/07/04 Javascript
JS实现滑动导航效果
2020/01/14 Javascript
vue设置全局访问接口API地址操作
2020/08/14 Javascript
[07:49]2014DOTA2国际邀请赛 Newbee夺冠后采访xiao8坦言奖金会上交
2014/07/23 DOTA
Python基础之函数用法实例详解
2014/09/10 Python
在Python的Django框架中编写错误提示页面
2015/07/22 Python
解决Matplotlib图表不能在Pycharm中显示的问题
2018/05/24 Python
Python3中编码与解码之Unicode与bytes的讲解
2019/02/28 Python
Django中自定义查询对象的具体使用
2019/10/13 Python
Python帮你识破双11的套路
2019/11/11 Python
Python中six模块基础用法
2019/12/08 Python
Python基于jieba, wordcloud库生成中文词云
2020/05/13 Python
Ajax主要包含了哪些技术
2014/06/12 面试题
银行个人求职自荐信范文
2013/12/16 职场文书
大四自我鉴定
2014/02/08 职场文书
党的群众路线教育实践活动对照检查材料
2014/09/22 职场文书
2014年关工委工作总结
2014/11/17 职场文书
世界遗产导游词
2015/02/13 职场文书
幼儿园中班个人总结
2015/02/28 职场文书
2015年客服工作总结范文
2015/04/02 职场文书
个人道歉信大全
2019/04/11 职场文书
微信小程序中wxs文件的一些妙用分享
2022/02/18 Javascript