KNN分类算法实现手写数字识别
需求:
利用一个手写数字“先验数据”集,使用knn算法来实现对手写数字的自动识别;
先验数据(训练数据)集:
♦数据维度比较大,样本数比较多。
♦ 数据集包括数字0-9的手写体。
♦每个数字大约有200个样本。
♦每个样本保持在一个txt文件中。
♦手写体图像本身的大小是32x32的二值图,转换到txt文件保存后,内容也是32x32个数字,0或者1,如下:
数据集压缩包解压后有两个目录:(将这两个目录文件夹拷贝的项目路径下E:/KNNCase/digits/)
♦目录trainingDigits存放的是大约2000个训练数据
♦目录testDigits存放大约900个测试数据。
模型分析:
1、手写体因为每个人,甚至每次写的字都不会完全精确一致,所以,识别手写体的关键是“相似度”
2、既然是要求样本之间的相似度,那么,首先需要将样本进行抽象,将每个样本变成一系列特征数据(即特征向量)
3、手写体在直观上就是一个个的图片,而图片是由上述图示中的像素点来描述的,样本的相似度其实就是像素的位置和颜色之间的组合的相似度
4、因此,将图片的像素按照固定顺序读取到一个个的向量中,即可很好地表示手写体样本
5、抽象出了样本向量,及相似度计算模型,即可应用KNN来实现
python实现:
新建一个KNN.py脚本文件,文件里面包含四个函数:
1) 一个用来生成将每个样本的txt文件转换为对应的一个向量,
2) 一个用来加载整个数据集,
3) 一个实现kNN分类算法。
4) 最后就是实现加载、测试的函数。
#!/usr/bin/python
# coding=utf-8
#########################################
# kNN: k Nearest Neighbors # 参数: inX: vector to compare to existing dataset (1xN)
# dataSet: size m data set of known vectors (NxM)
# labels: data set labels (1xM vector)
# k: number of neighbors to use for comparison # 输出: 多数类
######################################### from numpy import *
import operator
import os # KNN分类核心方法
def kNNClassify(newInput, dataSet, labels, k):
numSamples = dataSet.shape[0] # shape[0]代表行数 # # step 1: 计算欧式距离
# tile(A, reps): 将A重复reps次来构造一个矩阵
# the following copy numSamples rows for dataSet
diff = tile(newInput, (numSamples, 1)) - dataSet # Subtract element-wise
squaredDiff = diff ** 2 # squared for the subtract
squaredDist = sum(squaredDiff, axis = 1) # sum is performed by row
distance = squaredDist ** 0.5 # # step 2: 对距离排序
# argsort()返回排序后的索引
sortedDistIndices = argsort(distance) classCount = {} # 定义一个空的字典
for i in xrange(k):
# # step 3: 选择k个最小距离
voteLabel = labels[sortedDistIndices[i]] # # step 4: 计算类别的出现次数
# when the key voteLabel is not in dictionary classCount, get()
# will return 0
classCount[voteLabel] = classCount.get(voteLabel, 0) + 1 # # step 5: 返回出现次数最多的类别作为分类结果
maxCount = 0
for key, value in classCount.items():
if value > maxCount:
maxCount = value
maxIndex = key return maxIndex # 将图片转换为向量
def img2vector(filename):
rows = 32
cols = 32
imgVector = zeros((1, rows * cols))
fileIn = open(filename)
for row in xrange(rows):
lineStr = fileIn.readline()
for col in xrange(cols):
imgVector[0, row * 32 + col] = int(lineStr[col]) return imgVector # 加载数据集
def loadDataSet():
# # step 1: 读取训练数据集
print "---Getting training set..."
dataSetDir = 'E:/KNNCase/digits/'
trainingFileList = os.listdir(dataSetDir + 'trainingDigits') # 加载测试数据
numSamples = len(trainingFileList) train_x = zeros((numSamples, 1024))
train_y = []
for i in xrange(numSamples):
filename = trainingFileList[i] # get train_x
train_x[i, :] = img2vector(dataSetDir + 'trainingDigits/%s' % filename) # get label from file name such as "1_18.txt"
label = int(filename.split('_')[0]) # return 1
train_y.append(label) # # step 2:读取测试数据集
print "---Getting testing set..."
testingFileList = os.listdir(dataSetDir + 'testDigits') # load the testing set
numSamples = len(testingFileList)
test_x = zeros((numSamples, 1024))
test_y = []
for i in xrange(numSamples):
filename = testingFileList[i] # get train_x
test_x[i, :] = img2vector(dataSetDir + 'testDigits/%s' % filename) # get label from file name such as "1_18.txt"
label = int(filename.split('_')[0]) # return 1
test_y.append(label) return train_x, train_y, test_x, test_y # 手写识别主流程
def testHandWritingClass():
# # step 1: 加载数据
print "step 1: load data..."
train_x, train_y, test_x, test_y = loadDataSet() # # step 2: 模型训练.
print "step 2: training..."
pass # # step 3: 测试
print "step 3: testing..."
numTestSamples = test_x.shape[0]
matchCount = 0
for i in xrange(numTestSamples):
predict = kNNClassify(test_x[i], train_x, train_y, 3)
if predict == test_y[i]:
matchCount += 1
accuracy = float(matchCount) / numTestSamples # # step 4: 输出结果
print "step 4: show the result..."
print 'The classify accuracy is: %.2f%%' % (accuracy * 100)
KNNTest.py
#!/usr/bin/python
# coding=utf-8 import KNN
KNN.testHandWritingClass()
测试结果:
KNN分类算法实现手写数字识别的更多相关文章
- 基于OpenCV的KNN算法实现手写数字识别
基于OpenCV的KNN算法实现手写数字识别 一.数据预处理 # 导入所需模块 import cv2 import numpy as np import matplotlib.pyplot as pl ...
- C#中调用Matlab人工神经网络算法实现手写数字识别
手写数字识别实现 设计技术参数:通过由数字构成的图像,自动实现几个不同数字的识别,设计识别方法,有较高的识别率 关键字:二值化 投影 矩阵 目标定位 Matlab 手写数字图像识别简介: 手写 ...
- 使用AI算法进行手写数字识别
人工智能 人工智能(Artificial Intelligence,简称AI)一词最初是在1956年Dartmouth学会上提出的,从那以后,研究者们发展了众多理论和原理,人工智能的概念也随之扩展 ...
- KNN算法案例--手写数字识别
import numpy as np import matplotlib .pyplot as plt import pandas as pd from sklearn.neighbors impor ...
- 实验楼 1. k-近邻算法实现手写数字识别系统--《机器学习实战 》
首先看看一些关键词:K-NN算法,训练集,测试集,特征(空间),标签 举实验楼中的样例,通俗的讲讲K-NN算法:电影有两个分类(标签)-动作片-爱情片.两个特征--打斗场面--亲吻画面. 将那些数字和 ...
- CNN:人工智能之神经网络算法进阶优化,六种不同优化算法实现手写数字识别逐步提高,应用案例自动驾驶之捕捉并识别周围车牌号—Jason niu
import mnist_loader from network3 import Network from network3 import ConvPoolLayer, FullyConnectedL ...
- 分类-MNIST(手写数字识别)
这是学习<Hands-On Machine Learning with Scikit-Learn and TensorFlow>的笔记,如果此笔记对该书有侵权内容,请联系我,将其删除. 这 ...
- 机器学习框架ML.NET学习笔记【4】多元分类之手写数字识别
一.问题与解决方案 通过多元分类算法进行手写数字识别,手写数字的图片分辨率为8*8的灰度图片.已经预先进行过处理,读取了各像素点的灰度值,并进行了标记. 其中第0列是序号(不参与运算).1-64列是像 ...
- 一看就懂的K近邻算法(KNN),K-D树,并实现手写数字识别!
1. 什么是KNN 1.1 KNN的通俗解释 何谓K近邻算法,即K-Nearest Neighbor algorithm,简称KNN算法,单从名字来猜想,可以简单粗暴的认为是:K个最近的邻居,当K=1 ...
随机推荐
- 淘淘商城之SSM框架整合概要
一.后台系统所用的技术 1)框架:Spring + SpringMVC + Mybatis: 2)前端:EasyUI: 3)数据库:mysql 二.创建数据库 1)安装mysql数据库: 2)在mys ...
- Javaweb学习笔记——(二)——————CSS概述,进入JavaScript
day02day01内容回顾 1.html操作思想 **使用标签把要操作的数据包起来,通过修改标签的属性值来是实现标签内数据样式的变化 ***<font size="5"&g ...
- php 设置中文 cookie, js获取
参考链接:http://www.nowamagic.net/librarys/veda/detail/1271 http://www.ruanyifeng.com/blog/2008/06/base6 ...
- Biorhythms HDU - 1370 (中国剩余定理)
孙子定理: 当前存在三个式子,t%3=2,t%5=3,t%7=2.然后让你求出t的值的一个通解. 具体过程:选取3和5的一个公倍数t1能够使得这个公倍数t1%7==1,然后选取3和7的一个公倍数t2使 ...
- 论文笔记系列-Neural Architecture Search With Reinforcement Learning
摘要 神经网络在多个领域都取得了不错的成绩,但是神经网络的合理设计却是比较困难的.在本篇论文中,作者使用 递归网络去省城神经网络的模型描述,并且使用 增强学习训练RNN,以使得生成得到的模型在验证集上 ...
- GitHub:Awesome-Hacking(黑客技能列表-恶意代码)
0 初衷 GitHub这一份黑客技能列表很不错,包含了多个方向的安全.但目前我关注只有逆向工程与恶意代码,所以其他的被暂时略过. 虽然很感谢作者的辛勤付出,但并不打算复制粘贴全套转载.逐条整理是为了从 ...
- ROC,AUC,PR,AP介绍及python绘制
这里介绍一下如题所述的四个概念以及相应的使用python绘制曲线: 参考博客:http://kubicode.me/2016/09/19/Machine%20Learning/AUC-Calculat ...
- Linux串口—struct termios结构体【转】
转自:https://blog.csdn.net/yemingzhu163/article/details/5897156 一.数据成员 termios 函数族提供了一个常规的终端接口,用于控制非同步 ...
- Linux Kernel 代码艺术——编译时断言【转】
转自:http://www.cnblogs.com/hazir/p/static_assert_macro.html 本系列文章主要写我在阅读Linux内核过程中,关注的比较难以理解但又设计巧妙的代码 ...
- 设置linux新用户默认当前目录及使用的shell
切换到root用户,直接修改/etc/passwd文件,找到你的用户名你一行,如下图所示修改路径,然后保存即可.