本文实例讲述了Python实现基于KNN算法的笔迹识别功能。分享给大家供大家参考,具体如下:

需要用到:

Numpy库

Pandas库

手写识别数据 点击此处本站下载。

数据说明:

数据共有785列,第一列为label,剩下的784列数据存储的是灰度图像(0~255)的像素值 28*28=784

KNN(K近邻算法):

从训练集中找到和新数据最接近的K条记录,根据他们的主要分类来决定新数据的类型。

这里的主要分类,可以有不同的判别依据,比如“最多”,“最近邻”,或者是“距离加权”。

整个程序的几个部分:

1.数据的归一化处理(normalization)

2.(重要)找出与test数据最接近的train数据的编号,根据编号查找到对应的label,将label赋给test数据的预测值

3.统计知道的test的label值与test的预测label值得正确率

Step 1

导入Numpy与Pandas库

import numpy as np

import pandas as pd

Step 2

对数据进行归一化

对数据归一化的方法很多,比如:

一、max-Min标准化

max - Min标准化方法是对原始数据进行线性变换。设minA和maxA分别为属性A的最小值和最大值,将A的一个原始值x通过max-Min标准化映射成在区间[0,1]中的值x',其公式为:

新数据=(原数据-极小值)/(极大值-极小值)

二、

新数据=原数据/(原数据的平方和开根号)

三、

y = ( x - min )/( max - min ) 其中min为x的最小值,max为x的最大值,输入向量为x,归一化后的输出向量为y 。上式将数据归一化到 [ 0 , 1 ]区间,当激活函数采用S形函数时(值域为(0,1))时这条式子适用

在这里采用方法二

def normalize(x):

norms = np.apply_along_axis(np.linalg.norm,1,x)

return x / np.expand_dims(norms,-1)

调用np中的linalg.norm(x)和 apply_along_axis(func, axis, x)函数

linalg.norm(x)函数的作用是 return sum(abs(xi)**2)**0.5,

apply_along_axis(func, axis, x)函数的作用是将x按axis方向执行func函数,axis=0表示做列方向上的运算,axis=1表示做行方向上的运算

step 3

找出与test数据最接近的train数据,这步是最关键的一步。

在这里,test数据与train数据就是空间的两个向量,问题就变成了如何计算这两个向量的相似程度。

我们可以把它们想象成空间中的两条线段,都是从原点([0, 0, ...])出发,指向不同的方向。两条线段之间形成一个夹角,如果夹角为0度,意味着方向相同、线段重合;如果夹角为90度,意味着形成直角,方向完全不相似;如果夹角为180度,意味着方向正好相反。因此,我们可以通过夹角的大小,来判断向量的相似程度。夹角越小,就代表越相似。

假定a向量是[x1, y1],b向量是[x2, y2],那么可以将余弦定理改写成下面的形式:

余玄定理

def nearest_neighbor(norm_func,train_data,train_label,test_data):

train_data = norm_func(train_data)

test_data = norm_func(test_data)

cos = np.dot(train_data,np.transpose(test_data))#np.transpose为求转置,dot为矩阵的乘积,结果为cos的一列值为test与train的相似度

max_cos = np.argmax(cos,axis=0)#np.argmax为cos中一列上方的最大值

test_pred = train_label[max_cos]#train_label为一列,max_cos为一个数组,train_label[max_cos]会读出train_label中max_cos数组编号的元素

return test_pred#返回test的预测值

step 4

统计预测值的正确率

def validate(test_pred,test_label):

c=len(test_pred)#在数组里面套数组的时候,len得到的是大数组里数组的个数,在只有一层数组的时候,得到的是数组中元素的个数

correct=(test_pred == test_label).sum()#统计两个数组中有多少个元素相同

return float(correct)/c#必须转变成浮点数再做除法,之前使用correct/c得到0

测试代码:

if __name__ == '__main__':

train_num = 200

test_num = 300#测试数据起始是test_num-train_num

x = pd.read_csv('train.csv')

x_train = x.values[0:train_num,1:]#读取pandas中读取出来的数据,需要用data.values[]

x_train_label = x.values[0:train_num,0]#第一列是label,每幅图的数据是一行

x_test = x.values[train_num:test_num,1:]

x_test_label = x.values[train_num:test_num,0]

test_pred=nearest_neighbor(normalize,x_train,x_train_label,x_test)

prec=validate(test_pred,x_test_label)

print u"正确率为%.2f"%(prec)#浮点数是%f

完整代码点击此处本站下载。

注解:

上面部分主要是讲解KNN算法,运用到的是现成的28*28的数据,而在实际做笔迹分析的时候,首先需要将图像转化成矩阵数据。

现在介绍一下,图像转化成矩阵与矩阵转化成图像的方法

矩阵转化成图像

需要用到的库是图像处理库Python Imaging Library (PIL)

在Windows下使用pip install PIL安装失败,采取了下载PIL.exe双击安装的方法

下载地址:

PIL官方下载地址

import pandas as pd

import numpy as np

from PIL import Image

# load data

train = pd.read_csv('train.csv')

# now draw the numbers

for ind, row in train.iloc[0:3].iterrows():#iloc方法(介绍见后)来获得前3行数据

i = row[0]#[0]为标签项

arr = np.array(row[1:], dtype=np.uint8)#1-784列组成一幅图,,uint8为8位无符号整数

#arr = np.array(255 - row[1:], dtype=np.uint8)#如果需要颜色取反,用255减去当前每个像素点的值

arr.resize((28, 28))#把它变成28*28的矩阵

#save to file

im = Image.fromarray(arr)

im.save("./train_pics/%s-%s.png" % (ind, i))#第一个%s(ind)表示它是第几幅图像,第二个%s表示这个图像里面数字是几 ,注意该语句不能产生文件夹,需要现在指定目录建一个文件夹

.iloc()方法

iloc[行位置,列位置]

df.iloc[1,1]#选取第二行,第二列的值,返回的为单个值

df.iloc[0,2],:]#选取第一行及第三行的数据

图像转化成矩阵

需要用到的库是opencv(open source computer vision),下载安装方式请参照附录:python_OpenCV安装

这里主要讲它的几个简单功能

1.静态图像的输入,输出

cv2.imread('xxx.png')#输入,#这里输入image的维度image.shape = (w,h,3),w*h是图片的长宽,3是BGR等三种颜色的channel值,每个值为0~255

cv2.imwrite('xxx.jpg', image)#输出

2.将图片转化为灰度图片

#灰度图片的颜色channel只有一个,0~255表示灰度值

grayImage = cv2.imread('xxx.png',cv2.CV_LOAD_IMAGE_GRAYSCALE)

3.改变图像的大小

print grayImage.shape#查看图像的shape,shape为(137,301),如果查看的是图像的size,则为42137(41237=137*301)

res=cv2.resize(grayImage,(28,28),interpolation=cv2.INTER_CUBIC)#将图片grayImage以cv2.INTER_CUBIC方式变化为(28,28)大小的图片

变换的方法:

CV_INTER_NN - 最近邻插值,

CV_INTER_LINEAR - 双线性插值 (缺省使用)

CV_INTER_AREA - 使用象素关系重采样。当图像缩小时候,该方法可以避免波纹出现。当图像放大时,类似于 CV_INTER_NN 方法..

CV_INTER_CUBIC -立方插值.

下面是有关输入,输出,改变成灰度图,改变图像大小,显示的完整程序,注意图像在窗口中的显示

import cv2

image = cv2.imread('111.png')#读

cv2.imwrite('111.jpg', image)#写

grayImage = cv2.imread('111.png',cv2.CV_LOAD_IMAGE_GRAYSCALE)

print grayImage.shape

res=cv2.resize(grayImage,(28,28),interpolation=cv2.INTER_CUBIC)

#显示图像

cv2.imshow('test',grayImage)#显示灰度图

cv2.imshow('change',res)#显示改变了大小的图

#捕获键盘输入

k=cv2.waitKey(0)

if k==27:#27表示ESC键

cv2.destroyWindow()

cv2.imshow()用于将图片显示在窗口中,后面必须跟个cv2.waitKey()函数,才能让显示持续,不然显示出来程序就中止了,窗口就会被关闭。cv2.waitKey()函数是捕获键盘的输入,cv2.destroyWindow()是释放窗口。

在学习了如果读取,输出图片后,我们就可以用写好的KNN算法识别我们的笔迹了。

问题:

我使用了很多手写的数据去验证识别是否准确,发现准确率还不够高。主要存在的问题是

1.图片大小问题,大小的调节不应该把整张图片变为28*28的图,而应该识别出写有数字的中心图片,把旁边的白边去掉

2.手写的数字照片,不能保证写字的地方为黑(像素值为255)

解决方式:需要使用一个滤波器,把因纸张,拍摄问题出现的像素值降。再没有使用滤波器的条件下,我把照片换成了在画图板上写的数字。

3.写字的粗细会影响判断

解决办法:这个可能是训练样本不够多,整体训练样本的字迹偏粗,在输入很细的笔迹时,不能识别出来。还有就是应该监测输入字体的粗细,对输入的很细的笔迹做膨胀处理,对很粗的笔迹做腐蚀处理

附:python_OpenCV安装

看到网上好多教程的是在VS环境下OpenCV的安装,而我一直都是在windows7,32位,sublime+cmd环境下,进行python的编程,所以琢磨了下这种条件下的OpenCV安装

使用pip install numpy语句安装numpy

(如果出现错误:Microsoft Visual C++ 9.0 is required ,使用管理员身份安装 Microsoft Visual C++ 9.0,重新启动计算机,再使用使用pip install numpy语句安装numpyopencv2.4.10下载

下载之后解压(随便解压到哪里),将解压目录opencv文件夹中,build->python->2.7->x86下的文件cv2.pyd 复制到python2.7\Lib\site-packages 中

测试是否安装成功,执行解压目录下的sources\samples\python\drawing.py或者进入python环境,使用import cv2

更多关于Python相关内容感兴趣的读者可查看本站专题:《Python数学运算技巧总结》、《Python数据结构与算法教程》、《Python函数使用技巧总结》、《Python字符串操作技巧汇总》、《Python入门与进阶经典教程》及《Python文件与目录操作技巧汇总》

希望本文所述对大家Python程序设计有所帮助。

本文标题: Python实现基于KNN算法的笔迹识别功能详解

本文地址: http://www.cppcns.com/jiaoben/python/232504.html

python模拟手写笔迹_Python实现基于KNN算法的笔迹识别功能详解相关推荐

  1. python 数学公式识别_Python实现基于KNN算法的笔迹识别功能详解

    本文实例讲述了Python实现基于KNN算法的笔迹识别功能.分享给大家供大家参考,具体如下: 需要用到: Numpy库 Pandas库 手写识别数据 点击此处本站下载. 数据说明: 数据共有785列, ...

  2. Python 手写机器学习最简单的 kNN 算法

    https://www.toutiao.com/a6698919092876739079/ Python 手写机器学习最简单的 kNN 算法 苏克1900 Python爬虫与数据挖掘 本文 3000 ...

  3. python 数据、曲线平滑处理——基于Numpy.convolve实现滑动平均滤波——详解

    文章目录 1 基于Numpy.convolve实现滑动平均滤波 1.1 滑动平均概念 1.2 滑动平均的数学原理 1.3 语法 1.4 滑动平均滤波示例 2 曲线平滑处理--Savitzky-Gola ...

  4. python itchat_Python使用微信itchat接口实现查看自己微信的信息功能详解

    本文实例讲述了Python使用微信itchat接口实现查看自己微信的信息功能.分享给大家供大家参考,具体如下: itchat是python的一个api,可以访问自己的微信信息,功能还蛮好玩的,可以扒取 ...

  5. python笔迹识别_python_基于KNN算法的笔迹识别

    需要用到: Numpy库 Pandas库 手写识别数据 下载地址 数据说明: 数据共有785列,第一列为label,剩下的784列数据存储的是灰度图像(0~255)的像素值 28*28=784 KNN ...

  6. 用 Python 手写机器学习最简单的 KNN 算法

    作者 | 苏克1900 责编 | 胡巍巍 说实话,相比爬虫,掌握机器学习更实用竞争力也更强些. 目前网上大多这类教程对新手都不友好,要么直接调用 Sklearn 包,要么满篇抽象枯燥的算法公式文字,看 ...

  7. python 录制web视频_Python django框架 web端视频加密的实例详解

    视频加密流程图: 后端获取保利威的视频播放授权token,提供接口api给前端 参考文档:http://dev.polyv.net/2019/videoproduct/v-api/v-api-play ...

  8. python抽奖滚动界面_Python使用Tkinter实现转盘抽奖器的步骤详解

    我使用 Python 中的 Tkinter 模块实现了一个简单的滚动抽奖器,接下来继续写一个简单的转盘抽奖器. 滚动抽奖器与点名的场景相似,是从一群人中抽出中奖的人,奖品是提前确定了的,抽奖只是确定中 ...

  9. python类的命名空间_Python之关于类变量的两种赋值区别详解

    我就废话不多说了,还是直接看代码吧! # -*- coding:utf-8 -*- #面试题,写一个方法,将一行字符串中所有的单词数量统计出来 class Person(object): TAG = ...

最新文章

  1. 数据结构----单链表增删改查
  2. php中的css样式改变无反应,解决ecshop清除缓存css样式没反应问题
  3. 深入浅出--梯度下降法及其实现
  4. 推荐一个很牛逼的 Github 项目:本人历时半年完成的【Java 面试 + Java 后端技术学习指南】,已拿大厂offer
  5. 动态加载laydate 失效_Java对象的内存布局+反射的原理+动态代理+ 并发和锁+文末彩蛋...
  6. 关于MyEclipse项目的名字的修改对项目导入导出的影响
  7. Jqgried树形列表
  8. python123添加列表元素_Python之列表
  9. paip.mysql 性能测试 报告 home right
  10. 【转载】金山词霸”屏幕取词技术揭密(讨论稿)
  11. linux运行海康的sdk,海康摄像头SDK在Linux、windows下的兼容问题(二)已解决
  12. 看到有人在帮易到洗白,镁客君只想说:易到或许并非不可或缺
  13. [原]最初的梦想---关于野猪和家猪
  14. 我的世界电脑服务器怎么显示键盘,我的世界电脑版操作按键
  15. qq的云消息服务器,20 万台 QQ 服务器全面上云
  16. Super Prime
  17. Gitlab-runner 构建失败问题排查
  18. 风险管理_cissp
  19. 数据分析-如何搭建业务指标体系
  20. idea不区分大小写提示

热门文章

  1. LinkedList底层链表结构
  2. Dynamic Debug [dyndbg] 概述
  3. 在我们使用vue-admin-templete进行二次开发的时候,我们会发现有些是英文,比如分页里面的每页尺码。
  4. 如何提升会议体验感和氛围感?
  5. 再谈机器学习中的归一化方法(Normalization Method)
  6. 程序猿的世界~~~~
  7. 数据库系统-存储过程
  8. dvwa中的xss(跨站脚本)攻击
  9. 企业邮箱注册申请,如何注册电子邮箱域名
  10. autoJS pro-手机自动化脚本(douyin App模拟人工操作点赞、评论、收藏、转发)