【机器学习算法实现】系列文章将记录个人阅读机器学习论文、书籍过程中所碰到的算法,每篇文章描述一个具体的算法、算法的编程实现、算法的具体应用实例。争取每个算法都用多种语言编程实现。所有代码共享至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、手写识别实例

kNN算法主要被应用于文本分类、相似推荐。本文将描述一个分类的例子,是《机器学习实战》一书中的实例,使用python语言以及数值计算库NumPy。下面首先简单介绍本实例编程开发过程中所用到的python、numpy中的函数。

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  编程实现“手写识别”

手写识别的概念:是指将在手写设备上书写时产生的轨迹信息转化为具体字码。
手写识别系统是个很大的项目,识别汉字、英语、数字、其他字符。本文只是个小demo,重点不在手写识别而在于理解kNN,因此只识别0~9单个数字。
输入格式:每个手写数字已经事先处理成32*32的二进制文本,存储为txt文件。0~9每个数字都有10个训练样本,5个测试样本。训练样本集如下图:
打开3_3.txt这个文件看看:
上面的背景介绍完了,现在编程实现,大概分为三个步骤
(1)将每个图片(即txt文本,以下提到图片都指txt文本)转化为一个向量,即32*32的数组转化为1*1024的数组,这个1*1024的数组用机器学习的术语来说就是特征向量。
(2)训练样本中有10*10个图片,可以合并成一个100*1024的矩阵,每一行对应一个图片。(这是为了方便计算,很多机器学习算法在计算的时候采用矩阵运算,可以简化代码,有时还可以减少计算复杂度)。
(3)测试样本中有10*5个图片,我们要让程序自动判断每个图片所表示的数字。同样的,对于测试图片,将其转化为1*1024的向量,然后计算它与训练样本中各个图片的“距离”(这里两个向量的距离采用欧式距离),然后对距离排序,选出较小的前k个,因为这k个样本来自训练集,是已知其代表的数字的,所以被测试图片所代表的数字就可以确定为这k个中出现次数最多的那个数字。
第一步:转化为1*1024的特征向量。程序中的filename是文件名,比如3_3.txt
[python] view plaincopy
  1. <span style="font-family:SimSun;font-size:18px;">#样本是32*32的二值图片,将其处理成1*1024的特征向量
  2. def img2vector(filename):
  3. returnVect = zeros((1,1024))
  4. fr = open(filename)
  5. for i in range(32):
  6. lineStr = fr.readline()
  7. for j in range(32):
  8. returnVect[0,32*i+j] = int(lineStr[j])
  9. return returnVect</span>
第二步、第三步:将训练集图片合并成100*1024的大矩阵,同时逐一对测试集中的样本分类
[python] view plaincopy
  1. <span style="font-family:SimSun;font-size:18px;">def handwritingClassTest():
  2. #加载训练集到大矩阵trainingMat
  3. hwLabels = []
  4. trainingFileList = listdir('trainingDigits')           #os模块中的listdir('str')可以读取目录str下的所有文件名,返回一个字符串列表
  5. m = len(trainingFileList)
  6. trainingMat = zeros((m,1024))
  7. for i in range(m):
  8. fileNameStr = trainingFileList[i]                  #训练样本的命名格式:1_120.txt
  9. fileStr = fileNameStr.split('.')[0]                #string.split('str')以字符str为分隔符切片,返回list,这里去list[0],得到类似1_120这样的
  10. classNumStr = int(fileStr.split('_')[0])           #以_切片,得到1,即类别
  11. hwLabels.append(classNumStr)
  12. trainingMat[i,:] = img2vector('trainingDigits/%s' % fileNameStr)
  13. #逐一读取测试图片,同时将其分类
  14. testFileList = listdir('testDigits')
  15. errorCount = 0.0
  16. mTest = len(testFileList)
  17. for i in range(mTest):
  18. fileNameStr = testFileList[i]
  19. fileStr = fileNameStr.split('.')[0]
  20. classNumStr = int(fileStr.split('_')[0])
  21. vectorUnderTest = img2vector('testDigits/%s' % fileNameStr)
  22. classifierResult = classify0(vectorUnderTest, trainingMat, hwLabels, 3)
  23. print "the classifier came back with: %d, the real answer is: %d" % (classifierResult, classNumStr)
  24. if (classifierResult != classNumStr): errorCount += 1.0
  25. print "\nthe total number of errors is: %d" % errorCount
  26. print "\nthe total error rate is: %f" % (errorCount/float(mTest))</span>
这里面的函数classify()为分类主体函数,计算欧式距离,并最终返回测试图片类别:
[python] view plaincopy
  1. <span style="font-family:SimSun;font-size:18px;">#分类主体程序,计算欧式距离,选择距离最小的k个,返回k个中出现频率最高的类别
  2. #inX是所要测试的向量
  3. #dataSet是训练样本集,一行对应一个样本。dataSet对应的标签向量为labels
  4. #k是所选的最近邻数目
  5. def classify0(inX, dataSet, labels, k):
  6. dataSetSize = dataSet.shape[0]                       #shape[0]得出dataSet的行数,即样本个数
  7. diffMat = tile(inX, (dataSetSize,1)) - dataSet       #tile(A,(m,n))将数组A作为元素构造m行n列的数组
  8. sqDiffMat = diffMat**2
  9. sqDistances = sqDiffMat.sum(axis=1)                  #array.sum(axis=1)按行累加,axis=0为按列累加
  10. distances = sqDistances**0.5
  11. sortedDistIndicies = distances.argsort()             #array.argsort(),得到每个元素的排序序号
  12. classCount={}                                        #sortedDistIndicies[0]表示排序后排在第一个的那个数在原来数组中的下标
  13. for i in range(k):
  14. voteIlabel = labels[sortedDistIndicies[i]]
  15. classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1 #get(key,x)从字典中获取key对应的value,没有key的话返回0
  16. sortedClassCount = sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse=True) #sorted()函数,按照第二个元素即value的次序逆向(reverse=True)排序
  17. return sortedClassCount[0][0]</span>

3、工程文件

整个工程文件包括源代码、训练集、测试集,可到github获取:github地址
进入use Python and NumPy目录,打开python开发环境,import kNN模块,调用手写识别函数:
因为我用的训练集和测试集都比较小,所以凑巧没有识别错误的情况:

kNN算法__手写识别——基于Python和NumPy函数库相关推荐

  1. 【Python】基于kNN算法的手写识别系统的实现与分类器测试

    基于kNN算法的手写识别系统 1.      数据准备 使用windows画图工具,手写0-9共10个数字,每个数字写20遍,共200个BMP文件. 方法如下,使用画图工具,打开网格线,调整像素为32 ...

  2. knn算法测试手写识别系统准确率

    手写识别系统,KNN算法实现手写识别系统的准确率 (准确率=测试分对的样本数/总的样本数) import numpy as np from itertools import chain from os ...

  3. Knn算法之手写识别系统

    knn值之手写识别系统 导入包 import numpy as np from os import listdir import operator 介绍 1.os模块 os.listdir() 方法用 ...

  4. 机器学习入门-kNN算法实现手写数字识别

    实验环境 Python:3.7.0 Anconda:3-5.3.1 64位 操作系统:win10 开发工具:sublime text(非必要) 简介 本次实验中的重点为采用kNN算法进行手写数字识别, ...

  5. kNN算法实现手写数字识别(机器学习)

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.实验步骤 二.实验过程 1.收集数据:提供文本文件 2.准备数据:将图像转换为测试向量 3.测试算法:使用k-近邻 ...

  6. 经典实战案例:用机器学习 KNN 算法实现手写数字识别 | 原力计划

    作者 | 奶糖猫 来源 | CSDN 博客,责编 | 夕颜 头图 | CSDN 下载自视觉中国 出品 | CSDN(ID:CSDNnews) 算法简介 手写数字识别是KNN算法一个特别经典的实例,其数 ...

  7. 开根号的笔算算法图解_机器学习KNN算法之手写数字识别

    1.算法简介 手写数字识别是KNN算法一个特别经典的实例,其数据源获取方式有两种,一种是来自MNIST数据集,另一种是从UCI欧文大学机器学习存储库中下载,本文基于后者讲解该例. 基本思想就是利用KN ...

  8. kNN算法与手写数字识别

    kNN算法简介 kNN算法采用测量不同特征值之间的距离来进行分类. 工作原理:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别.存在一个 ...

  9. 【机器学习实战】k近邻算法实战——手写识别系统

    文章目录 手写识别系统 步骤: 准备数据:将图像转换为测试向量 测试算法:使用k-近邻算法识别手写数字 [完整代码] 手写识别系统 为了简单起见,这里构造的系统只能识别数字0到9,参见图2-6.需要识 ...

  10. 【人工智能】利用C语言实现KNN算法进行手写数字识别

    KNN算法称为邻近算法,或者说K最近邻(kNN,k-NearestNeighbor)分类算法.所谓K最近邻,就是k个最近的邻居的意思,说的是每个样本都可以用它最接近的k个邻居来代表. kNN算法的核心 ...

最新文章

  1. 自己动手,做一款抬头显示的「Todo Hud」
  2. 专家点评Science:中英合作揭示拟南芥三萜化合物特异调控根系微生物组
  3. angular4创建html,Angular 4 Http服务
  4. UOJ#31 【UR #2】猪猪侠再战括号序列
  5. python 计算每日累计_5分钟学会用Python可视化数据分析美股
  6. Nginx 状态监控、缓存的两种机制(学习笔记十四)
  7. VB删除带子文件夹和文件的文件夹
  8. 【渝粤教育】广东开放大学 知识产权法 形成性考核 (44)
  9. 《Efficient Android Threading》Chapter 3---Threads on Android (Android中的线程)
  10. python画画excel_用Python在Excel里画出蒙娜丽莎
  11. 王垠受邀面试阿里P9,被P10面跪后网上怒发文,惨打325的P10赵海平回应了
  12. Ceph Calamari Server RPM编译
  13. 腹板拼接宽度_钢结构工程部件拼接一般规定
  14. 编写一个学生类student,包含的属性有学号,姓名,年龄
  15. html js制作高级拼图,基于JavaScript实现十五拼图代码实例
  16. 高通全新WiFi方案支持Ayla物联网平台连接
  17. CC00033.bigdatajava——|Java方法封装.V15|——|Java.v15|费氏数列.v01|递归实现|
  18. 快速调整 图片的 像素大小
  19. 【李佳辉_周报_2022.10.2】
  20. 大数据中台架构以及建设全流程二(Daas层设计)

热门文章

  1. Windows 8正式版亮点与新功能抢先看
  2. Objective-C 常用结构体
  3. 优秀的命令行文件传输程序(转)
  4. How to install and configure vsftpd
  5. Hive实践(hive0.12)
  6. linux一步一脚印--- ls -l 命令执行显示结果的每一列含义
  7. Linux之MariaDB
  8. LeetCode之SQL练习:第二高薪
  9. [Python WEB开发] 使用WSGI开发类Flask框架 (二)
  10. 【linux】安装python依赖库confluent_kafka