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中分数的相关使用教程
Mar 30 Python
Python自动化部署工具Fabric的简单上手指南
Apr 19 Python
python实现简单淘宝秒杀功能
May 03 Python
python实现两张图片的像素融合
Feb 23 Python
Pycharm生成可执行文件.exe的实现方法
Jun 02 Python
python模块如何查看
Jun 16 Python
Numpy 多维数据数组的实现
Jun 18 Python
Python 没有main函数的原因
Jul 10 Python
python 爬虫基本使用——统计杭电oj题目正确率并排序
Oct 26 Python
python如何获得list或numpy数组中最大元素对应的索引
Nov 16 Python
利用Python+OpenCV三步去除水印
May 28 Python
Python OpenCV 彩色与灰度图像的转换实现
Jun 05 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
WIN98下Apache1.3.14+PHP4.0.4的安装
2006/10/09 PHP
php网站来路获取代码(针对搜索引擎)
2010/06/08 PHP
一个简洁实用的PHP缓存类完整实例
2014/07/26 PHP
教你如何开启shopnc b2b2c 伪静态
2014/10/21 PHP
PHP将字符分解为多个字符串的方法
2014/11/22 PHP
typecho插件编写教程(六):调用接口
2015/05/28 PHP
php开发微信支付获取用户地址
2015/10/04 PHP
php中static 静态变量和普通变量的区别
2016/12/01 PHP
PHP正则匹配反斜杠'\'和美元'$'的方法
2017/02/08 PHP
利用Laravel事件系统如何实现登录日志的记录详解
2017/05/20 PHP
php防止表单重复提交实例讲解
2019/02/11 PHP
JQuery文本改变触发事件如聚焦事件、失焦事件
2014/01/15 Javascript
JQuery获取表格数据示例代码
2014/05/26 Javascript
$.each遍历对象、数组的属性值并进行处理
2014/07/18 Javascript
jQuery实现复选框批量选择与反选的方法
2015/06/17 Javascript
获取阴历(农历)和当前日期的js代码
2016/02/15 Javascript
JavaScript中的事件委托及好处
2016/07/12 Javascript
js时间查询插件使用详解
2017/04/07 Javascript
JavaScript切换搜索引擎的导航网页搜索框实例代码
2017/06/11 Javascript
React Native开发封装Toast与加载Loading组件示例
2018/09/08 Javascript
react实现移动端下拉菜单的示例代码
2020/01/16 Javascript
JavaScript enum枚举类型定义及使用方法
2020/05/15 Javascript
JS使用setInterval计时器实现挑战10秒
2020/11/08 Javascript
使用相同的Apache实例来运行Django和Media文件
2015/07/22 Python
Python实现二维有序数组查找的方法
2016/04/27 Python
python按综合、销量排序抓取100页的淘宝商品列表信息
2018/02/24 Python
python隐藏终端执行cmd命令的方法
2019/06/24 Python
Python实现变声器功能(萝莉音御姐音)
2019/12/05 Python
基于numpy中的expand_dims函数用法
2019/12/18 Python
python修改微信和支付宝步数的示例代码
2020/10/12 Python
python如何控制进程或者线程的个数
2020/10/16 Python
新秀丽官方旗舰店:Samsonite拉杆箱、双肩包、皮具
2018/03/05 全球购物
Radley英国官网:英国莱德利小狗包
2019/03/21 全球购物
电子商务专业自我鉴定
2013/12/18 职场文书
孔子观后感
2015/06/08 职场文书
2016年度农村党员干部主题教育活动总结
2016/04/06 职场文书