k-近邻算法-手写识别系统
手写数字是32x32的黑白图像。为了能使用KNN分类器,我们需要把32x32的二进制图像转换为1x1024
1. 将图像转化为向量
from numpy import *
# 导入科学计算包numpy和运算符模块operator
import operator
from os import listdir
def img2vector(filename):
"""
将图像数据转换为向量
:param filename: 图片文件 因为我们的输入数据的图片格式是 32 * 32的
:return: 一维矩阵
该函数将图像转换为向量:该函数创建 1 * 1024 的NumPy数组,然后打开给定的文件,
循环读出文件的前32行,并将每行的头32个字符值存储在NumPy数组中,最后返回数组。
"""
returnVect = zeros((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
测试:
testVector = img2vector('F:/迅雷下载/machinelearninginaction/Ch02/testDigits/0_13.txt')
testVector[0, 0:31]
array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 1., 1.,
1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])
2. KNN分类器
def classify0(inX, dataSet, labels, k):
"""
inX: 用于分类的输入向量
dataSet: 输入的训练样本集
labels: 标签向量
k: 选择最近邻居的数目
注意:labels元素数目和dataSet行数相同;程序使用欧式距离公式.
"""
# 求出数据集的行数
dataSetSize = dataSet.shape[0]
# tile生成和训练样本对应的矩阵,并与训练样本求差
"""
tile: 列: 3表示复制的行数, 行:1/2 表示对inx的重复的次数
例:In []: inX = [1, 2, 3]
tile(inx, (3, 1)) Out[]: array([[1, 2, 3],
[1, 2, 3],
[1, 2, 3]])
"""
# 用inx(输入向量)生成和dataSet类型一样的矩阵,在减去dataSet
diffMat = tile(inX, (dataSetSize, 1)) - dataSet
# 取平方
sqDiffMat = diffMat ** 2
# 将矩阵的每一行相加
sqDistances = sqDiffMat.sum(axis=1)
# 开方
distances = sqDistances ** 0.5
# 根据距离排序从小到大的排序,返回对应的索引位置
# argsort() 是将x中的元素从小到大排列,提取其对应的index(索引),然后输出到y。
"""
In [] : y = argsort([3, 0, 2, -1, 4, 5])
print(y[0])
print(y[5])
Out[] : 3
5
由于最小的数是-1,它的序号是3,因此y[0] = 3, 最大的数是5,它的序号是5,因此y[5] = 5
"""
sortedDistIndicies = distances.argsort()
# 2. 选择距离最小的k个点
classCount = {}
for i in range(k):
voteIlabel = labels[sortedDistIndicies[i]]
classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1
sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)
return sortedClassCount[0][0]
3. 手写数字识别系统的测试代码
def handwritingClassTest():
# 1. 导入数据
hwLabels = []
trainingFileList = listdir('F:/迅雷下载/machinelearninginaction/Ch02/trainingDigits') # load the training set
m = len(trainingFileList)
trainingMat = zeros((m, 1024))
# hwLabels存储0~9对应的index位置, trainingMat存放的每个位置对应的图片向量
for i in range(m):
fileNameStr = trainingFileList[i]
fileStr = fileNameStr.split('.')[0] # take off .txt
classNumStr = int(fileStr.split('_')[0])
hwLabels.append(classNumStr)
# 将 32*32的矩阵->1*1024的矩阵
trainingMat[i, :] = img2vector('F:/迅雷下载/machinelearninginaction/Ch02/trainingDigits/%s' % fileNameStr) # 2. 导入测试数据
testFileList = listdir('F:/迅雷下载/machinelearninginaction/Ch02/testDigits') # iterate through the test set
errorCount = 0.0
mTest = len(testFileList)
for i in range(mTest):
fileNameStr = testFileList[i]
fileStr = fileNameStr.split('.')[0] # take off .txt
classNumStr = int(fileStr.split('_')[0])
vectorUnderTest = img2vector('F:/迅雷下载/machinelearninginaction/Ch02/testDigits/%s' % fileNameStr)
classifierResult = classify0(vectorUnderTest, trainingMat, hwLabels, 3)
print("the classifier came back with: %d, the real answer is: %d" % (classifierResult, classNumStr))
if (classifierResult != classNumStr): errorCount += 1.0
print("\nthe total number of errors is: %d" % errorCount)
print("\nthe total error rate is: %f" % (errorCount / float(mTest)))
handwritingClassTest()
the classifier came back with: 0, the real answer is: 0
the classifier came back with: 0, the real answer is: 0
...
the classifier came back with: 9, the real answer is: 9
the classifier came back with: 9, the real answer is: 9 the total number of errors is: 10 the total error rate is: 0.010571
k-近邻算法识别手写数字,错误率在1.1%.改变k的值、修改函数 handwritingClassTest 随机选取训练样本、改变训练样本的数目,都会对k-近邻算法的错误率产生影响。
实际上,这个算法的执行效率并不高。因为每个算法需要为每个测试向量做2000次距离计算,每个距离计算包括了1024个维度浮点运算,总计执行900次。
而K决策树就是k-近邻的优化版。
4. 总结
k-近邻算法的特点:
1. 是分类数据最简单最有效的算法
2. 必须保存全部数据集,会使用大量存储空间
3. 必须对每个数据计算距离值,非常耗时
k-近邻算法-手写识别系统的更多相关文章
- 第三篇:基于K-近邻分类算法的手写识别系统
前言 本文将继续讲解K-近邻算法的项目实例 - 手写识别系统. 该系统在获取用户的手写输入后,判断用户写的是什么. 为了突出核心,简化细节,本示例系统中的输入为32x32矩阵,分类结果也均为数字.但对 ...
- 机器学习实战一:kNN手写识别系统
实战一:kNN手写识别系统 本文将一步步地构造使用K-近邻分类器的手写识别系统.由于能力有限,这里构造的系统只能识别0-9.需要识别的数字已经使用图形处理软件,处理成具有相同的色彩和大小:32像素*3 ...
- 吴裕雄--天生自然python机器学习:KNN-近邻算法在手写识别系统上的应用
需要识别的数字已经使用图形处理软件,处理成具有相同的色 彩和大小® : 宽髙是32像 素 *32像素的黑白图像.尽管采用文本格式存储图像不能有效地利用内 存空间,但是为了方便理解,我们还是将图像转换为 ...
- 【Machine Learning in Action --2】K-近邻算法构造手写识别系统
为了简单起见,这里构造的系统只能识别数字0到9,需要识别的数字已经使用图形处理软件,处理成具有相同的色彩和大小:宽高是32像素的黑白图像.尽管采用文本格式存储图像不能有效地利用内存空间,但是为了方便理 ...
- K近邻实战手写数字识别
1.导包 import numpy as np import operator from os import listdir from sklearn.neighbors import KNeighb ...
- 《机器学习实战》之k-近邻算法(手写识别系统)
这个玩意和改进约会网站的那个差不多,它是提前把所有数字转换成了32*32像素大小的黑白图,然后转换成字符图(用0,1表示),将所有1024个像素点用一维矩阵保存下来,这样就可以通过knn计算欧几里得距 ...
- 《机器学习实战》-k近邻算法
目录 K-近邻算法 k-近邻算法概述 解析和导入数据 使用 Python 导入数据 实施 kNN 分类算法 测试分类器 使用 k-近邻算法改进约会网站的配对效果 收集数据 准备数据:使用 Python ...
- 机器学习实战kNN之手写识别
kNN算法算是机器学习入门级绝佳的素材.书上是这样诠释的:“存在一个样本数据集合,也称作训练样本集,并且样本集中每个数据都有标签,即我们知道样本集中每一条数据与所属分类的对应关系.输入没有标签的新数据 ...
- python 实现 KNN 分类器——手写识别
1 算法概述 1.1 优劣 优点:进度高,对异常值不敏感,无数据输入假定 缺点:计算复杂度高,空间复杂度高 应用:主要用于文本分类,相似推荐 适用数据范围:数值型和标称型 1.2 算法伪代码 (1)计 ...
随机推荐
- python第l六天,lambda表达式学习,涉及filter及Map。
在python中lambda表达式可以作为匿名函数来使用,举一个简单的栗子: 以前我们写两个数相加的函数需要 #以前我们写两个数相加的函数,需要这样写 >>> def sum(x,y ...
- shell 在手分析服务器日志【转】
自己的小网站跑在阿里云的 ECS 上面, 偶尔也去分析分析自己网站服务器日志,看看网站的访问量.看看有没有黑阔搞破坏!于是收集,整理一些服务器日志分析命令,大家可以试试! awk '{print $1 ...
- 题解-AtCoder-agc006C Rabbit Exercise
Problem AtCoder & bzoj 题意:数轴上有\(n\)个点(初始坐标均为整数),编号为\(1\)~\(n\).给出\(m\)个操作. 每个操作会选定点\(a\),然后随机在点\ ...
- strstr()函数的使用
strstr(str1,str2) 函数用于判断字符串str2是否是str1的子串.如果是,则该函数返回str2在str1中首次出现的地址:否则,返回NULL. 实例: /** *Descriptio ...
- Delta DVP 系列 PLC 各装置 Modbus 地址
此Modbus地址表以 1 为基础地址 Device Range Type DVP address (Hex) Modbus address (Dec) Effective ES/EX/SS SA/S ...
- macbook 安装win7
长按option进入启动选择页面,选择winpe后进入安装,与普通电脑没有区别.安装后需要安装苹果专用驱动程序Boot Camp,才可以正常使用触控板等驱动
- MySQL基本语句、存储引擎
数据库服务器中存放的是 库(文件加) 表(文件) 表里面是记录(一行数据)quit or exit 退出客户端\s \c \G 库(文件) 创建 create database ...
- Linq与Lambda常用查询语法
1.查询全部 2.按条件查询全部 3.去除重复 4.连接查询 between and 5.排序 6.分组
- 【原创】大数据基础之Logstash(3)应用之file解析(grok/ruby/kv)
从nginx日志中进行url解析 /v1/test?param2=v2¶m3=v3&time=2019-03-18%2017%3A34%3A14->{'param1':' ...
- 阿里云服务器ubuntu 配置
由于阿里云的导入自定义 ubuntu 镜像需要开通 OSS 快照是收费的(看着感觉不贵,但是也很麻烦),而且自己已配置好的镜像想导入需要转换格式,还存在不能使用的情况,所以麻烦点直接在阿里云原来的ub ...