python实现kNN算法识别手写体数字的示例代码


Posted in Python onAugust 16, 2019

1。总体概要

kNN算法已经在上一篇博客中说明。对于要处理手写体数字,需要处理的点主要包括:

(1)图片的预处理:将png,jpg等格式的图片转换成文本数据,本博客的思想是,利用图片的rgb16进制编码(255,255,255)为白色,(0,0,0)为黑色,获取图片大小后,逐个像素进行判断分析,当此像素为空白时,在文本数据中使用0来替换,反之使用1来替换。

from PIL import Image
'''将图片转换成文档,使用0,1分别替代空白和数字'''
pic = Image.open('/Users/wangxingfan/Desktop/1.png')
path = open('/Users/wangxingfan/Desktop/1.txt','a')
width = pic.size[0]
height = pic.size[1]
for i in range(0,width):
 for j in range(0,height):
  c_RGB = pic.getpixel((i,j))#获取该像素所对应的RGB值
  if c_RGB[0]+c_RGB[1]+c_RGB[2]>0:#白色
   path.write('0')
  elif c_RGB[0]+c_RGB[1]+c_RGB[2]==0:#黑色
   path.write('1')
  else:
   pass
 path.write('\n')
path.close()

(2)训练集的构建。首先想到的是将(1)中图片处理后的文本数据构建成list形式,所以训练集将是二维数组,形如[[1,0,1,1,0,,,,,0,1],[0,1,1,1,10,,,,],[0,0,1,0,,,],,,,,]所以我们构建函数处理训练集数据。

2。代码

简单的总结这个算法,就是将测试数据向量化,逐个和同样向量化的训练数据进行kNN运算,求的最短距离出现最多的分类就是我们要的分类。建立训练集的过程就是将文件数据向量化的过程。

#!/user/bin/env python
#-*- coding:utf-8 -*-
from os import listdir#获取文件目录下所有文件
'''
from PIL import Image
#将图片转换成文档,使用0,1分别替代空白和数字
pic = Image.open('/Users/wangxingfan/Desktop/1.png')
path = open('/Users/wangxingfan/Desktop/1.txt','a')
width = pic.size[0]
height = pic.size[1]
for i in range(0,width):
 for j in range(0,height):
  c_RGB = pic.getpixel((i,j))#获取该像素所对应的RGB值
  if c_RGB[0]+c_RGB[1]+c_RGB[2]>0:#白色
   path.write('0')
  elif c_RGB[0]+c_RGB[1]+c_RGB[2]==0:#黑色
   path.write('1')
  else:
   pass
 path.write('\n')
path.close()
'''
import numpy as np
import operator as opt

def kNN(dataSet, labels, testData, k):
 '''首先明确列表不能想加减,dataSet是数组形式,而对于下面的test函数,testData只是一列,相当于列表,所以在进行加减时,需要将其转换为数组,我们使用np下的tile函数来实现'''
 testDatasize = dataSet.shape[0]#获取dataSet的总行数
 dataSet = dataSet.astype('float64')#不进行转换则报错
 testData1 = np.tile(testData,(testDatasize,1))#使用tile函数返回多个重复构成的数组
 testData1 = testData1.astype('float64')
 distSquareMat = (dataSet - testData1) ** 2 # 计算差值的平方
 distSquareSums = distSquareMat.sum(axis=1) # 求每一行的差值平方和,axis=0则按列计算
 distances = distSquareSums ** 0.5 # 开根号,得出每个样本到测试点的距离
 sortedIndices = distances.argsort() # 排序,得到排序后的下标
 indices = sortedIndices[:k] # 取最小的k个
 labelCount = {} # 存储每个label的出现次数,出现次数最多的就是我们要选择的类别
 for i in indices:
  label = labels[i]
  labelCount[label] = labelCount.get(label, 0) + 1 # 次数加一,使用字典的get方法,第一次出现时默认值是0
 sortedCount = sorted(labelCount.items(), key=opt.itemgetter(1), reverse=True) # 对label出现的次数从大到小进行排序
 return sortedCount[0][0] # 返回出现次数最大的label

#定义函数读取某个文件,返回该文件组成的数组
def file_data(fname):
 arr = []
 path = open(fname)
 for i in range(0,32):
  line = path.readline()
  for j in range(0,32):
   arr.append(line[j])
 return arr

#建立训练数据集
def train_data():
 lables = []
 file_list = listdir('/学习/视频课程/源码/第7周/testandtraindata/traindata/')
 trainarr = np.zeros((len(file_list),1024))
 for i in range(0,len(file_list)):
  file = '/学习/视频课程/源码/第7周/testandtraindata/traindata/'+file_list[i]
  lables.append(file_list[i].split('_')[0])#获取对应的文件类别
  trainarr[i,:] = file_data(file)#取所有列的第一个数据
 return trainarr,lables

#测试函数
def test():
 j = 0
 k = 0
 trainarr,lables = train_data()
 testdata_list = listdir('/学习/视频课程/源码/第7周/testandtraindata/testdata/')
 for i in range(0,len(testdata_list)):#逐个去测试
  testfile = '/学习/视频课程/源码/第7周/testandtraindata/testdata/'+testdata_list[i]
  testdata1 = file_data(testfile)
  result = kNN(trainarr,lables,testdata1,k=3)
  print(result+',real_number:'+testdata_list[i].split('_')[0])
  if result == testdata_list[i].split('_')[0]:
   j +=1
  else:
   k +=1

 print('辨识成功率:'+j/(k+j))

test()

输出结果为:

python实现kNN算法识别手写体数字的示例代码

3。几个知识点代码说明

(1)numpy.tile

p = np.array([0,0,0])
np.tile(p,(3,1))#表示columns方向重复三次,index方向不变
Out[12]: 
array([[0, 0, 0],
  [0, 0, 0],
  [0, 0, 0]])
np.tile(p,(1,3))#表示index方向重复三次,行还是一行
Out[13]: array([[0, 0, 0, 0, 0, 0, 0, 0, 0]])

(2)array[1,:]表示取所有列的第【索引1】个数据(也就是第二行数据)

a = np.array([[1,1,1],[2,2,2],[3,3,3],[4,4,4]])
a[1,:]
Out[21]: array([2, 2, 2])
a[:,1]#所有行的第二列数据
Out[22]: array([1, 2, 3, 4])

(3)list并不能进行加减计算,需要使用numpy将数据转换为数组形式,且在使用例如:arr1+arr2时,需要两个数组的维度相同,在某个纬度上的数据长度也相同。

(4)使用os模块下的listdir,可以显示所有该文件夹下的文件,以列表的形式返回。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python数据结构之二叉树的遍历实例
Apr 29 Python
跟老齐学Python之编写类之四再论继承
Oct 11 Python
Python基于pygame实现的font游戏字体(附源码)
Nov 11 Python
详解Python发送邮件实例
Jan 10 Python
opencv python 2D直方图的示例代码
Jul 20 Python
opencv python 基于KNN的手写体识别的实例
Aug 03 Python
python中import与from方法总结(推荐)
Mar 21 Python
Python中xml和dict格式转换的示例代码
Nov 07 Python
Python实现子类调用父类的初始化实例
Mar 12 Python
python新式类和经典类的区别实例分析
Mar 23 Python
Python SMTP配置参数并发送邮件
Jun 16 Python
解决tensorflow读取本地MNITS_data失败的原因
Jun 22 Python
python爬虫 爬取超清壁纸代码实例
Aug 16 #Python
Python PO设计模式的具体使用
Aug 16 #Python
python使用sessions模拟登录淘宝的方式
Aug 16 #Python
Django错误:TypeError at / 'bool' object is not callable解决
Aug 16 #Python
Python facenet进行人脸识别测试过程解析
Aug 16 #Python
Python Web框架之Django框架Model基础详解
Aug 16 #Python
pycharm配置git(图文教程)
Aug 16 #Python
You might like
UCenter Home二次开发指南
2009/05/28 PHP
叫你如何修改Nginx与PHP的文件上传大小限制
2014/09/10 PHP
作为PHP程序员你要知道的另外一种日志
2018/07/30 PHP
Javascript 八进制转义字符(8进制)
2011/04/08 Javascript
Javascript对象中关于setTimeout和setInterval的this介绍
2012/07/21 Javascript
js不能跳转到上一页面的问题解决方法
2013/03/01 Javascript
Javascript事件实例详解
2013/11/06 Javascript
Windows 系统下安装和部署Egret的开发环境
2014/07/31 Javascript
JavaScript重定向URL参数的两种方法小结
2016/10/19 Javascript
Highcharts+NodeJS搭建数据可视化平台示例
2017/01/01 NodeJs
详解node.js平台下Express的session与cookie模块包的配置
2017/04/26 Javascript
node前端模板引擎Jade之标签的基本写法
2018/05/11 Javascript
JS获取浏览器地址栏的多个参数值的任意值实例代码
2018/07/24 Javascript
Bootstrap table表格初始化表格数据的方法
2018/07/25 Javascript
详解如何理解vue的key属性
2019/04/14 Javascript
JS实现查找数组中对象的属性值是否存在示例
2019/05/24 Javascript
ES6如何用一句代码实现函数的柯里化
2020/01/18 Javascript
webpack打包优化的几个方法总结
2020/02/10 Javascript
typescript编写微信小程序创建项目的方法
2021/01/29 Javascript
Python中字典的基础知识归纳小结
2015/08/19 Python
Python实现简单http服务器
2018/04/12 Python
Python基于递归和非递归算法求两个数最大公约数、最小公倍数示例
2018/05/21 Python
Python命令行参数解析工具 docopt 安装和应用过程详解
2019/09/26 Python
Python TCPServer 多线程多客户端通信的实现
2019/12/31 Python
浅谈django不使用restframework自定义接口与使用的区别
2020/07/15 Python
python 下载文件的多种方法汇总
2020/11/17 Python
英国网上超市:Ocado
2020/03/05 全球购物
自荐信结尾
2013/10/27 职场文书
思想品德自我评价
2014/02/04 职场文书
离婚协议书范本(通用篇)
2014/11/30 职场文书
大雁塔导游词
2015/02/04 职场文书
2015年创先争优工作总结
2015/05/23 职场文书
公司2015年终工作总结
2015/05/26 职场文书
HTML速写之Emmet语法规则的实现
2021/04/07 HTML / CSS
Python内置的数据类型及使用方法
2022/04/13 Python
python开发制作好看的时钟效果
2022/05/02 Python