0. 介绍

kNN,即k-Nearest Neighbor(k近邻算法), 简介可参考KNN的一些总结. 本文是《机器学习实战》一书第二章的例子, 主要利用kNN实现简单的手写文字识别.

书中使用Python实现, 本文是使用R语言. 数据集中的图片分辨率为32*32, 并且该数据已经预处理成文本文件, 即类似点阵字体, 使用1代表有文字的像素, 0表示空白.

1. kNN算法实现

算法的步骤主要有:

  1. 计算测试数据到所有训练数据的距离

  2. 对1中计算的距离排序, 选出最小k个训练数据

  3. 在2中选出的k个数据中选取出现几率最大的标签, 此即算法对测试数据的分类

排序的时候, 利用的是order方法, 取出降序排序元素的索引, 这在numpy中对应的方法是argsort.

实现代码如下:

classify0 <- function(inX, dataSet, labels, k){dataSetSize = length(dataSet[,1])#扩展测试向量inXoneMat = matrix(1, dataSetSize, 1)dataMat = oneMat %*% inX#计算距离dataMat = dataMat - dataSetsqDiffMat = dataMat ** 2sqDistances = rowSums(sqDiffMat)distances = sqDistances ** 0.5#选择距离最小的k个点#按第一列升序排列获取序号sortedDistIndicies = order(distances)voteLabelsCount = rep(0, length(labels))for(i in 1:k){#获取第k小距离数据的标签label = labels[sortedDistIndicies[i]]index = which(labels == label)voteLabelsCount[index[1]] = voteLabelsCount[index[1]] + 1}sortedVoteLabelsCount = order(-voteLabelsCount)return(labels[sortedVoteLabelsCount[1]])
}

2. 准备数据

本次实践准备的数据在两个文件目录中,

  • trainingDigits -- 包含2000个例子, 每个数字大概200个.

  • testDigits -- 包含大约900个例子.

trainingDigits中的数据将用于训练分类器, testDigits中的数据将用于测试分类器的效果.

由于原始数据是32*32的矩阵, 现在需要将其转化为1*1024的向量. 程序如下:

img2vector <- function(filename){returnVect = matrix(0,1,1024)con = file(filename, "r")for(i in 0:31){line = readLines(con,n=1)for(j in 1:32){returnVect[1,(32*i+j)] = as.numeric(substr(line,j,j))}}close(con)return(returnVect)
}

3. 测试算法

主要的任务是从数据文件中提取所有的用例, 然后调用上面所述的classify0img2vector函数实现识别工作, 并计算错误率以供参考.

图像文本文件的命名格式为"a_b.txt", a表示当前文件的数字, b表示这是该数字的第b个例子. R对于文本的处理是比较弱的, 不过对于这点内容还是能应付, 使用了一点正则替换搞定.

处理完数据调用核心的classify0函数即可. 具体代码如下:

hardwritingTest <- function(){print("the test start.")print("read trainingDigits.")trainingFileList = Sys.glob("trainingDigits/*.txt")m = length(trainingFileList)hwLabels = rep(0, m)trainingMat = matrix(0,m,1024)for(i in 1:m){fileNameStr = trainingFileList[i]#提取数字fileStr = sub("trainingDigits/", "", fileNameStr)fileStr = sub("_[0-9]+.txt", "", fileStr)classNumStr = as.numeric(fileStr)hwLabels[i] = classNumStrtrainingMat[i,] = img2vector(trainingFileList[i])}print("read testDigits.")testFileList = Sys.glob("testDigits/*.txt")errorCount = 0.0mTest = length(testFileList)for(i in 1:mTest){fileNameStr = testFileList[i]fileStr = sub("testDigits/", "", fileNameStr)fileStr = sub("_[0-9]+.txt", "", fileStr)classNumStr = as.numeric(fileStr)vectorUnderTest = img2vector(testFileList[i])print(paste0("classify the ", i, "th testDigit."))classifierResult = classify0(vectorUnderTest, trainingMat, hwLabels, 3)print(paste0("--the classifier came back with: ", classifierResult, ", the real answer is: ", classNumStr))if(classifierResult != classNumStr){errorCount = errorCount + 1.0}}print(paste0("the total number of errors is: ", errorCount))print(paste0("the total error rate is: ", (errorCount / mTest)))
}

4. 小结

kNN算法的分类思路是很简单的, 实现起来也很方便. 在对数据集测试的时候, 错误率在1.27%, 这个结果还是比较不错的.

不足之处是这种即时训练消耗了过多的时间和空间, 时间主要消耗在读取文件建立数据集和计算距离的时候. 在实际过程中, 前者可以缓存数据, 达到一次读取多次使用; 后者便很难优化了, 这其中涉及到了高阶矩阵的运算, 开销较大. 因此该算法在大规模数据时不宜采用.

使用kNN算法实现简单的手写文字识别相关推荐

  1. 机器学习之KNN结合微信机器人实现手写数字识别终极API

    机器学习之KNN结合微信机器人实现手写数字识别终极API 手写数字识别 功能概述 实现步骤 结果展示 改进之处和TIPS 手写数字识别 功能概述 微信机器人接收到的手写数字图片,传送给已经经过机器学习 ...

  2. TensorFlow笔记(3)——利用TensorFlow和MNIST数据集训练一个最简单的手写数字识别模型...

    前言 当我们开始学习编程的时候,第一件事往往是学习打印"Hello World".就好比编程入门有Hello World,机器学习入门有MNIST. MNIST是一个入门级的计算机 ...

  3. 手写文字识别的使用软件

    手写文字怎么进行识别,手写文字识别用什么软件比较简单?想要将大家手中的手写文字识别有一种比较简单的方法,我们可以使用迅捷PDF在线转换器来操作,下面就是小编为大家介绍的转换过程. 步骤一:先将自己的手 ...

  4. 百度AI攻略:手写文字识别

    1.功能描述: 支持对图片中的手写中文.手写数字进行检测和识别,针对不规则的手写字体进行专项优化,识别准确率可达90%以上 2.平台接入 具体接入方式比较简单,可以参考我的另一个帖子,这里就不重复了: ...

  5. 不知道怎么识别手写文字?快来看这些手写文字识别成文档软件

    平时在上课的时候,我们经常需要通过记笔记的方式将老师讲的课堂知识点记录下来,方便课后复习巩固.而有些勤奋的小伙伴为了能够时时刻刻进行复习,还会将纸质笔记整理成电子版便于日常查看.其实他们正是通过一些识 ...

  6. 手写文字识别软件有哪些?教你怎么识别手写文字

    我们有时会遇到需要将笔记本上记录的信息内容登记到电脑上,整理成电子版文件的情况.这种时候你们是一字一句手动输入呢?还是用识别工具来帮忙呢?那还用说嘛?当然是用工具来,自己挨个整理不仅费劲还耗时间.要是 ...

  7. 接入百度大脑手写文字识别为企业降本增效

    作者:https://ai.baidu.com/forum/topic/show/945112 一.需求描述: 信息智能化时代,大部分中小企业都用上了ERP等办公软件,数字化纸质内容,软件化管理数据, ...

  8. 手写文字识别为何这么难?怎么应对?

    手写文字识别是一项极具挑战性的任务,它之所以比识别印刷体文字难,笔者认为,主要原因在于以下几个方面: 首先,手写文字样式的多样性是识别难度的主要来源.我们知道,签名具有法律效力,为什么呢?因为它具有唯 ...

  9. 手写文字识别软件哪个好?安利这三款

    随着人工智能技术的不断发展,手写文字识别技术也被广泛应用于各个领域.手写文字识别软件可以帮助人们快速输入和编辑手写文字,提高文字处理效率和准确性.例如,在智能阅卷方面,手写文字识别软件可以帮助老师们快 ...

最新文章

  1. js学习总结----获取数组最大值
  2. 织梦gbk转utf8(数据库篇)
  3. Orchard详解--第一篇 介绍
  4. mysql 与gemfire的同步_(转)分布式缓存GemFire架构介绍
  5. 美国已批准马斯克的SpaceX发射1.2万颗卫星 以打造一个天基互联网
  6. 操作系统之进程管理:7、进程同步、进程互斥
  7. “Python小屋”编程比赛参赛与领奖方式
  8. (最简单的)在VS中调用存储过程
  9. 《HelloGitHub》第 52 期
  10. 2010版gmp 计算机系统,2010版GMP附录:计算机化系统 整体及条款解读
  11. 全卷积 FCN 数据标签制作
  12. HDFS优缺点及解决方案
  13. RTL8188CUS驱动程序编译步骤
  14. 2022年全球市场高空作业平台总体规模、主要生产商、主要地区、产品和应用细分研究报告
  15. 计算机设备选型的基本原则,信息系统设备选型原则.doc
  16. deepin系统中.txt文件图标显示内容问题_深度操作系统 deepin V20(UOS)的10大优化操作
  17. C# 图片与byte[]转换
  18. Flutter自定义Widget实例 -如何创建炫酷粒子时钟效果!
  19. linux配置4g网络命令_【树莓派】树莓派移动网络连接(配置4G网卡)
  20. 厦大C语言上机 2020年期末上机考试 校验ISBN

热门文章

  1. Base64编码详解及其变种(解决加号在URL变空格问题)
  2. 打开 VMware Workstation 14 Pro 中的虚拟机出现 “此主机支持 Intel VT-x,但 Intel VT-x 处于禁用状态” 解决方法
  3. html2canvas+jspdf 完美解决html导出且分页 解决图片显示不全问题
  4. Python:检查‘Dictionary‘是否为空似乎不起作用
  5. 即使对象属性显示在控制台日志中,也无法访问
  6. Android基础知识:在UI线程中运行代码
  7. 在java.time.LocalDateTime和java.util.Date之间进行转换
  8. mysql_fetch_array()/ mysql_fetch_assoc()/ mysql_fetch_row()/ mysql_num_rows等…期望参数1为资源或结果
  9. win11鼠标指针如何设置 Windows11鼠标指针的设置方法
  10. ros之service通讯