上篇文章中提到了使用pillow对手写文字进行预处理,本文介绍如何使用kNN算法对文字进行识别。

基本概念

  k最邻近算法(k-Nearest Neighbor, KNN),是机器学习分类算法中最简单的一类。假设一个样本空间被分为几类,然后给定一个待分类的特征数据,通过计算距离该数据的最近的k个样本来判断这个数据属于哪一类。如果距离待分类属性最近的k个类大多数都属于某一个特定的类,那么这个待分类的数据也就属于这个类。所谓K最近邻,就是k个最近的邻居的意思,说的是每个样本都可以用它最接近的k个邻居来代表。kNN在确定分类决策上只依据最邻近的一个或者几个样本的类别来决定待分样本所属的类别,在决策时,只与极少量的相邻样本有关。通常,k是不大于20的整数。

  下图所示,绿色圆要被决定赋予哪个类,是红色三角形还是蓝色四方形?如果K=3,由于红色三角形所占比例为2/3,绿色圆将被赋予红色三角形那个类,如果K=5,由于蓝色四方形比例为3/5,因此绿色圆被赋予蓝色四方形类。

  在理想情况下,k值选择1,即只选择最近的邻居。在现实生活中往往没这么理想,比如对于价格来说,有些顾客消息闭塞,可能会为 “最近的邻居”多付很多钱,所以应当货比三家,多选择一些邻居,取均值来减少噪声。实际上,k值过大或过小都将影响结果。

计算过程

过程如下:

  1. 计算训练集中的点与当前点之间的距离;
  2. 按距离降序排序;
  3. 选取与当前点距离最小的k个点;
  4. 如果是数值型数据,计算前k个点的均值;如果是离散数据,计算前k个点所在类别出现的频率;
  5. 如果是数值型数据,返回前k个点的均值作为预测数值;如果是离散数据,返回前k个点出现频率最高的类别作为预测分类。

  代码如下:

 from os import  listdir

 #将图片文件转换为向量
def img2vector(filename):
with open(filename) as fobj:
arr = fobj.readlines() vec, demension = [], len(arr)
for i in range(demension):
line = arr[i].strip()
for j in range(demension):
vec.append(int(line[j])) return vec #读取训练数据
def createDataset(dir):
dataset, labels = [], []
files = listdir(dir)
for filename in files:
label = int(filename[0])
labels.append(label)
dataset.append(img2vector(dir + '/' + filename)) return dataset, labels #计算谷本系数
def tanimoto(vec1, vec2):
c1, c2, c3 = 0, 0, 0
for i in range(len(vec1)):
if vec1[i] == 1: c1 += 1
if vec2[i] == 1: c2 += 1
if vec1[i] == 1 and vec2[i] == 1: c3 += 1 return c3 / (c1 + c2 - c3) def classify(dataset, labels, testData, k=20):
distances = [] for i in range(len(labels)):
d = tanimoto(dataset[i], testData)
distances.append((d, labels[i])) distances.sort(reverse=True)
#key label, value count of the label
klabelDict = {}
for i in range(k):
klabelDict.setdefault(distances[i][1], 0)
klabelDict[distances[i][1]] += 1 / k #按value降序排序
predDict = sorted(klabelDict.items(), key=lambda item: item[1], reverse=True)
return predDic dataset, labels = createDataset('trainingDigits')
testData = img2vector('testDigits/8_19.txt')
print(classify(dataset, labels, testData))

  我们事先使用pillow对手写数字进行了二值化处理,形成一个32*32的矩阵,并将每个训练样本保存到一个txt文件,文件名以数字开头,这个数字就是手写数字的label,如3_1.txt,其中的内容是:

        由于特征值仅由0和1构成,可以将二维的样本数据保存到一维数组,img2vector完成了数据的转换。在计算相似度时,使用谷本系数(Tanimoto)计算有限离散集之间的距离,其公式是:,两者重合(相交)的越多,其相似度越高。classify对测试数据进行分类,返回一个包含了预测结果和结果几率的字典。

加权kNN

  在上述手写识别的例子中,供使用了900个测试样本,其中34个产生了误判,下图是一个误判的例子:

  图中是手写数字1,程序判断为7,其原因是代码所用的方法有可能会选择很远的近邻:

  Y点肉眼去看因为在红色区域内很容易判断出多半属于红色一类,但因为蓝色过多,若K值选取稍大则很容易将其归为蓝色一类。为了改进这一点,可以为每个点的距离增加一个权重,这样距离近的点可以得到更大的权重。具体的加权方法将会在下一篇文章中介绍。


   出处:微信公众号 "我是8位的"

  本文以学习、研究和分享为主,如需转载,请联系本人,标明作者和出处,非商业用途!

   扫描二维码关注作者公众号“我是8位的”

k最邻近算法——使用kNN进行手写识别的更多相关文章

  1. 机器学习实战kNN之手写识别

    kNN算法算是机器学习入门级绝佳的素材.书上是这样诠释的:“存在一个样本数据集合,也称作训练样本集,并且样本集中每个数据都有标签,即我们知道样本集中每一条数据与所属分类的对应关系.输入没有标签的新数据 ...

  2. python 实现 KNN 分类器——手写识别

    1 算法概述 1.1 优劣 优点:进度高,对异常值不敏感,无数据输入假定 缺点:计算复杂度高,空间复杂度高 应用:主要用于文本分类,相似推荐 适用数据范围:数值型和标称型 1.2 算法伪代码 (1)计 ...

  3. 在opencv3中实现机器学习算法之:利用最近邻算法(knn)实现手写数字分类

    手写数字digits分类,这可是深度学习算法的入门练习.而且还有专门的手写数字MINIST库.opencv提供了一张手写数字图片给我们,先来看看 这是一张密密麻麻的手写数字图:图片大小为1000*20 ...

  4. k最邻近算法——加权kNN

    加权kNN 上篇文章中提到为每个点的距离增加一个权重,使得距离近的点可以得到更大的权重,在此描述如何加权. 反函数 该方法最简单的形式是返回距离的倒数,比如距离d,权重1/d.有时候,完全一样或非常接 ...

  5. kNN算法实例(约会对象喜好预测和手写识别)

    import numpy as np import operator import random import os def file2matrix(filePath):#从文本中提取特征矩阵和标签 ...

  6. 基于kNN的手写字体识别——《机器学习实战》笔记

    看完一节<机器学习实战>,算是踏入ML的大门了吧!这里就详细讲一下一个demo:使用kNN算法实现手写字体的简单识别 kNN 先简单介绍一下kNN,就是所谓的K-近邻算法: [作用原理]: ...

  7. 机器学习实战一:kNN手写识别系统

    实战一:kNN手写识别系统 本文将一步步地构造使用K-近邻分类器的手写识别系统.由于能力有限,这里构造的系统只能识别0-9.需要识别的数字已经使用图形处理软件,处理成具有相同的色彩和大小:32像素*3 ...

  8. 利用神经网络算法的C#手写数字识别

    欢迎大家前往云+社区,获取更多腾讯海量技术实践干货哦~ 下载Demo - 2.77 MB (原始地址):handwritten_character_recognition.zip 下载源码 - 70. ...

  9. KNN实现手写数字识别

    KNN实现手写数字识别 博客上显示这个没有Jupyter的好看,想看Jupyter Notebook的请戳KNN实现手写数字识别.ipynb 1 - 导入模块 import numpy as np i ...

随机推荐

  1. hdu 1175 bfs+priority_queue

    连连看 如上图所示如果采用传统bfs的话,如果按照逆时针方向从(1,1)-->(3,4)搜索,会优先选择走拐四次弯的路径导致ans错误: Time Limit: 20000/10000 MS ( ...

  2. OAF系统更新默认LOGO图标和主页环境描述

    更新EBS  OAF系统中默认的LOGO图标和主页的环境描述 左上角的ORACLE图片位置在  登录界面左上角oracle LOGO图片为GIF格式,大小155*20 背景透明.文件名为:FNDSSC ...

  3. OC Copy和内存管理

  4. AOJ1024 Cleaning Robot 2.0

    先说一说这个OJ:貌似是11区某大学ACM的OJ,叫AIZU ONLINE JUDGE,貌似还可以看到部分犇的代码...跪跪跪 然后知道这个OJ是某场比赛安利的= = 接下来将做法: 首先我们可以发现 ...

  5. PHP:第三章——数组中的array_values

    例: <?php header("Content-Type:text/html;charset=utf-8"); //array_value(); //功能:返回数组中所有的 ...

  6. cas 认证管理器

    CAS-默认的认证管理器:AuthenticationManagerImpl <bean id="authenticationManager" class="org ...

  7. 抓取错误之onerror

    一处定义,可以抓取全局的错误,相当于一个全局的try catch呀. <html> <head> <script type="text/javascript&q ...

  8. pandas 常用语句

    pandas的功能非常强大,支持类似与sql的数据增.删.查.改,并且带有丰富的数据处理函数: 支持时间序列分析功能:支持灵活处理缺失数据等. pandas的基本数据结构是Series和DataFra ...

  9. apache的<directory> 语句以及属性的含义

    在整完apache和tomcat的之后我觉得有必要把<directory>和它下面的属性捋顺一下 如何访问根目录下的目录http://192.168.1.12/test/ 第一.缺省apa ...

  10. arpspoof与其他几款工具的使用

    arpspoof 是一款进行arp欺骗的工具 arpspoof -i 网卡 -t 目标ip 默认网关 如果kali没有进行IP转发  那么目标就会因为配置错网而导致断网 这就是所谓的arp断网攻击 开 ...