最邻近算法(KNN)识别数字验证码
应用场景
对于简单的数字型验证码的自动识别。前期已经完成的工作是通过切割将验证码图片切割成一个一个的单个数字的图片,并按照对应的数字表征类别进行分类(即哪些图片表示数字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)识别数字验证码的更多相关文章
- knn识别简单验证码
参考 https://www.biaodianfu.com/knn-captcha-recognition.html 内容大致一样,只是根据自己的想法加入了一些改动 KNN(k近邻算法) 算法原理请看 ...
- k邻近算法(KNN)实例
一 k近邻算法原理 k近邻算法是一种基本分类和回归方法. 原理:K近邻算法,即是给定一个训练数据集,对新的输入实例,在训练数据集中找到与该实例最邻近的K个实例,这K个实例的多数属于某个类,就把该输入实 ...
- <机器学习实战>读书笔记--k邻近算法KNN
k邻近算法的伪代码: 对未知类别属性的数据集中的每个点一次执行以下操作: (1)计算已知类别数据集中的点与当前点之间的距离: (2)按照距离递增次序排列 (3)选取与当前点距离最小的k个点 (4)确定 ...
- selenium来识别数字验证码
用python写一爬虫,需要模拟登陆,并且有数字验证码.通过selenium+pytesseract+PIL可以实现验证码识别并登陆.三大步: 用selenium截屏,此时截取的是整个页面的 用PIL ...
- python之基于libsvm识别数字验证码
1. 参考 字符型图片验证码识别完整过程及Python实现 2.图片预处理和手动分类 (1)分析图片 from PIL import Image img = Image.open('nums/ttt. ...
- Python识别网站验证码
http://drops.wooyun.org/tips/6313 Python识别网站验证码 Manning · 2015/05/28 10:57 0x00 识别涉及技术 验证码识别涉及很多方面的内 ...
- 监督学习——K邻近算法及数字识别实践
1. KNN 算法 K-近邻(k-Nearest Neighbor,KNN)是分类算法,是一个理论上比较成熟的方法,也是最简单的机器学习算法之一.该方法的思路是:如果一个样本在特征空间中的k个最相似( ...
- k最邻近算法——使用kNN进行手写识别
上篇文章中提到了使用pillow对手写文字进行预处理,本文介绍如何使用kNN算法对文字进行识别. 基本概念 k最邻近算法(k-Nearest Neighbor, KNN),是机器学习分类算法中最简单的 ...
- KNN识别图像上的数字及python实现
领导让我每天手工录入BI系统中的数据并判断数据是否存在异常,若有异常点,则检测是系统问题还是业务问题.为了解放双手,我决定写个程序完成每天录入管理驾驶舱数据的任务.首先用按键精灵录了一套脚本把系统中的 ...
随机推荐
- Jquery的框架解析
最近闲的刁痛,想看看jQuery源码.但是这个源码看起来 还是挺费劲的.所以呢整理一份框架出来, 避免走入jQuery关键字的误区,我用Gys代替关键字jQuery. 下面是源码: (function ...
- 基于pyQt5开发的股价显示器(原创)
#/usr/bin/env python # -*- coding: utf-8 -*- ''' @author="livermorium116" 为了绕开公司内网而开发的 股票实 ...
- ECharts动态加载堆叠柱状图的实例
一.引入echarts.js文件(下载页:http://echarts.baidu.com/download.html) 二.HTML代码: <div style="width: 10 ...
- Java 多线程 (Thread 类)
1.多线程 2.卖票 1.多线程实现 两种方式可以实现多线程: 继承 Thread 类,重写 run 方法:定义对象,调用 start 方法 创建类实现 Runnable 接口,作为实参传递给 thr ...
- 50.纯 CSS 创作一个永动的牛顿摆
原文地址:https://segmentfault.com/a/1190000015270808#articleHeader0 感想: 动画效果 + ::before + 2D转换 HTML code ...
- 《算法》第三章部分程序 part 6
▶ 书中第三章部分程序,加上自己补充的代码,包含双向索引表.文建索引.稀疏向量类型 ● 双向索引表 package package01; import edu.princeton.cs.algs4.S ...
- dom编程艺术章12
function addLoadEvent(func){//添加事件函数 var oldonload = window.onload; if(typeof window.onload != 'func ...
- python3下安装Selenium插件和驱动
import sysimport osimport shutilimport time os.system('pip install selenium') file_name="IEDriv ...
- Address already in use: JVM_Bind 端口被占用的几个解决办法
运行Tomcat时若出现Address already in use: JVM_Bind 端口被占用,一般使用下面几个办法可以解决: 假设端口为1099 1.启动cmd, 执行命令netstat -a ...
- POI解析大量数据
参考:https://blog.csdn.net/whandgdh/article/details/80267674