侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

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

Python  /  管理员 发布于 7年前   135

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 npimport operator as optdef 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()

输出结果为:

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实现kNN算法的代码
    下一条:
    python爬虫 爬取超清壁纸代码实例
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 在python语言中Flask框架的学习及简单功能示例(0个评论)
    • 在Python语言中实现GUI全屏倒计时代码示例(0个评论)
    • Python + zipfile库实现zip文件解压自动化脚本示例(0个评论)
    • python爬虫BeautifulSoup快速抓取网站图片(1个评论)
    • vscode 配置 python3开发环境的方法(0个评论)
    • 近期文章
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 在go + gin中gorm实现指定搜索/区间搜索分页列表功能接口实例(0个评论)
    • 在go语言中实现IP/CIDR的ip和netmask互转及IP段形式互转及ip是否存在IP/CIDR(0个评论)
    • PHP 8.4 Alpha 1现已发布!(0个评论)
    • Laravel 11.15版本发布 - Eloquent Builder中添加的泛型(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2018-04
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2022-01
    • 2023-07
    • 2023-10
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客