应用场景

  对于简单的数字型验证码的自动识别。前期已经完成的工作是通过切割将验证码图片切割成一个一个的单个数字的图片,并按照对应的数字表征类别进行分类(即哪些图片表示数字7,哪些表示8),将各种数字的图片转换成32×32的二值矩阵,并存放在.txt中,每一种数字表示所对应的.txt的文件名为:“数字类标号_序号.txt”。取一部分这样的.txt作为已知样本集,另一部分作为验证集。使用最邻近算法KNN实现对数字进行识别。

最邻近算法(KNN,K-Nearest Neighbor)

  可以说KNN是最简单的分类算法了。已知的数据集是带类标号的数据。KNN本质是基于一种数据统计的方法!其实很多机器学习算法也是基于数据统计的。

  KNN是一种memory-based learning,也叫instance-based learning,属于lazy learning。即它没有明显的前期训练过程,而是程序开始运行时,把数据集加载到内存后,不需要进行训练,就可以开始分类了。下面的源码部分的注释,我用到了“训练”这样的表述,是为了在这个领域方便交流的表达。

  具体是每次来一个未知的样本点,就在附近找K个最近的点进行投票。或者说,就是计算这个未知的样本点(或者在数据挖掘领域叫“元组”)和所有已知点的欧几里得距离,选择距离最近的前k个已知样本进行投票,即这k个已知样本中,哪一种类型占的比例最大,那么就认为这个未知的样本属于哪一个分类。

源码

from numpy import *
import operator
from os import listdir def knn(k, testdata, traindata, labels): #k为人为设定的阈值,表示在最接近的k个训练元组中获得类标号 # testdata:[特征1,特征2,特征3,……,特征1024]
# traindata:[[特征1,特征2,特征3,……,特征1024],[特征1,特征2,特征3,……,特征1024],[特征1,特征2,特征3,……,特征1024],……]
#调用(numpy中的)shape函数来返回traindata的长度,也就是traindata.shape[0]返回的是训练集的元组个数
traindatasize = traindata.shape[0] #调用(numpy中的)tile将一维的testdata扩展成一个二维和traindata规模相同的矩阵。
#tile得到的矩阵和traindata作差,得到的矩阵为dif
dif = tile(testdata, (traindatasize, 1)) - traindata sqdif = dif ** 2 #计算每个特征的差的平方 # sumsqdif已经成为一维列表
sumsqdif = sqdif.sum(axis=1) # axis=1 是按行求和(axis=0是列求和) #每个和数作开平方操作,存放到一维的distance中
distance = sumsqdif ** 0.5 #对distance中的元素进行排序,argsort函数返回的是数组值从小到大的索引值,即返回的第一个元素是distance中最小值的索引值,以此类推
sortdistance = distance.argsort() # sortdistance指的是测试数据与各训练数据的距离由近到远排序之后的结果列表 #声明一个字典count存放排序前k小的类标号及其出现频数
count = {} # {"类别":"次数"}
for i in range(0, k):
vote = labels[sortdistance[i]] # 当前距离的类别是谁(由近至远)
#count.get(vote, 0)的作用是在字典count中查找vote并返回其值,如果vote键不存在则返回0
count[vote] = count.get(vote, 0) + 1 #使用sorted()产生一个新的排序后的列表,当reverse参数置为真时,这个列表是降序排序的
#item()方法把字典中每对key和value组成一个元组,并把这些元组放在列表中返回。
#key=operator.itemgetter(1)表示按第2个域排序
#因为count.items()返回一个二维列表,所以排序后sortcount也是二维的。
sortcount = sorted(count.items(), key=operator.itemgetter(1), reverse=True) #取sortcount第一行(出现次数最多的键值对)的第一个元素就是对应的预测的分类标号。
return sortcount[0][0] # 数据加载
#预处理,将源训练数据处理成一个长度为1024的整型列表
def datatoarray(fname):
arr = []
fh = open(fname)
for i in range(0, 32):
#逐行读入
thisline = fh.readline()
for j in range(0, 32):
arr.append(int(thisline[j]))
return arr # 取文件名前缀(类别)
def seplabel(fname):
#用split来切割训练元组的文件名,分隔符是下划线,split返回的是一个字符串列表,我们只需要这个列表的第一个元素,来作为这个元组的类标号,并强转为整型
label = int(fname.split("_")[0]) return label # 建立训练数据
# labels:[类别,类别,类别,类别,……]有多少个训练元组就有多少个类别标号class label
# trainarr:[[特征1,特征2,特征3,……,特征1024],[特征1,特征2,特征3,……,特征1024],[特征1,特征2,特征3,……,特征1024],……]一个字符用一个特征表示
# 可见,trainarr是一个矩阵(二维数组),有num行,1024列。num是训练元组个数,也等于lables数组的长度。一个字符用一个特征表示
def traindata():
labels = [] #trainfile是一个存储训练元组对应的文件名的一维数组
trainfile = listdir("./traindata") num = len(trainfile)
#(numpy中的)zeros函数功能是创建给定类型的矩阵,并初始化为0。在这里用来初始化一个num行,1024列的矩阵trainarr。
trainarr = zeros((num, 1024)) #遍历每一个训练元组
for i in range(0, num):
thisname = trainfile[i] #提取当前这个训练元组的类标号(分类)
thislabel = seplabel(thisname) #将当前训练元组的类标号存放进labels数组
labels.append(thislabel) #将当前这个训练元组(第i个)的内容转换成一个一维的特征序列覆盖trainarr的第i行
trainarr[i, :] = datatoarray("./traindata/" + thisname) #函数返回训练数据集trainarr和对应的类标号数组
return trainarr, labels #执行测试
trainarr, labels = traindata() #当前要测试的元组
thistestfile = "6_21.txt" #将这个测试元组转换成一维的特征序列(长度为1024)
testarr = datatoarray("./testdata/" + thistestfile) #调用函数knn,返回结果
rst = knn(3, testarr, trainarr, labels)
print(rst)

最邻近算法(KNN)识别数字验证码的更多相关文章

  1. knn识别简单验证码

    参考 https://www.biaodianfu.com/knn-captcha-recognition.html 内容大致一样,只是根据自己的想法加入了一些改动 KNN(k近邻算法) 算法原理请看 ...

  2. k邻近算法(KNN)实例

    一 k近邻算法原理 k近邻算法是一种基本分类和回归方法. 原理:K近邻算法,即是给定一个训练数据集,对新的输入实例,在训练数据集中找到与该实例最邻近的K个实例,这K个实例的多数属于某个类,就把该输入实 ...

  3. <机器学习实战>读书笔记--k邻近算法KNN

    k邻近算法的伪代码: 对未知类别属性的数据集中的每个点一次执行以下操作: (1)计算已知类别数据集中的点与当前点之间的距离: (2)按照距离递增次序排列 (3)选取与当前点距离最小的k个点 (4)确定 ...

  4. selenium来识别数字验证码

    用python写一爬虫,需要模拟登陆,并且有数字验证码.通过selenium+pytesseract+PIL可以实现验证码识别并登陆.三大步: 用selenium截屏,此时截取的是整个页面的 用PIL ...

  5. python之基于libsvm识别数字验证码

    1. 参考 字符型图片验证码识别完整过程及Python实现 2.图片预处理和手动分类 (1)分析图片 from PIL import Image img = Image.open('nums/ttt. ...

  6. Python识别网站验证码

    http://drops.wooyun.org/tips/6313 Python识别网站验证码 Manning · 2015/05/28 10:57 0x00 识别涉及技术 验证码识别涉及很多方面的内 ...

  7. 监督学习——K邻近算法及数字识别实践

    1. KNN 算法 K-近邻(k-Nearest Neighbor,KNN)是分类算法,是一个理论上比较成熟的方法,也是最简单的机器学习算法之一.该方法的思路是:如果一个样本在特征空间中的k个最相似( ...

  8. k最邻近算法——使用kNN进行手写识别

    上篇文章中提到了使用pillow对手写文字进行预处理,本文介绍如何使用kNN算法对文字进行识别. 基本概念 k最邻近算法(k-Nearest Neighbor, KNN),是机器学习分类算法中最简单的 ...

  9. KNN识别图像上的数字及python实现

    领导让我每天手工录入BI系统中的数据并判断数据是否存在异常,若有异常点,则检测是系统问题还是业务问题.为了解放双手,我决定写个程序完成每天录入管理驾驶舱数据的任务.首先用按键精灵录了一套脚本把系统中的 ...

随机推荐

  1. Delphi TstringList Stringlist的特殊用法

    procedure TForm1.btn1Click(Sender : TObject); var   m      : Integer;   s       : string;   strlst   ...

  2. Oracle数据库类型

    Oracle数据库类型 字符类型char[(length)] 定长字符 最长2000字节varchar2[(length)] 可变长度的字符数据类型,最长4000字节NCHAR[(length)] 固 ...

  3. 数组.html

    <script > var arr1 = [1, 2, 3, 4, 5, 6 ]; 赋值 var arr2 =Array(1,2,3,4,5,6); var arr3 = new Arra ...

  4. boost serialize序列化

    boost序列化 #ifndef FND_SERI_H #define FND_SERI_H #include <boost/archive/text_oarchive.hpp> #inc ...

  5. navicat创建存储过程的小问题

    再简单的东西长时间不用了就会出错,特此即时的记录下来,以便以后参考! 转自:http://blog.csdn.net/winy_lm/article/details/49690633 以下为navic ...

  6. tcp粘包解决

    import socket import hashlib import subprocess import struct phone = socket.socket(socket.AF_INET,so ...

  7. DRF 视图组件代码

    序列化器代码 # 声明序列化器from rest_framework import serializersfrom djangoDome.models import Book class Publis ...

  8. mock生成随机数的各种情况

    [发现一篇好的文章,用来自己作参考] 接口测试时需要生成各种正则表达式的随机数进行边界值测试,字符串测试等: 比如生成数字,字母,邮箱,一段中文,一段英文 推荐1:生成随机数的多种情况 http:// ...

  9. python学习之----导航树

    findAll 函数通过标签的名称和属性来查找标签 .但是如果你需要通过标签在文档中的位 置来查找标签,该怎么办?这就是导航树(Navigating Trees)的作用.在第1 章里,我们 看过用单一 ...

  10. ace admin

    .svg             image/svg+xml.woff            application/x-font-woff.woff2          application/x- ...