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 中__name__ = '__main__' 的作用
Jul 05 Python
Python算法之栈(stack)的实现
Aug 18 Python
深入Python解释器理解Python中的字节码
Apr 01 Python
Python for Informatics 第11章 正则表达式(一)
Apr 21 Python
Python socket实现简单聊天室
Apr 01 Python
设置python3为默认python的方法
Oct 31 Python
Python实现多线程/多进程的TCP服务器
Sep 03 Python
将python包发布到PyPI和制作whl文件方式
Dec 25 Python
安装pyecharts1.8.0版本后导入pyecharts模块绘图时报错: “所有图表类型将在 v1.9.0 版本开始强制使用 ChartItem 进行数据项配置 ”的解决方法
Aug 18 Python
python 8种必备的gui库
Aug 27 Python
python自动化办公操作PPT的实现
Feb 05 Python
python 爬取华为应用市场评论
May 29 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
PHP聊天室技术
2006/10/09 PHP
php二维数组用键名分组相加实例函数
2013/11/06 PHP
php使用cookie保存用户登录的用户名实例
2015/01/26 PHP
PHP使用 Pear 进行安装和卸载包的方法详解
2019/07/08 PHP
TP5框架实现一次选择多张图片并预览的方法示例
2020/04/04 PHP
JavaScript去掉数组中的重复元素
2011/01/13 Javascript
JS中Iframe之间传值及子页面与父页面应用
2013/03/11 Javascript
jquery弹出框的用法示例(一)
2013/08/26 Javascript
div浮层,滚动条移动,位置保持不变的4种方法汇总
2013/12/11 Javascript
jquery自定义下拉列表示例
2014/04/25 Javascript
JS实现鼠标滑过显示边框的菜单效果
2016/09/21 Javascript
hovertree插件实现二级树形菜单(简单实用)
2016/12/28 Javascript
jQuery实现腾讯信用界面(自制刻度尺)样式
2017/08/15 jQuery
JavaScript对象的浅拷贝与深拷贝实例分析
2018/07/25 Javascript
css配合JavaScript实现tab标签切换效果
2018/10/11 Javascript
JavaScript数据结构之栈实例用法
2019/01/18 Javascript
layui动态表头的实现代码
2019/08/22 Javascript
解决layUI的页面显示不全的问题
2019/09/20 Javascript
javascript操作向表格中动态加载数据
2020/08/27 Javascript
[20:46]Ti4循环赛第三日VG vs DK
2014/07/12 DOTA
在Python中进行自动化单元测试的教程
2015/04/15 Python
python脚本实现xls(xlsx)转成csv
2016/04/10 Python
使用Django Form解决表单数据无法动态刷新的两种方法
2017/07/14 Python
python3连接MySQL数据库实例详解
2018/05/24 Python
Django之PopUp的具体实现方法
2019/08/31 Python
Python基础进阶之海量表情包多线程爬虫功能的实现
2020/12/17 Python
为2021年的第一场雪锦上添花:用matplotlib绘制雪花和雪景
2021/01/05 Python
css3教程之倾斜页面
2014/01/27 HTML / CSS
CSS去掉A标签(链接)虚线框的方法
2014/04/01 HTML / CSS
毕业生自我鉴定实例
2014/01/21 职场文书
电子专业毕业生自我鉴定
2014/01/22 职场文书
开会迟到检讨书
2014/02/03 职场文书
幼儿园毕业寄语
2014/04/03 职场文书
销售团队激励口号
2014/06/06 职场文书
陈胜吴广起义口号
2014/06/20 职场文书
2015年小学数学教研组工作总结
2015/05/21 职场文书