kNN算法__手写识别——基于Python和NumPy函数库
【机器学习算法实现】系列文章将记录个人阅读机器学习论文、书籍过程中所碰到的算法,每篇文章描述一个具体的算法、算法的编程实现、算法的具体应用实例。争取每个算法都用多种语言编程实现。所有代码共享至github:https://github.com/wepe/MachineLearning-Demo 欢迎交流指正!
(1)kNN算法_手写识别实例——基于Python和NumPy函数库
1、kNN算法简介
kNN算法,即K最近邻(k-NearestNeighbor)分类算法,是最简单的机器学习算法之一,算法思想很简单:从训练样本集中选择k个与测试样本“距离”最近的样本,这k个样本中出现频率最高的类别即作为测试样本的类别。下面的简介选自wiki百科:http://zh.wikipedia.org/wiki/%E6%9C%80%E8%BF%91%E9%84%B0%E5%B1%85%E6%B3%95
方法
- 目标:分类未知类别案例。
- 输入:待分类未知类别案例项目。已知类别案例集合D ,其中包含 j个已知类别的案例。
- 输出:项目可能的类别。
步骤
如下图
我们考虑样本为二维的情况下,利用knn方法进行二分类的问题。图中三角形和方形是已知类别的样本点,这里我们假设三角形为正类,方形为负类。图中圆形点是未知类别的数据,我们要利用这些已知类别的样本对它进行分类。
k近邻算法例子示意图
分类过程如下:
1 首先我们事先定下k值(就是指k近邻方法的k的大小,代表对于一个待分类的数据点,我们要寻找几个它的邻居)。这边为了说明问题,我们取两个k值,分别为3和5;
2 根据事先确定的距离度量公式(如:欧氏距离),得出待分类数据点和所有已知类别的样本点中,距离最近的k个样本。
3 统计这k个样本点中,各个类别的数量。如上图,如果我们选定k值为3,则正类样本(三角形)有2个,负类样本(方形)有1个,那么我们就把这个圆形数据点定为正类;而如果我们选择k值为5,则正类样本(三角形)有2个,负类样本(方形)有3个,那么我们这个数据点定为负类。即,根据k个样本中,数量最多的样本是什么类别,我们就把这个数据点定为什么类别。
补充:
优缺点:
(1)优点:
算法简单,易于实现,不需要参数估计,不需要事先训练。
(2)缺点:
属于懒惰算法,“平时不好好学习,考试时才临阵磨枪”,意思是kNN不用事先训练,而是在输入待分类样本时才开始运行,这一特点导致kNN计算量特别大,而且训练样本必须存储在本地,内存开销也特别大。
K的取值:
参数k的取值一般通常不大于20。——《机器学习实战》
2、手写识别实例
2.1 python、numpy函数
NumPy库总包含两种基本的数据类型:矩阵和数组,矩阵的使用类似Matlab,本实例用得多的是数组array。
shape()
shape是numpy函数库中的方法,用于查看矩阵或者数组的维素
>>>shape(array) 若矩阵有m行n列,则返回(m,n)
>>>array.shape[0] 返回矩阵的行数m,参数为1的话返回列数n
tile()
tile是numpy函数库中的方法,用法如下:
>>>tile(A,(m,n)) 将数组A作为元素构造出m行n列的数组
sum()
sum()是numpy函数库中的方法
>>>array.sum(axis=1)按行累加,axis=0为按列累加
argsort()
argsort()是numpy中的方法,得到矩阵中每个元素的排序序号
>>>A=array.argsort() A[0]表示排序后 排在第一个的那个数在原来数组中的下标
dict.get(key,x)
Python中字典的方法,get(key,x)从字典中获取key对应的value,字典中没有key的话返回0
sorted()
python中的方法
min()、max()
numpy中有min()、max()方法,用法如下
>>>array.min(0) 返回一个数组,数组中每个数都是它所在列的所有数的最小值
>>>array.min(1) 返回一个数组,数组中每个数都是它所在行的所有数的最小值
listdir('str')
python的operator中的方法
>>>strlist=listdir('str') 读取目录str下的所有文件名,返回一个字符串列表
split()
python中的方法,切片函数
>>>string.split('str')以字符str为分隔符切片,返回list
关于更多的numpy中的函数,可以查阅官网:http://docs.scipy.org/doc/
2.2 编程实现“手写识别”
- <span style="font-family:SimSun;font-size:18px;">#样本是32*32的二值图片,将其处理成1*1024的特征向量
- def img2vector(filename):
- 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</span>
- <span style="font-family:SimSun;font-size:18px;">def handwritingClassTest():
- #加载训练集到大矩阵trainingMat
- hwLabels = []
- trainingFileList = listdir('trainingDigits') #os模块中的listdir('str')可以读取目录str下的所有文件名,返回一个字符串列表
- m = len(trainingFileList)
- trainingMat = zeros((m,1024))
- for i in range(m):
- fileNameStr = trainingFileList[i] #训练样本的命名格式:1_120.txt
- fileStr = fileNameStr.split('.')[0] #string.split('str')以字符str为分隔符切片,返回list,这里去list[0],得到类似1_120这样的
- classNumStr = int(fileStr.split('_')[0]) #以_切片,得到1,即类别
- hwLabels.append(classNumStr)
- trainingMat[i,:] = img2vector('trainingDigits/%s' % fileNameStr)
- #逐一读取测试图片,同时将其分类
- testFileList = listdir('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('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))</span>
- <span style="font-family:SimSun;font-size:18px;">#分类主体程序,计算欧式距离,选择距离最小的k个,返回k个中出现频率最高的类别
- #inX是所要测试的向量
- #dataSet是训练样本集,一行对应一个样本。dataSet对应的标签向量为labels
- #k是所选的最近邻数目
- def classify0(inX, dataSet, labels, k):
- dataSetSize = dataSet.shape[0] #shape[0]得出dataSet的行数,即样本个数
- diffMat = tile(inX, (dataSetSize,1)) - dataSet #tile(A,(m,n))将数组A作为元素构造m行n列的数组
- sqDiffMat = diffMat**2
- sqDistances = sqDiffMat.sum(axis=1) #array.sum(axis=1)按行累加,axis=0为按列累加
- distances = sqDistances**0.5
- sortedDistIndicies = distances.argsort() #array.argsort(),得到每个元素的排序序号
- classCount={} #sortedDistIndicies[0]表示排序后排在第一个的那个数在原来数组中的下标
- for i in range(k):
- voteIlabel = labels[sortedDistIndicies[i]]
- classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1 #get(key,x)从字典中获取key对应的value,没有key的话返回0
- sortedClassCount = sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse=True) #sorted()函数,按照第二个元素即value的次序逆向(reverse=True)排序
- return sortedClassCount[0][0]</span>
3、工程文件
kNN算法__手写识别——基于Python和NumPy函数库相关推荐
- 【Python】基于kNN算法的手写识别系统的实现与分类器测试
基于kNN算法的手写识别系统 1. 数据准备 使用windows画图工具,手写0-9共10个数字,每个数字写20遍,共200个BMP文件. 方法如下,使用画图工具,打开网格线,调整像素为32 ...
- knn算法测试手写识别系统准确率
手写识别系统,KNN算法实现手写识别系统的准确率 (准确率=测试分对的样本数/总的样本数) import numpy as np from itertools import chain from os ...
- Knn算法之手写识别系统
knn值之手写识别系统 导入包 import numpy as np from os import listdir import operator 介绍 1.os模块 os.listdir() 方法用 ...
- 机器学习入门-kNN算法实现手写数字识别
实验环境 Python:3.7.0 Anconda:3-5.3.1 64位 操作系统:win10 开发工具:sublime text(非必要) 简介 本次实验中的重点为采用kNN算法进行手写数字识别, ...
- kNN算法实现手写数字识别(机器学习)
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.实验步骤 二.实验过程 1.收集数据:提供文本文件 2.准备数据:将图像转换为测试向量 3.测试算法:使用k-近邻 ...
- 经典实战案例:用机器学习 KNN 算法实现手写数字识别 | 原力计划
作者 | 奶糖猫 来源 | CSDN 博客,责编 | 夕颜 头图 | CSDN 下载自视觉中国 出品 | CSDN(ID:CSDNnews) 算法简介 手写数字识别是KNN算法一个特别经典的实例,其数 ...
- 开根号的笔算算法图解_机器学习KNN算法之手写数字识别
1.算法简介 手写数字识别是KNN算法一个特别经典的实例,其数据源获取方式有两种,一种是来自MNIST数据集,另一种是从UCI欧文大学机器学习存储库中下载,本文基于后者讲解该例. 基本思想就是利用KN ...
- kNN算法与手写数字识别
kNN算法简介 kNN算法采用测量不同特征值之间的距离来进行分类. 工作原理:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别.存在一个 ...
- 【机器学习实战】k近邻算法实战——手写识别系统
文章目录 手写识别系统 步骤: 准备数据:将图像转换为测试向量 测试算法:使用k-近邻算法识别手写数字 [完整代码] 手写识别系统 为了简单起见,这里构造的系统只能识别数字0到9,参见图2-6.需要识 ...
- 【人工智能】利用C语言实现KNN算法进行手写数字识别
KNN算法称为邻近算法,或者说K最近邻(kNN,k-NearestNeighbor)分类算法.所谓K最近邻,就是k个最近的邻居的意思,说的是每个样本都可以用它最接近的k个邻居来代表. kNN算法的核心 ...
最新文章
- 自己动手,做一款抬头显示的「Todo Hud」
- 专家点评Science:中英合作揭示拟南芥三萜化合物特异调控根系微生物组
- angular4创建html,Angular 4 Http服务
- UOJ#31 【UR #2】猪猪侠再战括号序列
- python 计算每日累计_5分钟学会用Python可视化数据分析美股
- Nginx 状态监控、缓存的两种机制(学习笔记十四)
- VB删除带子文件夹和文件的文件夹
- 【渝粤教育】广东开放大学 知识产权法 形成性考核 (44)
- 《Efficient Android Threading》Chapter 3---Threads on Android (Android中的线程)
- python画画excel_用Python在Excel里画出蒙娜丽莎
- 王垠受邀面试阿里P9,被P10面跪后网上怒发文,惨打325的P10赵海平回应了
- Ceph Calamari Server RPM编译
- 腹板拼接宽度_钢结构工程部件拼接一般规定
- 编写一个学生类student,包含的属性有学号,姓名,年龄
- html js制作高级拼图,基于JavaScript实现十五拼图代码实例
- 高通全新WiFi方案支持Ayla物联网平台连接
- CC00033.bigdatajava——|Java方法封装.V15|——|Java.v15|费氏数列.v01|递归实现|
- 快速调整 图片的 像素大小
- 【李佳辉_周报_2022.10.2】
- 大数据中台架构以及建设全流程二(Daas层设计)