各位大大好!首先要向各位大大说一声抱歉,这一期的文章更新稍微有点延迟,对此笔者必须说一声抱歉,并保证在以后的更新中尽量做到及时,望各位朋友给予谅解。上期文章中,笔者介绍了KNN算法在约会配对中的实践,这期文章笔者将继续KNN算法的学习,当然这期文章也将是KNN系列的最后一期文章(后面有没有续文,笔者目前尚未能确定,如果有遇到更好的关于KNN方面的知识,笔者将在后面以续的方式再次谈到KNN算法,目前为止,这将是关于KNN的最后一期文章)。在本期文章中,笔者将继续讲解KNN算法的运用,将重点讲解KNN算法在识别系统中的用法;同时本期文章也将讲解python中的神级机器学习库scikit-learn。因此本期文章将主要有两大部分构成:手写识别系统以及scikit-learn库介绍。闲话不再多续,下面正式进入主题。
Part 1 手写识别系统
在本部分中,笔者将带领众看官一步步构造使用KNN分类器的手写识别系统。为了简便起见,这里构造的系统将只能够用来识别数字0-9。需要识别的数字已经使用图形处理软件将其处理成了具有相同色彩和大小的黑白图像,同时已将其保存为文本格式了。各位看官如果需要跟随练习的话,请到https://github.com/TinyPrince/Machine_Learning/tree/KNN中下载digits压缩包,解压压缩包后文件夹中包含训练数据集文件夹以及测试数据集文件夹,读者朋友可以运用这些数据进行实践练习。
知道笔者尿性的读者都已了解,笔者在开始讲解之前,会首先对分析步骤进行一下梳理,这里自然不能例外:
(一)准备数据:将图形转化成向量
解压后的文件夹包含了训练数据集(trainingDigits)以及测试数据文件夹(testDigits),训练数据文件夹中包含了2000个例子,测试数据文件夹中包含了900个样本,再一次强调一下,图像已经被整理成文本格式,每一个数字图形都是由01进行构成,如下所示:
可以看出每一个数字都是由32*32个二进制数字组合而成,因此,为了便于运用分类器对数字进行识别,必须要先把这个32*32的二进制矩阵转化为一个1*1024的向量,然后就可以使用前期文章中介绍的分类器对图像进行分类了。因此笔者下面将编写函数image2vector()对图像进行向量化。
因为前期文章中,有部分读者反映,截图后的python程序一方面看不清晰,另一方面不便于复制粘贴,所以从这一期往后笔者的程序都将编辑在表格之中,以便大家的阅读和借鉴。
这样,笔者便创建了将图像向量化的程序,为了验证程序的正确性,输入以下命令之后便会得到:
这证明了笔者的转换函数已经生效,接下来笔者便可以进行手写识别程序的编写了。
(二)测试算法:使用KNN算法识别手写数字
既然已经有了转化程序,下面就是要将训练集中的样本全部转化成向量,然后去进行分类。从训练数据集文件夹中可以看出,每一个文件名的首位数字就是这个样本的分类标签,因此,可以很容易得出标签向量和属性矩阵,同时可以对测试数据集采用同样的转化,最终便可以得出每一个样本的分类。下面,笔者开始逐步编写程序:
然后在命令行中输入handwritingClass()便可以得出错误率为1.2%,可以证明笔者这里的程序还是很实用的嘛。
至此,笔者完成了手写识别程序的所有介绍,也完成了对于KNN算法的正式介绍,在这一部分的最后,笔者来大致地总结一下KNN算法的优缺点吧。
(三)KNN算法优缺点
Part 2 scikit-learn库介绍
在前期介绍的分类学习中,笔者主要采用自己所编写的KNN算法程序去对样本进行分类,然而在python的世界中存在着一种更加简单高效的机器学习库scikit-learn,因此本部分笔者就简单地和诸位聊聊这一机器学习的神级库。
(一)scikit-learn简介与安装
scikit-learn又被称之为sklearn,是python世界中最为著名的机器学习库,它所能实现的机器学习方式主要包括:
Classfication 分类
Regression 回归
Clustering 聚类
Dimensionality reduction 降维
Model Selection 模型选择
Preprocessing 预处理
使用sklearn可以很方便地实现一个机器学习算法。一个复杂度算法的实现,使用sklearn可能只需要调用几行API即可。所以学习sklearn,可以有效减少特定任务的实现周期。
为了能够使用scikit-learn,你必须确保已经在你的python环境下安装了scikit-learn库,当然如果你按照笔者在前面的推荐安装了anaconda的话,那么恭喜你,此库已经安装在了你的python环境之下,只需要导入便可以正常使用了。当然如果你只是单纯地安装了python的话,那你可能就需要稍稍折腾一番了,首先需要你安装Numpy+mkl,然后需要再安装Scipy,最后在这一切都安装好的情形下你才能安装scikit-learn库。所以这个时候我必须要再次重申一下python的哲学:简单即美!既然已经有简单的方式安装scikit-learn,你又为何要去不断折腾呢,须知NoZuoNoDie。下面笔者就来谈一下scikit-learn库如何用于分类。
(二)基于scikit-learn的KNN分类
scikit-learn中的KNN分类算法实现基于sklearn.neighbors模块下的KNeighborsClassifier算法,即可以通过采用sklearn.neighbors.KNeighborsClassfier函数进行KNN分类。这里笔者就先讲解一下这个函数的相关参数,而后采用这一函数去解决笔者在上文中所实现的数字识别。
sklearn.neighbors.KNeighborsClassfier函数一共有八大参数,分别为:
n_neighbors:默认为5,就是KNN的k值,选取最近的k个点。
weights:默认是uniform,参数可以是distance,也可以是用户自己定义的函数。uniform是均等的权重,就说所有的邻近点的权重都是相等的。distance是不均等的权重,距离近的点比距离远的点的影响大。用户自定义的函数,接收距离的数组,返回一组维数相同的权重。
algorithm:快速k近邻搜索算法,默认参数为auto,可以理解为算法自己决定合适的搜索算法。除此之外,用户也可以自己指定搜索算法ball_tree、kd_tree、brute方法进行搜索,具体含义读者请自行阅读官方文档。
leaf_size:默认是30,这个是构造kd树和ball树的大小。这个值的设置会影响树构建的速度和搜索速度,同样也影响存储树所需内存大小。
metric:用于距离度量,默认度量是minkowski,也就是p=2的欧氏距离(欧几里德度量)。
p:距离度量公式。默认为2,也就是使用欧式距离公式;也可以设置为1,使用曼哈顿距离公式进行距离度量。
metric_params:距离公式的其他关键参数,这个可以不管,使用默认的None即可。
n_jobs:并行处理设置。默认为1,临近点搜索并行工作数。如果为-1,那么CPU的所有cores都用于并行工作。
现在已经对scikit-learn中的KNN分类函数有所了解,那么下面笔者就直接基于此函数分析上文中介绍的数字识别。
将上述程序保存,然后在命令行中运行函数名后便可以得出相应的测试效果,这里不再进行展示。
可以看出,使用scikit-learn库后,省却了编写自定义KN算法的环节,你可以把更多的时间用在数据处理以及新型算法思维的开拓上面,这就是python第三方库带来的便利。
后 记
至此本期正式内容已告结束,展望这三期文章,笔者先后介绍了KNN算法的原理,然后基于原理编写了相应的处理程序,接着笔者先后介绍了KNN算法在两个示例中的应用,最后,笔者进一步介绍了python中的机器学习库scikit-learn。总体看来,笔者基本对KNN算法做出了一个比较详细的说明介绍,更多的开拓与创新依赖于诸位的智慧。关于KNN的话题笔者就暂时介绍到这里,如有后续笔者会做一步说明。
最后,结束了此前三期的KNN主题系列,下期系列笔者将开始讲述一下python中的基础知识,关于机器学习系列的文章可能会在3-4期其它系列的文章之后再作出进一步讲述,各位朋友敬请期待。
领取专属 10元无门槛券
私享最新 技术干货