需求:

利用一个手写数字“先验数据”集,使用knn算法来实现对手写数字的自动识别;

先验数据(训练数据)集:

♦数据维度比较大,样本数比较多。

♦ 数据集包括数字0-9的手写体。

♦每个数字大约有200个样本。

♦每个样本保持在一个txt文件中。

♦手写体图像本身的大小是32x32的二值图,转换到txt文件保存后,内容也是32x32个数字,0或者1,如下:

♦目录trainingDigits存放的是大约2000个训练数据

♦目录testDigits存放大约900个测试数据。

trainingDigits文件夹中为训练数据,里面存储的都是32*32的txt格式的数字图像数值矩阵。testDigits文件夹中为测试数据,存储格式与trainingDigits中相同。文件格式名例如:0_1.txt,0为数字的标签(即数字本身),1为表示数字0的第一个文件。训练数据是多张32*32手写图像的二维矩阵,所谓二维矩阵就是整个图像空白的地方使用0描述,写字的地方使用1描述,

代码python:https://github.com/kongxiaoshuang/KNN

#-*- coding: utf-8 -*-
from numpy import *
import operator import matplotlib
import matplotlib.pyplot as plt def createDataSet():
group = array([[1.0, 1.1], [1.0, 1.0], [0, 0], [0, 0.1]])
labels = ['A', 'A', 'B', 'B']
return group, labels def classify0(inX, dataSet, labels, k): #inX为用于分类的输入向量,dataSet为输入的训练样本集, labels为训练标签,k表示用于选择最近的数目
dataSetSize = dataSet.shape[0] #dataSet的行数
diffMat = tile(inX, (dataSetSize, 1)) - dataSet #将inX数组复制成与dataSet相同行数,与dataSet相减,求坐标差
sqDiffMat = diffMat**2 #diffMat的平方
sqDistances = sqDiffMat.sum(axis=1) #将sqDiffMat每一行的所有数相加
distances = sqDistances**0.5 #开根号,求点和点之间的欧式距离
sortedDistIndicies = distances.argsort() #将distances中的元素从小到大排列,提取其对应的index,然后输出到sortedDistIndicies
classCount = {} #创建字典
for i in range(k):
voteIlabel = labels[sortedDistIndicies[i]] #前k个标签数据
classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1 #判断classCount中有没有对应的voteIlabel,
# 如果有返回voteIlabel对应的值,如果没有则返回0,在最后加1。为了计算k个标签的类别数量
sortedClassCount = sorted(classCount.items(),
key=operator.itemgetter(1), reverse=True) #生成classCount的迭代器,进行排序,
# operator.itemgetter(1)以标签的个数降序排序
return sortedClassCount[0][0] #返回个数最多的标签 def file2matrix(filename):
fr = open(filename)
arrayOLines = fr.readlines() #读入所有行
numberOfLines = len(arrayOLines) #行数
returnMat = zeros((numberOfLines, 3)) #创建数组,数据集
classLabelVector = [] #标签集
index = 0
for line in arrayOLines:
line = line.strip() #移除所有的回车符
listFromLine = line.split('\t') #把一个字符串按\t分割成字符串数组
returnMat[index,:] = listFromLine[0:3] #取listFromLine的前三个元素放入returnMat
classLabelVector.append(int(listFromLine[-1])) #选取listFromLine的最后一个元素依次存入classLabelVector列表中
index += 1
return returnMat, classLabelVector def autoNorm(dataSet):
minVals = dataSet.min(0) #0表示从列中选取最小值
maxVals = dataSet.max(0) #选取最大值
ranges = maxVals-minVals
normDataSet = zeros(shape(dataSet)) #创建一个与dataSet大小相同的零矩阵
m = dataSet.shape[0] #取dataSet得行数
normDataSet = dataSet - tile(minVals, (m, 1)) #将minVals复制m行 与dataSet数据集相减
#归一化相除
normDataSet = normDataSet/tile(ranges, (m, 1)) #将最大值-最小值的值复制m行 与normDataSet相除,即归一化
return normDataSet, ranges, minVals #normDataSet为归一化特征值,ranges为最大值-最小值 def datingClassTest():
hoRatio = 0.10 #测试数据占总数据的百分比
datingDataMat, datingLabels = file2matrix('datingTestSet2.txt') #将文本信息转成numpy格式
#datingDataMat为数据集,datingLabels为标签集
normMat, ranges, minVals = autoNorm(datingDataMat) #将datingDataMat数据归一化
#normMat为归一化数据特征值,ranges为特征最大值-最小值,minVals为最小值
m = normMat.shape[0] #取normMat的行数
numTestVecs = int(m*hoRatio) #测试数据的行数
errorCount = 0.0 #错误数据数量
for i in range(numTestVecs):
classifierResult = classify0(normMat[i,:], normMat[numTestVecs:m, :], datingLabels[numTestVecs:m], 3)
#classify0为kNN分类器,normMat为用于分类的输入向量,normMat为输入的训练样本集(剩余的90%)
#datingLabels为训练标签,3表示用于选择最近邻居的数目
print("the classifier came back with: %d, the real answer is: %d" %(classifierResult, datingLabels[i]))
if (classifierResult != datingLabels[i]):errorCount += 1.0 #分类器结果和原标签不一样,则errorCount加1
print("the total error rate is : %f" %(errorCount/float(numTestVecs))) # datingClassTest() # datingDataMat, datingLabels = file2matrix('datingTestSet2.txt')
#
# normDataSet, ranges, minVals = autoNorm(datingDataMat) # fig = plt.figure()
# ax = fig.add_subplot(111) #一行一列一个
# ax.scatter(datingDataMat[:,1], datingDataMat[:,2],
# 15.0*array(datingLabels), 15.0*array(datingLabels)) #scatter画散点图,使用标签属性绘制不同颜色不同大小的点
# plt.show() # #测试分类器
# group, labels = createDataSet()
# label = classify0([1,1], group, labels, 3)
# print(label) from os import listdir def img2vector (filename):
returnVect = zeros((1, 1024)) #创建一个1*1024的数组
fr = open(filename)
for i in range(32):
lineStr = fr.readline() #每次读入一行
for j in range(32):
returnVect[0, 32*i+j] = int(lineStr[j])
return returnVect def handwritingClassTest():
hwLabels = [] #标签集
trainingFileList = listdir('E:/digits/trainingDigits') #listdir获取训练集的文件目录
m = len(trainingFileList) #文件数量
trainingMat = zeros((m, 1024)) #一个数字1024个字符,创建m*1024的数组
for i in range(m):
fileNameStr = trainingFileList[i] #获取文件名
fileStr = fileNameStr.split('.')[0] #以'.'将字符串分割,并取第一项,即0_0.txt取0_0
classNumStr = int(fileStr.split('_')[0]) #以'_'将字符串分割,并取第一项
hwLabels.append(classNumStr) #依次存入hwLabels标签集
trainingMat[i, :] = img2vector('E:/digits/trainingDigits/%s' % fileNameStr) #将每个数字的字符值依次存入trainingMat
testFileList = listdir('E:/digits/testDigits') #读入测试数据集
errorCount = 0.0 #测试错误数量
mTest = len(testFileList) #测试集的数量
for i in range(mTest):
fileNameStr = testFileList[i]
fileStr = fileNameStr.split('.')[0]
classNumStr = int(fileStr.split('_')[0]) #测试数据标签
vectorUnderTest = img2vector('E:/digits/testDigits/%s' % fileNameStr) #读入测试数据
classifierResult = classify0(vectorUnderTest, trainingMat, hwLabels, 3) #分类器kNN算法,3为最近邻数目
print("the calssifier came back with: %d, the real answer is : %d" %(classifierResult, classNumStr))
if (classifierResult != classNumStr): errorCount +=1.0
print("\nthe total number of errors is : %f" % errorCount)
print("\nthe total error rate is :%f" % (errorCount/float(mTest))) handwritingClassTest()

KNN算法识别手写数字的更多相关文章

  1. 基于OpenCV的KNN算法实现手写数字识别

    基于OpenCV的KNN算法实现手写数字识别 一.数据预处理 # 导入所需模块 import cv2 import numpy as np import matplotlib.pyplot as pl ...

  2. KNN (K近邻算法) - 识别手写数字

    KNN项目实战——手写数字识别 1. 介绍 k近邻法(k-nearest neighbor, k-NN)是1967年由Cover T和Hart P提出的一种基本分类与回归方法.它的工作原理是:存在一个 ...

  3. 机器学习--kNN算法识别手写字母

    本文主要是用kNN算法对字母图片进行特征提取,分类识别.内容如下: kNN算法及相关Python模块介绍 对字母图片进行特征提取 kNN算法实现 kNN算法分析 一.kNN算法介绍 K近邻(kNN,k ...

  4. KNN算法案例--手写数字识别

    import numpy as np import matplotlib .pyplot as plt import pandas as pd from sklearn.neighbors impor ...

  5. KNN算法实现手写数字

    from numpy import * import operator from os import listdir def classify0(inX, dataSet, labels, k): d ...

  6. KNN 算法-实战篇-如何识别手写数字

    公号:码农充电站pro 主页:https://codeshellme.github.io 上篇文章介绍了KNN 算法的原理,今天来介绍如何使用KNN 算法识别手写数字? 1,手写数字数据集 手写数字数 ...

  7. C#中调用Matlab人工神经网络算法实现手写数字识别

    手写数字识别实现 设计技术参数:通过由数字构成的图像,自动实现几个不同数字的识别,设计识别方法,有较高的识别率 关键字:二值化  投影  矩阵  目标定位  Matlab 手写数字图像识别简介: 手写 ...

  8. 使用神经网络来识别手写数字【译】(三)- 用Python代码实现

    实现我们分类数字的网络 好,让我们使用随机梯度下降和 MNIST训练数据来写一个程序来学习怎样识别手写数字. 我们用Python (2.7) 来实现.只有 74 行代码!我们需要的第一个东西是 MNI ...

  9. 学习笔记TF024:TensorFlow实现Softmax Regression(回归)识别手写数字

    TensorFlow实现Softmax Regression(回归)识别手写数字.MNIST(Mixed National Institute of Standards and Technology ...

随机推荐

  1. LC 990. Satisfiability of Equality Equations

    Given an array equations of strings that represent relationships between variables, each string equa ...

  2. JAVA书写格式规范

    1,大括号要对齐,并且成对写 2,左大括号前面有空格 3,遇到左大括号要缩进,Tab 4,方法和程序块之间加空行让程序看起来清晰 5,并排语句之间加空格,例如for语句 6,运算符两侧加空格

  3. SpringCloud学习成长之十三 断路器聚合监控

    上一篇文章讲述了如何利用Hystrix Dashboard去监控断路器的Hystrix command.当我们有很多个服务的时候,这就需要聚合所以服务的Hystrix Dashboard的数据了.这就 ...

  4. Apache配置优化之开启KeepAlive

    在HTTP 1.0中和Apache服务器的一次连接只能发出一次HTTP请求,而KeepAlive参数支持HTTP 1.1版本的一次连接,多次传输功能,这样就可以在一次连接中发出多个HTTP请求.从而避 ...

  5. ELK之在CentOS7.5上使用rpm包安装配置ELK7版本

    一,安装环境查看 二,软件版本选用 jdk 1.8.0_171 elasticsearch 7.1.1 kibana 7.1.1 logstash 7.1.1 三,安装配置 1,安装JDK 过程不详述 ...

  6. vue时间戳转换(10位数)/(13位)

    <template> <!-- time为时间戳 --> <div>{{time | formatDate}}</div> <!-- 结果为 20 ...

  7. 微信H5支付开发全过程(除内置微信以外的浏览器)

    前言:网上都是~ 呵呵 自己搞 只要花时间 多问客服总会有的 只说程序不说准备工作 自己ID 或者秘钥都准备好了  写的有点儿乱 可以把所有的方法 放在一个文件中调用 public function ...

  8. 帝国cms 批量替换语句

    UPDATE www_92game_net_cnys_ecms_caipu SET titlepic=REPLACE(titlepic,'http://file.92game.net', '') ; ...

  9. vue和小程序的相似之处

    小程序参考vue语法,之前做过小程序的,可以逆向思维.1,Vue文件后缀是.vue,vue组件把html<template>.js<script>和css<style&g ...

  10. es6 装饰器decorator的使用 +webpack4.0配置

    decorator 装饰器 许多面向对象都有decorator(装饰器)函数,比如python中也可以用decorator函数来强化代码,decorator相当于一个高阶函数,接收一个函数,返回一个被 ...